Turn a tag field id into an instance of the tag model The add-on I'm using to import blogs has this to save tags to an entry:

craft()->relations->saveRelations($tagFieldId, $entryRecord['elementId'], $tags);

Where the first arg is the field id for the tag, the second is the entry, and the third is the tags.

I'm getting an error that says $tagFieldId needs to be an instance of the tag model:

  Argument 1 passed to Craft\RelationsService::saveRelations() must be
  an instance of Craft\FieldModel,

Can I turn my little field ID into an instance of this? How do I get a fresh one, if not? Thanks for your help.

Any suggestions on approaches appreciated.

Also - would tag tagmodel but I'm a wee newbie.

You need to get the FieldModel using the $tagFieldId variable, and then pass that model into the function as follows:

$tagFieldRecord = FieldRecord::model()->findById($tagFieldId);

$tagFieldModel = FieldModel::populateModel($tagFieldRecord);

craft()->relations->saveRelations($tagFieldModel, $entryRecord['elementId'], $tags);


Multi-locale pages 404 on subdirectories I'm developing and running a Craft site locally through Laravel Homestead and am having issues with pages 404'ing in a multi-locale setup.

I've followed this guide closely: https://craftcms.com/docs/localization-guide and still running into problems.

Basically, I want to have a Spanish locale set up, with English as the default top level. So my example.com/xyz-article will be the English version, and example.com/es/xyz-article will be the Spanish version.

Here is how my folder structure is set up:

craft/
public/
   .htaccess
   index.php
   es/
      index.php
      .htaccess

My craft/config/general.php is set up like this:

return array(
    '*' => array(
        'omitScriptNameInUrls' => true,
    ),

    '.dev' => array(
        'devMode' => true,
        'userSessionDuration'           => 'P101Y',
        'rememberedUserSessionDuration' => 'P101Y',
        'rememberUsernameDuration'      => 'P101Y',
        'invalidLoginWindowDuration'    => 'P101Y',
        'cooldownDuration'              => 'PT1S',
        'maxInvalidLogins'              => 101,
        'siteUrl' => array(
            'en_us' => 'http://example.dev/',
            'es' => 'http://example.dev/es/',
        )
    ),
);

My index.php file under the public/es directory looks like this:

<?php

// Path to your craft/ folder
$craftPath = '../../craft';

// Tell Craft to serve the Spanish content
define('CRAFT_LOCALE', 'es');

// Do not edit below this line
$path = rtrim($craftPath, '/').'/app/index.php';

if (!is_file($path))
{
    if (function_exists('http_response_code'))
    {
        http_response_code(503);
    }

    exit('Could not find your craft/ folder. Please ensure that  $craftPath is set correctly in '.__FILE__);
}

require_once $path;

Finally, both of my .htaccess files inside the public and es directories are identical and look like this:

<IfModule mod_rewrite.c>
    RewriteEngine On

    # Send would-be 404 requests to Craft
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
    RewriteRule (.+) index.php?p=$1 [QSA,L]
</IfModule>

Going to example.dev brings up the English homepage just fine, and example.dev/es brings up the Spanish homepage just fine. Everything looks good so far...but when I try to navigate into subdirectories, the es/ pages always 404's.

For instance, I set up a Single called "Testing", enabled it for both locales, and pointed it to a template inside my craft/templates folder called testing/index.html. example.dev/testing brings up the English version, but example.dev/es/testing gives me a 404 error.

The odd thing is, is that the ugly version of the URL at http://example.dev/index.php/es?p=testing brings up the Spanish version, and Live Preview also works and displays/updates when I'm working on the Spanish version of the page.

I'm at a bit of a loss as to where I'm going wrong here -- it seems like some paths are just screwy but I can't find where I may have entered something in incorrectly. Any help would be appreciated!

UPDATE: Here are the log errors I'm getting when I load the es/testing page.

I was running into the same issue, struggling with it and it turns out that the official documentation is a bit misleading (no offense) when it comes to the .htaccess file, because it just mentions to copy it:

You can not just copy the .htaccess but you have to change the RewriteBase parameter according to your folder structure in the /public folder.

In your case the .htaccess file in the /public folder should start like this:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /

    (...)

Within your /public/es folder you should have the following in the .htaccess:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /es/

    (...)

Hope that helps!

TL;DR —> The RewriteBase in the .htaccess has to be changed according to the folder setup of the locales


What does the error "Use of undefined constant CRAFT_BUILD - assumed 'CRAFT_BUILD'?" mean? Accessing my /admin of a craft site and i get this error.

Internal Server Error

Use of undefined constant CRAFT_BUILD - assumed 'CRAFT_BUILD'

Never happened before today, I'm running PHP v5.6.30.

Thanks

Had a plugin installed which had been using CRAFT_BUILD and as its been deprecated it was throwing the error, problem was could access admin to update plugin.

Manually, entered CRAFT_BUILD and other deprecated info into craft/app/Info.php and it let me login to fix.


Sanitize front-end entry form field If I'm enabling a user to post to Craft using the front-end entry form, is there a way that I can sanitize the title of a post?

I'm looking to apply AP formatting to titles.

I know Stephen has a plugin Entitle that does this but I'd rather have it on the initial submission.

This is a JS app so I can't do it on the Twig side.

I would definitely not rely on client-side validation. It's fine to do it from a UX point of view, but you should also be doing it server-side as well.

If this is a Vue app, write a custom validator for Vee Validate


Show only and merge the entries from multiple categories related to that entry I want to show the entries which have same category of that entry. The entry might have multiple categories, so I want to merge the result. If there is a result, then only the whole structure will be shown. The title 'Recommended Product' should only show one time. Currently, the issue is if there are three categories, the whole structure will show three times.

{% set subcategories = craft.categories.group('prodCat').descendantOf(prodCat).level(2).relatedto(entry) %}
    {% if subcategories | length %}
        {% for subcategory in subcategories %}
            {% set relatedentry = craft.entries.section('products').relatedTo(subcategories).id('not '~entry.id).all() %}
            {% set relatedentry_count = relatedentry|length %}
            {% if relatedentry_count > 0 %}

Recommended Product

                    {% for entry in relatedentry %}

{{entry.title}}

                    {% endfor %}

            {% endif %}
        {% endfor %}
    {% endif %}

Update based on the answer:

I manage to solve the issue after making some tweak of the answer given, just merge the subcategory.

{% set subcategory = craft.categories.group('prodCat').level(2).relatedto(entry) %}
{% set subcategories = subcategory|merge(subcategory) %}
    {% if subcategories | length %}
        {% set relatedentry = craft.entries.section('products').relatedTo(subcategories).id('not '~entry.id).all() %}
        {% set relatedentry_count = relatedentry|length %}
        {% if relatedentry_count > 0 %}

Recommended Product

                    {% for entry in relatedentry %}

{{entry.title}}

                    {% endfor %}

        {% endif %}
    {% endif %}

You can collect the id from the previous entry, then you can exclude id in the next query.
For example like this :

 {% set subcategories = craft.categories.group('prodCat').descendantOf(prodCat).level(2).relatedto(entry) %}
 {% set listId = ['not', entry.id ] %} //get id from current page id.
        {% if subcategories | length %}
            {% for subcategory in subcategories %}
                {% set relatedentry = craft.entries.section('products').relatedTo(subcategories).id(listId).all() %}
                {% set relatedentry_count = relatedentry|length %}
                {% if relatedentry_count > 0 %}

Recommended Product

                        {% for entry in relatedentry %}
                        {% set listId = listId|merge([entry.id]) %} // append the id from current category to the array.

{{entry.title}}

                        {% endfor %}

                {% endif %}
            {% endfor %}
        {% endif %}


Getting a "500 Internal Server Error" when uploading an image asset Just giving Craft CMS a test drive. Setup a local site using MAMP Pro. Got the basic site up and running ok, admin as well. Then i wanted to try out image assets, so I created an Asset Source for images, local folder. Created my "images" folder under the public dir, and specified "images/" as the file system path for my asset source. Added an image transform.

Then I try and upload an image, and it fails, with the ajax call "/index.php/admin/actions/assets/uploadFile" returning a 500 error. I tried checking the log files but there are no error messages relating to this failed ajax call.

Any ideas what I am doing wrong? Thanks!

ok i solved the problem by following the answer to this question here:

FastCGI error when accessing a local development site using MAMP Pro

even though the ajax call didn't generate an apache error at the moment it was called, it must have been something to do with fastcgi in general, cos the answer to that question worked for me!

i have never had this problem before, and i have heaps of other local sites which also do file/image uploading. so strange. and uploading of other file types (eg pdf) into the assets area worked no problem! doesn't make sense. but as a developer, sometimes you just accept the mystery of it all...

UPDATE

the problem started rearing it's ugly head again, even though i hadn't touched the httpd.conf edit i did to fix it. so i just deactivated the fastcgi module on the MAMP Pro dashboard. et voila, we're back in business....


Can I open templates/routes other than 503 when Craft is offline? I've set Craft offline (System status). Is it possible to "open" URL routes so it can be accessed even though the website is offline? Right now every request gets routed to my 503.html page.

For example the routes: /impressum and /about

I don't think it's possible using the System Status switch in Settings → General.

I had a similar requirement and solved it with a custom variable "maintenanceMode" in my config.php and added some simple logic to the init method in my business logic plugin, which redirects all request except some maintenance mode URLs to the 503 page.

$maintenanceUrls = array('/503', '/impressum', '/about');

if (craft()->request->isSiteRequest() && craft()->config->get('maintenanceMode')) {
    if (!in_array(craft()->request->getUrl(), $maintenanceUrls)) {
        craft()->request->redirect('503');
    }
}


Padding on .redactor-editor hides "structure" setting display Trying to use the Redactor "structure" setting: https://imperavi.com/redactor/docs/settings/special/#setting-structure

Craft overrides the padding on .redactor-editor, which makes the display a bit broken when using this setting.

https://goo.gl/photos/Qi9HbLmsvyGNGxsw9

Redactor puts a "redactor-structure" class in the markup, so to override, I'm putting:

body .redactor-box:not(.redactor-box-fullscreen) .redactor-editor.redactor-structure {
   padding-left: 32px;
}

Might be nice to have that in the core.


WYSIWYG removes HTML button all non- tags when view source Any code that I previously inserted using the html button on the rich text wysiwyg is removed when I click into edit the html within a post. Only <p> tags remain.

I have turned off the "Clean html" and the "Purify html" in the settings for the body field (rich text field), and have tried to enter iframes (videos).  I can insert them initially, but if I go back to the edit as rich text, and then click to edit the html, any iframes, divs or tags other than <p> tags are stripped out of the code.

I cannot edit html in any posts that have videos else the videos are stripped out.

I have also downloaded a fresh install of Craft to make sure that it wasn't just my install.  I encountered the same issue.

Can someone tell me what is going on?

This is a feature of "redactor" which is used with Craft to clean and format input.

To change the settings, you need to change the config in Craft/config/redactor/. See http://buildwithcraft.com/docs/rich-text-fields and http://imperavi.com/redactor/docs/settings/clean/#setting-allowedTags

This is not, however, working for me with iframes, which is a whole other issue.


Sortable Categories on per Entry basis I've been searching all over for this and have been coming up short unfortunately. Does anyone know if it's possible with in Craft CMS 3 to allow custom sorting of categories on a per entry basis?

For instance, maybe one entry is:

Category 1
Category 2
Category 3
Category 4

And on another entry, the admin orders the categories as:

Category 3
Category 4
Category 2
Category 1

If not available in Craft's core functionality, does anyone know of a custom category field type that allows this?

Thank you!

Evan

This isn't possible using Craft's Categories since Categories are a hierarchical structure and will always keep the order they are set in the Category Group when they are added to a category field.

One way around this limitation is to use a channel of entries in place of categories, since it is possible to drag and drop the order of related entries in an entries field.


How to notify the user from a Task Is it possible to somehow notify the user from a completing task?
I am walking trough a set of .csv files and on completion i would like to notify the user.

// last step
$stepIndex = $step + 1;
if ( $stepIndex == $this->getTotalSteps() )
{
    craft()->userSession->getFlash('notice', 'Reroutes  imported.');
    // craft()->userSession->setNotice(Craft::t('Reroutes   imported.'));
    // craft()->userSession->getFlashes();
}

return true;

I tried with the UserSessionService but i guess that won't work because the task is running separately from the session. If so reloading the page would be a good alternative but how can I let the front-end know of the task being completed.

The simple way to do this would be to log a message to your Plugin's custom log using

ExamplePlugin::log( 'TaskName has completed' );

This would require the user to visit the log and refresh to see if the task had completed - not ideal!

However, if you wanted something that updated as the task was being run you could possibly redirect them to a Plugin template with a text area that  displays a log for the task where you could show completion of each step of the task and then finally a "Completed Task" message.

// Create task
$task = craft()->tasks->createTask( 'TaskName', 'desc' ), array(
  'products' => $products
));

// Set session notice for start
craft()->userSession->setNotice(Craft::t('Import process started.'));

// Redirect to Plugin template page that displays a log
$this->redirect( 'templateName?task=' . $task->id );

Then inside the task you could log messages to be displayed in that template

if($step === $this->getTotalSteps()-1) {
  Log::message( 'Task finished.' );
}


How to get related entry data using ElementCriteriaModel in a plugin I am working on a custom plugin which gets some entry data using

$criteria = craft()->elements->getCriteria(ElementType::Entry);
$criteria->order('postDate asc');
$criteria->dateUpdated = array('and', '>=' . $this->dateFrom->format(DateTime::MYSQL_DATETIME), '<=' . $this->dateTo->format(DateTime::MYSQL_DATETIME));
$criteria->limit('null');

$responses = $criteria->find();

The returned entries contain a relationship to entries in another channel. In this case, the relationship field is named 'video'. So when looping through $responses I can see that $response->video is an array containing the sourceElement id and field id.

Is it possible to get the complete entry data for the related entry returned in the same query rather than needing to perform an additional query?

This is called Eager Loading you have to do

$criteria = craft()->elements->getCriteria(ElementType::Entry);
$criteria->order('postDate asc');
$criteria->dateUpdated = array('and', '>=' . $this->dateFrom->format(DateTime::MYSQL_DATETIME), '<=' . $this->dateTo->format(DateTime::MYSQL_DATETIME));
$criteria->limit('null');

// ========== start change ===============
$criteria->with = ['video'];
// ========== end change  ================

$responses = $criteria->find();

Edit: One of the most important things when working with Craft.

  I can see that $response->video is an array containing the sourceElement id and field id.

No, no and no. Many people believe this, or many other things, but that is not true. Your $response->video will contain an object of type ElementCriteriaModel. $respose->video is exactly the same type of object like $criteria = craft()->elements->getCriteria();

Thus you can do

$videos = $response->video->order('')->limit(2)->find()


Element API, VueJs and Imager! I'm trying to do something akin to Andrew's excellent article whereby I have a 'more' button that spits out 6 more entries at a time. I'm nearly there, but running into some issues. I don't get past the spinner, and looks like I have some syntax issues lines 17 and/or 24 (because it works if I comment those out). Pretty new to Element API and working this way, and can't Google up anything that makes sense to me as a fix. Anyone help me out?

Here's my element-api.php:

<?php

use craft\elements\Entry;
use craft\helpers\UrlHelper;

return [
    'endpoints' => [
        'api/news.json' => function() {
            return [
                'elementType' => Entry::class,
                'criteria' => ['section' => 'news'],
                'elementsPerPage' => 6,
                'transformer' => function(Entry $entry) {
                    // Generate new image transforms right away
                    craft()->config->set('generateTransformsBeforePageLoad', true);
                    // Get card image
                    $srcImage = $entry->cardImage->one();

                    if ($srcImage) {
                        $imageUrl = $srcImage->getUrl();
                        // Check if Imager plugin installed
                        if (craft()->plugins->getPlugin('Imager')) {
                            $image = craft()->imager->transformImage($srcImage, [
                                'width' => 800,
                                'format' => 'jpg',
                                'ratio' => 3/2,
                                'allowUpscale' => false,
                                'mode' => 'crop',
                                'jpegQuality' => 60,
                                'position' => $srcImage->focusPctX() . '% ' . $srcImage->focusPctY() . '%',
                                'interlace' => true
                            ], null, null);
                            $imageUrl = $image->url;
                        } else {
                            $imageUrl = $srcImage->getUrl(['width' => 800, 'height' => 533]);
                        }
                    } else {
                        $imageUrl = null;
                    }

                    return [
                        'title' => $entry->title,
                        'url' => $entry->url,
                        'jsonUrl' => UrlHelper::url("news/{$entry->slug}.json"),
                        'postDate' => $entry->postDate->format(\DateTime::ATOM),
                        'author' => ['name' => $entry->author->name],
                        'cardImageUrl' => $imageUrl,
                        'summary' => $entry->summary,
                    ];
                },
                'meta' => [
                    'description' => 'Latest news',
                ],
                'pretty' => true,
            ];
        },
    ]
];

So the problem is that you're using an example from my older article, which was written for Craft 2.x. This line:

craft()->config->set('generateTransformsBeforePageLoad', true);

...and also these lines:

if (craft()->plugins->getPlugin('Imager')) {
    $image = craft()->imager->transformImage($srcImage, [

...are specific to Craft 2.x; anything craft() is Craft 2.x; you can see some of the changes here: https://docs.craftcms.com/v3/extend/updating-plugins.html#high-level-notes


Craft Commerce - Advanced Product Options & Pricing What are the options for creating advanced product options with pricing.
I see there are way to create variants ok - but can this be linked to advanced pricing, e.g. for printing products.
the abaility to select different sizes, material, finish etc all which affect the price and then the quantity which also affects the price.

Similar options which you can see here - https://www.gogetprint.com/business-cards.

I can't see this being a problem. All variants can have their own pricing. You can also use relations to mix and match different things if you'd like.

There is a fine art printing section on the Image Science web site that may be an example of what you are thinking. There is a full write up of what it took to create the web site here: The Epic Journey to the New Image Science Website.


Allow user to delete their own account from the front end I'd like to allow a non-admin user to remove their own account from the front end of my app, without allowing them CP access.

I'm concerned that if I give the user group deleteUser permissions they will just be able to delete any other non-admin user if they change the values of my forms hidden inputs.

Here is my current form:

<form method="post" accept-charset="UTF-8">
  {{ getCsrfInput() }}
  <input type="hidden" name="action" value="users/deleteUser">
  <input type="hidden" name="redirect" value="account/delete/success">
  <input type="hidden" name="userId" value="{{ currentUser.id }}">
  <button type="submit" class="btn  btn--red">Delete my account!</button>
</form>

Is it best that I create a custom controller action to handle this and first check they are only deleting themselves before passing it off to the craft()->users->deleteUser() function? Or is there a better way?

I think you hit the nail on the head!

Including the userId in the front-end form give them the perfect opportunity to delete whoever they want... even just by guessing random IDs. That definitely seems like a huge security risk.

But if you build your own custom controller, you can guarantee that the current user is the one being deleted.


Paginate entries with 'page' query parameter? Is it possible to use a page query parameter for paginating entries with {% paginate %} instead of a dynamic segment?

So instead of http://example.com/articles/p2 i would like to use http://example.com/articles?page=2.

This would simplify interoperability with client side MVC frameworks because the query parameter would be clearly separated from a dynamic route for a single entry in articles (i.e. http://example.com/articles/a-single-article).

The only solution I can think of at the moment is to not use {% paginate %} altogether and instead calculate limit and offset for craft.entries.find(...) manually from craft.request.getQuery("page"). I hope there is an easier way?

I think this is what are you searching for:

http://buildwithcraft.com/docs/config-settings#pageTrigger


How to only show translated fields in an additional locale? I'm using the localisation feature for the first time, and I'm not sure if I understand its rationale.

On a site with entries that have multiple fields, I only have the main body text set up for translation. If I switch to the secondary language in the control panel, all fields are displayed and pre-populated with the contents of the main language (but according to my understanding, they're just pointers and not duplicated in the database).

Why are the non-translateable fields not set to disabled, marked up otherwise, or even hidden completely? Is there a way to do so?

(My concern is that my client can't identify which fields need to be translated, and hereby overwrites a non-translateable field with the secondary language.)

The fields that are not marked for translation are duplicated and synced between the different locales. So if you make a change in one locale, it will change it in all. This is different from saying that they are only available in one locale, which isn't possible in Craft.

Removing/disabling them in "secondary languages" isn't possible, and doesn't make sense since there is no "primary" or "secondary" languages in Craft. You can choose to publish an entry in only your "secondary language" if you want, and when doing so you'd probably want all fields to be editable.

But, I see your point, and I've had this dilemma myself. What I did was put the fields that weren't translatable in a separate tab (you could of course do it the opposite way, put the fields that are translatable in a separate tab). That made sense for my client, at least, but I guess it really depends on your project. :)


Convert checkbox values from an array to a string I have a front end form with multiple checkboxes. Is it possible to convert the checkbox values from an array to a string before it's submitted to the database?

I want to save the checkbox values into a PlainText Craft field in the database.

If I try to submit the front end form checkbox values into a PlainText field currently, I get the error: trim() expects parameter 1 to be string, array given

It looks like perhaps using the join or merge filter may accomplish this but I'm not sure.

If you need to do this in a twig template, the join filter will do the job.

Use {{ yourCheckboxesValues|join(', ') }} to print something like that : value1, value2, value3.


How to create an advanced route with query strings? I have a main structure as my navigation.
Within this structure I have multiple image galleries.
I want to make the image gallery's urls dynamic.

If I define a gallery within the structure entry:
https://mysite.com/sport/gallery/

The url of the images in the gallery (which is a channel) should be:
https://mysite.com/sport/gallery/mygallerySlug?type=gallery&parent=parentEntryId

now I would like to have a route which catches all of the ?type=gallery entries and load the "gallery/_entry" template.

It shouldn't matter how deep in the structure the ?type=gallery is.

I don't seem to be able to do this within the CP, and I've never used advanced routing...

Any help appreciated!

EDIT:

Maybe I need to specify a little further:

I have a structure called "pages" which acts as the main structure.
I have a channel that is called "galleries" where I can upload images and assign a category.
In my main structure I can assign galleries from within a matrix block and choose a category. That way I can regroup multiple entries from the channel "galleries" in a structure entry.

The urls of the galleries should be completely dynamic:

https://mysite.com/sport/gallery holds multiple gallery entries where each of these galleries should have a url the following way:
https://mysite.com/sport/gallery/gallery1
https://mysite.com/sport/gallery/gallery2 ...

another gallery collection could be here:
https://mysite.com/karting/galleries/
whith links like that:
https://mysite.com/karting/galleries/gallery3
https://mysite.com/karting/galleries/gallery4
etc..

I know I could specify the entry url of one gallery the following way in the "galleries" section url settings:

{{ craft.entries.id(65).locale('de').first.uri }}/{slug}
where the id is the id of e.g. https://mysite.com/sport/gallery/ structure entry.

But that works only for one gallery.

I could create a route for "sport/gallery/*" and assign the "gallery/_entry" template to it. But that way I would have to create a route for every gallery, which is not completely obvious, nor intuitive on a editor's point of view.

In fact this is almost a duplicate of this question:
dynamic urls for channel/structure that's linked to the main structure

Cheers
Stefan

You can do this completely in the template. Have the structure entries resolve to a route like gallery/_router and then inside that template you could use this code to include the template of your choice:

{% switch craft.app.request.getParam('type') %}

    {% case "gallery" %}

        {% include "gallery/_entry" %}

    {% case "anotherParam" %}

        {% include "gallery/_anotherParam" %}

     {% default %}

        {% include "gallery/_default" %}

{% endswitch %}


Require vendors in custom plugin I'm building a plugin in which I would like to use a vendor library, but just adding it to the plugin's composer.json file doesn't seem to be enough to get it installed.

It works when I run composer update in the plugin's root dir but I was hoping there would be a way to have it automatically installed when the plugin is installed?

When you include the library as required in your composer file, Craft will automatically download the package and install it in the global vendor directory rather than in your plugin directory (since both are inside the vendor folder).

You don't have to include it and you don't have to take care for certain other plugins that require the same one.

This process is done while running composer install >>yourplugin<< or composer update so everytime you make a Craft update it will search for new required libraries in your plugin but it won't do it during the installation of your plugin since every library should already exist - unless you add the dependency after your composer action -> composer update will solve it


Good way to handle multisite fallback templates So I've got a multisite going on.

For most of the sites, most of the time, they'll be using the same templates. But I want a good way to handle siteX needing one template to be different from the other sites.

For example, when going to siteX.com/news, I'd like for the template served to be siteX/news.html if it exists, otherwise default/news.html.

I know I could change the template path in the DB, but I'd rather keep it in the code for development/deployment simplicity.

I think I could could create custom routes, but I'd rather not create a route for every section.

At the moment I'm doing this by creating a root/news.html file, which just says

{% include [currentSite.handle ~ '/news', 'default/news'] %}

but it'd be nice to not have to do this for every template I create. It also seems inefficient to do this on a template level (though I don't actually know this to be true).

So the questions are:

(How) can I overwrite Craft's template resolver to do what I want?
Is this the best way to go about this?

Thanks!

You can create localized template files by placing them in a subfolder of templates/ named after the site handle.

See https://docs.craftcms.com/v3/dev/#template-localization for a full explanation.


Possible to set 2 data fields within 1 select option? I have the following code in my form, but I'd like to also save the eventDate of the selected entry into a separate date field to enable sorting/selection later.

<label for="eventName">Event
<select id="eventName" name="fields[eventName]">
  <option value="">select from list</option>
    {% set events = craft.entries.find({section:'events,activities', eventDate : ">= " ~ now.w3cDate() , order:'eventDate'}) %}
    {% if events %}
        {% for entry in events %}
            <option value="{{ entry.eventDate.format('D j M') }},{{ entry.eventName }}">{{ entry.eventDate.format('D j M') }},{{ entry.eventName }}</option>
        {% endfor %}
    {% endif %}
</select>
</label>

You could use the Preparse plugin to create a field that is automatically updated with the eventDate value whenever the entry is saved. It wouldn't be a datetime field, but if you stored the timestamp (i.e. {{ dateString|date('U') }}) it'd be easy to use as such.

Another option is to have an hidden input in your form for the eventDate datetime field, and use JavaScript to set its value whenever the <select> input changes (i.e. listen for the change event for the latter, in your JS).

The third option would be to write a plugin which listens to the entries.beforeSaveEntry event in order to set the eventDate value from the dropdown field.


Why are the email settings fields not showing, and how do I fix this? I'm trying to set up SMTP in Craft backend Settings > Email to get Mandrill working. But regardless of which protocol I choose, no settings fields are shown, and when I click save it just says "Couldn’t save email settings". It's the same in both Firefox and Chrome.

What could be the problem here, and how do I fix it?

Many thanks in advance and best regards.

/Monkey

Since I was short on time I ended up reinstalling Craft. Not exactly a minimum effort solution, but it fixed the backend > settings > email problem (and the updates page, that was not functioning properly as well). However, new install would not show my plugin in backend > settings > plugins. The solution to this, was to create a bare minimum test plugin (just copy pasted from https://craftcms.com/docs/plugins/setting-things-up), after which both the test plugin and my real plugin showed up in backend. All seem ok now.


How do you display user photo in templates? I tried using the following but it's not working:

{% if entry.author.photoUrl|length %}
<img src="{{ entry.author.photoUrl(84) }}" alt="" />
{% else %}
no photo
{% endif %}

Also, another question of mine is... when i upload a user photo on the profile tab, am I suppose to see the photo's thumbnail? All I see is the upload box with the button but the file seemed to have uploaded successfully to /craft/storage/userphotos

Yes, you should see the photo thumbnail in the list of users after you upload the photo. Your exact code works for me, so I think something has gone wrong with the photo upload.


Asset upload fails with progress bar at full, but images in tempuploads folder I can’t for the life of me get images to upload. Neither on my local server or on the live server. The progress bar goes to the end, and then … nothing. From what I can see online, I’m not the only one, but I can’t find any remedy.

I’ve gotten Imagemagick installed (locally, at least), but no change (GD is installed in both environments)
I’ve tried several types of image formats (seems some people have problems with JPEG)
I’ve tried relative asset paths and set through environmental variables

Nothing seems to work.

In the error logs, the only error I can find is:
Undefined index: singleUploadLocationSource ([correct path]/craft/app/models/AssetFileModel.php:171)

I just realised that the files do get uploaded to the storage/runtime/assets/tempUploads folder. So seems it fails to completing the copy to the final assets folder. Permissions should be correct, from what I can understand (I'm no expert on these things).

Does anyone have any ideas what can be the cause? I’ve been scratching my head here for weeks, and it still itches like crazy.

My own fault – I had set a subpath in the field type, so it tried to save to a folder that didn't exist.

I had first thought it was here the asset path was set, and when I figured out I needed asset types, I forgot to delete the subpath.

Now it works! Both with Imagemagick (local) and GD (live server).


EVENT_BEFORE_SAVE event not getting $entry-id when creating an entry I don't know if it was with Craft 3.5, but did something change slightly when using the EVENT_BEFORE_SAVE event?
I have a simple use case where I am encoding the entry ID and updating the slug when the entry is saved.
It does check if a title is empty and if the entry is a draft or revision, if any of those are true, then it does not encode it.
After updating from Craft 3.4.30 to Craft 3.5.5 when saving an entry I have noticed that it throws an error as $entry->id returns null, however on refreshing the page and then resaving it, it passes the entry ID in fine.
A basic example of what I have is:
Event::on(
    Entry::class,
    Entry::EVENT_BEFORE_SAVE,
    function (ModelEvent $event) {

        $entry = $event->sender;

        if (ElementHelper::isDraftOrRevision($entry)) {
            return false;
        }

        // Get entry title
        $title = $entry->title;

       if ($title !== null) {
            // Encode entry ID
            $newSlug = Module::$instance->hashid->encode($entry->id);

            // Update slug to be a hash
            $entry->slug = $newSlug;
        }
    }
);

Before hand this worked fine when creating the entry, but now it is requiring me to have to save the entries twice, any thoughts?

I did some looking into how the EVENT_BEFORE_SAVE is being used and whether or not we can get the entry ID, without having to over complicate things, it was better to use EVENT_AFTER_SAVE, this does mean you will have to resave the entry after saving it, in this case that is very little overhead and it is only for a certain section, if heavier stuff was happening you may want to check on the impact.
I also placed in a check to detect if the action was happening or not, to stop any loops.
Here is what I ended up doing for anyone who wants to know for reference.
use craft\elements\Entry;
use craft\events\ModelEvent;

const SECTION_ID = 4;
public static $entrySlugRenaming = false;

Event::on(
    Entry::class,
    Entry::EVENT_AFTER_SAVE,
    function (ModelEvent $event) {
        $this->handleEventAfterSave($event);
    }
);

private function handleEventAfterSave($event)
{
    // Get entry
    $entry = $event->sender;

    // Don't worry about draft or revisions
    if (ElementHelper::isDraftOrRevision($entry)) {
        return;
    }

    // Test if entry renaming is already running
    if (!self::$entrySlugRenaming) {
        self::$entrySlugRenaming = true;

        // Check if there is an entry
        if ($entry !== null) {
            // Test for entry section
            switch ($entry->sectionId) {
                case self::SECTION_ID:
                    // Update slug here
                break;
            }
        }

        // Resave event
        $elements = Craft::$app->getElements();
        $elements->saveElement($entry);

        // Reset $entrySlugRenaming
        self::$entrySlugRenaming = false;
    }
}


Any good tutorial for plugin developement? I am entirely lost I understand Craft Templating pretty well, but when it comes to programmation I am entirely lost, I don't get how it works. I used to use CodeIgniter a lot, which is a MVC as you guys may know. In CodeIgniter, everything goes through the controller, then in the controller, I call models. In models, I interact with database and then return the data to the controller and then display a view. In Craft, it doesn't seems to work like this. Is there any good tutorials for "programming" in Craft or develop a plugin? Like how controllers, models, services and events works? Or is there any good people willing to help me?

I want to use Craft so much, I just need to understand it before I use it at large for my client's projects.

I appreciate your help.

We just published a video course on Craft plugin development that might help you. https://mijingo.com/products/screencasts/craft-plugin-development/


Can image transforms decrease performance? If I have a site that will eventually have thousands of product images on it, would using image transforms slow things down?

Nope. Once a transform has been generated once, Craft remembers that, and saves it right in your asset source. Future page loads will get a direct URL to that generated image, so it gets loaded via your webserver (or S3, etc.) directly. No PHP involved.


Close entry editing after set time (for certain a user group) I have a group of users who are allowed to create entries and edit them but I want to put a window on how much time they have in which they can edit it. For example, after initial submission they would only have two weeks to edit the entry before only an admin can make changes to that entry.

I understand how to run the logic to check the user groups and calculate cut-off dates but I have no idea where I need to hook in to be able to do this.

Is there anywhere I can hook in to run this logic? If so, where is this?

Any guidance would be really appreciated!

Seems like you'd just need to write a plugin that listened to the onBeforeSaveEntry event.

That plugin would check if the entry author is in the user group you're interested in, and if it's a new entry just let it save.

If it's an existing entry, check the dateCreated date against your window and see if it's still valid.  If it's outside of your window you can set performAction to false so the entry won't save and set a flash message indicating they're outside the window.


$craftPath multiple enviroments I am new to Craft and am trying to figure out what the best way to set the $craftPath PHP variable to something like the other configurations for multi-environments.

Locally I have it set up the preferred way, but on my remote server, it's nested an extra level deep in folders (sub domains).

Is there a way to have the variable be set using the same functionality that Craft uses to determine environments? Or do I have to just manually change the value where the index.php lives.

Thanks for the advice.

There is a really nice multi-environment configuration method defined on the craft cookbook website, that creates a global php variable called CRAFT_ENVIRONMENT in your main index.php. It seems to me that you could also use this global to define the $craftPath.

switch (CRAFT_ENVIRONMENT) {
    case "dev":
        $craftPath = '../craft';
        break;
    case "stage":
        $craftPath = '../../craft';
        break;
    default:
        // default "production"
        $craftPath = '../../craft';
}

I generally use the above method (without the new switch part) in combination with this configuration method in my general.php config file.


General question: Has anybody ever used Craft along with ElectronJS to create a native based app? Just wondering if anybody has ever used Craft as a platform along with using something like ElectronJS to move a PWA to a native based app for windows or mac?

Is this possible I wonder? Has anybody come across any articles about this?

Thanks!

So if you're using Craft as an API service, whether via the ElementAPI or via GraphQL w/the CraftQL plugin, anything you like can talk to it, including a PWA app, a native PWA, an iOS app, whatever.


Using Charge plugin with Stripe Connect Has anyone set up the Charge plugin with Stripe Connect? I've followed the docs and things look good in the Craft back-end but the payments don't look to be routed to the correct Stripe accounts on the Stripe end.

The Squarebit docs refer to a config setting which I need but I haven't been able to track this down.

https://squarebit.co.uk/software/craft/charge/usage/controllers/connect-controller

Developer of Charge here.

The full details on the setup for Connect are detailed here : https://squarebit.co.uk/software/craft/charge/usage/reference/connect-setup

Setting up a Charge to use Connect takes 4 broad steps -

Configuring your Stripe Account, and Charge settings - this involves putting your platform keys into Charge, and the callback url(s) in to the Stripe settings
Adding the Charge Connect field to the elements you want to use as the parent elements for the connected accounts.
Updating your templates to reference these connected fields.
Actually connecting accounts to use - using the field you created in step 2.

From the sounds of it - the issue you're having is in either step 3, or 4.

The first thing to look in is the Charge > Logs - which will detail exactly what's happening, and why things aren't going to the connected accounts. It's almost certainly due to either the proper information isn't being passed through on the request (ie. a template issue) or an account issue (ie. the connected accounts aren't in the appropriate mode to accept payments)


Getting PHP errors to log in Nginx/PHP-FPM Under Nginx/PHP-FPM, I can't get PHP errors logged to craft/storage/runtime/logs/phperrors.log as they should be.

Initially, errors weren't logging anywhere, but I discovered I needed:
catch_workers_output = yes in our PHP-FPM config.

Errors are now logging to /var/log/php7.0-fpm.log, but not to Craft's custom location.

I'm only 80% confident in this answer, but I'm pretty sure that runtime PHP ini_set calls won't work with nginx running with FastCGI (which is what Craft uses to change the error_log path.

Try setting that path directly in your /etc/php5/fpm/php.ini file.


Site url is not generated correctly when using environment variables I'm working on a multi-site setup (for a localized website). In my .env file, I have defined a SITE_BASE_URL variable. Then, in the control panel, I set up each site's base url with that environment variable (e.g. http://$SITE_BASE_URL/en, http://$SITE_BASE_URL/nl, etc. for each language).
However, when I need to generate urls in my Twig templates, this environment variable doesn't seem to get parsed; I get generated html that looks like this ....
Example from a twig template:
{% set pages = [
    craft.entries.section("services").one(),
    craft.entries.section("products").one(),
] %}

{% for page in pages %}
{{page.title}}
{% endfor %}

This gives me URLs like http://$SITE_BASE_URL/en/services, http://$SITE_BASE_URL/en/products, etc.
This setup was working fine for me when using the @web alias in the CP. Why doesn't it work with the env variable? The only reason I switched to env variables is that it is not recommended to use the @web alias due to cache poisoning.
I've already looked at https://github.com/craftcms/cms/issues/3719 and baseUrl outputs environment variable
Neither have solved my issue...

Cache poisoning would only happen if you don't hard-set your @web alias manually and it is auto-determined.
Set it in your config/general.php with:
'aliases' => [
    'web' => getenv('SITE_BASE_URL'),
],

Then you'll be able to revert to using it in your Control Panel.
In terms of why this happened; you can't add to an environment variable the way you can with an alias so http://$SITE_BASE_URL/en will become a string and the variable aspect of it will disappear.
When you define $SITE_BASE_URL, it can only be used as is in the CP so if you wanted to use variables for you site, you would need to define one for each site/language.


Commerce: Combining unwanted quantity discounts quantity discounts

I have the following offer with quantity discounts for a series of my products:

Buy 1 item and get $5 off per item
Buy 2 items and get $10 off per item
Buy 3 items and get $15 off per item

I set these discount rules in my control panel under "commerce" > "promotions".

problem

The problem is that Craft combines the quantity discounts. So when I put 3 items into the cart, Craft will for each item add a $5 discount plus a $10 discount plus a $15 discount per item – so instead of a $15 discount per item I get a $30 discount per item.

I thought I might work around this by taking this process into account and simply reducing the quantity discounts in the control panel so they would add up to the desired amount.

But that's no solution if I want to display discounts per item and discounted item price correctly on the frontend.

Plus another issue: When I put 3 items into the cart, I will then see 3 types of discounts applied to my cart which is confusing.

Is there any way to avoid this sort of combining of discounts?
Will I have to create an Adjuster to accomplish my intended pricing structure?

Not really a good answer as such but at the moment (June 16) there is currently no facility to print the actual price a particular item will sell at after all discounts/sales are applied (unless you calculate it yourself).

This seems to me a bit of an oversight.

I have requested it as a feature, and Luke seemed amenable to the idea but I have no idea on the ETA for it.

To solve the cumulative discount issue - you can either express the discount as a cumulative thing as you mention, or you could write a simple plugin that listens to

https://craftcommerce.com/docs/events-reference#commerce_discounts.onbeforematchlineitem

...and only applies the desired discounts when the desired conditions are met


Is there a masked input field type for Craft? Is there anything like the EE add-on for Craft?

This would be really useful for part numbers, etc.

I just wrote one! MN Match Input. You specify an Input Mask and the entry won't save if preg_match($inputMask, $value) isn't 1. So you get all the power of preg_match (lots of rope...)


How do I find the closest parent entry with an Assets field filled in? I have a structure that goes up to 4 levels deep. Each page has a field for a 'hero' image. If a child page does not have this field filled out I would like to traverse up the structure and find the closest parent entry with this field set. Basically some 'sections' would have a default hero image added to the top level parent while others may have a specific image for each child page.

You can get your entry's parent entry with getParent(). Use this entry method in a conditional, if your entry has no hero image set.

You can nest the code to climb up all of your structure's levels:

{# Check if entry has hero image #}
{% if entry.hero.first() %}
    {{ entry.hero.first().url }}
{% else %}

    {# Check the parent entry #}
    {% if entry.getParent().hero.first() %}
        {{ entry.getParent().hero.first().url }}
    {% else %}

        {# Check the entry 2 levels above #}
        {% if entry.getParent().getParent().hero.first() %}
            {{ entry.getParent().getParent().hero.first().url }}
        {% else %}

            {# ... Oh no, we're not finished yet :( #}

        {% endif %}

    {% endif %}

{% endif %}

Yes, that's not good code. That's why I recommend to use the same technique in a macro, that you can call recursively:

{% macro showHero(thisRecursionEntryModel) %}

    {% import _self as self %}

    {# Check if entry has hero image #}
    {% if thisRecursionEntryModel.hero.first() %}
        {{ thisRecursionEntryModel.hero.first().url }}
    {% else %}

        {# Check the entry's ancestors recursively #}
        {% if thisRecursionEntryModel.getParent() %}
            {{ self.showHero(thisRecursionEntryModel.getParent()) }}
        {% endif %}

    {% endif %}

{% endmacro %}

{% import _self as self %}
{{ self.showHero(entry) }}

You can also import the macro from a file, if you want to use it in more than one template file or just like your code to be modular:

{% import '_includes/macros.html' as macros %}
{{ macros.showHero(entry) }}


Can a plugin add JS or CSS to the control panel in Craft 3? I want entries in a specific PlainText field for a named group to be pre-filled with random content. I am aware of the https://github.com/lukeyouell/craft-randomkeygenerator plugin and am aware that I could create my own field type, but I am intending to use jQuery to do this instead (which should be easier).

This Can a plugin add JS or CSS to the control panel? describes how to do this in Craft 2 (I assume that the code works). My equivalent in Craft3 is...

class MyPlugin extends Plugin {
    if (Craft::$app->request->getIsCpRequest())
    {
      Craft::$app->templates->includeJs('alert("xxx")');
    }
}

but $app->templates does not work. So is there a Craft3 equivalent of this line?

NB: I have already written a plugin that is adding a file volume (for encrypting files uploaded as Assets) so intend to add to that.

You should be able to do this with Asset Bundles. Full documentation on this is here.


Making changes to existing page - how do I make a draft page first? I'm making extensive updates to our homepage. Before I dig in, I want to confirm the steps to create a draft without overwriting the existing page.

Select the entry that requires changes
Select "Save a Draft"
Make applicable changes
When done, click on "Current" from version drop down
When new content approved, choose the new draft in the drop down and click "Update Entry"

Am I missing something? Is there something I should do differently?

After Step 3, you can hit Ctrl+S (windows) or Cmd+S (macOS). That will just save that update to the entry as a new draft.

Though Craft 3 brings autosaving, I'd still recommend you to use these shortcuts to save the draft.

When that particular draft gets approved, go back to that draft and hit on the big red Save button at the top-right corner. You should see another Save as a Draft grey button before that bit save button.

Current button drop-down shows the document's version history - as in who worked on that particular entry along with the timestamp.


Using Recaptcha v2 and Guest Entries plugin How can I prevent bots from sending tons of messages from a frontend form, it uses the Craft Guest Entries plugin. I'm using Recaptcha 2 but it only hides the submit button and it doesn't work using Craft 2.

All other solutions (antispam) that I check seems quite old...

Thank you.

I don't have much experience with these, but here are some potential plugins you can look into for Craft 2 that use various anti-spam techniques:

https://straightupcraft.com/craft-plugins/snaptcha

https://straightupcraft.com/craft-plugins/sprout-invisible-captcha

https://straightupcraft.com/craft-plugins/google-recaptcha

https://straightupcraft.com/craft-plugins/spam-guard


Category ID not being returned So, in my template I get what I'm calling parentCategory, and I can output what I need:

{% set parentCategory = craft.categories.slug(craft.request.getSegment(2)) %}
{# parentCategory.title and parentCategory.slug output fine #}

But shortly after, I'm wanting to get all the descendants of parentCategory, like so:

{% set cats = craft.categories.descendantOf(parentCategory.id).find() %}
{# outputs all categories, whether descendants or not #}

It seems parentCategory.id is empty:

{{ parentCategory.id }}
{# outputs nothing #}

Any ideas where I'm going wrong here? Why is no ID being returned while title, slug and my custom fields are working fine?

Here's line 1 and 2 from my template:

{% if craft.request.getSegment(3) %}
    {% set parentCategory = craft.categories.slug(craft.request.getSegment(2)) %}

If I change line 2 to:
{% set parentCategory = craft.categories.slug(craft.request.getSegment(2)).first() %}

I get the following error:

Craft\CategoryModel and its behaviors do not have a method or closure named "first".

Yet, I can repeat line 2 later in the template and include .first() and not get the error. What go on?

The craft.categories tag returns an ElementCriteriaModel, so parentCategory.title really shouldn't work. Try changing the first line of code to:

{% set parentCategory = craft.categories.slug(craft.request.getSegment(2)).first() %}


How do I return ALL entries that are singles I'm trying to generate a sitemap and wish to output all the entries that have a section type of 'single' but can't get the the correct syntax.

All of the entries need to return 'single' for {entry.section.type}.

{# This query doesn't work but hopefully helps demo the above question #}

{% for entry in craft.entries.section({'type':'single'}).order('id asc') %}
    <url>
        <loc>{{ entry.url }}</loc>
        <lastmod>{{ entry.dateUpdated.atom }}</lastmod>
        <changefreq>weekly</changefreq>
        {% if entry.section.isHomepage() %}
            <priority>1</priority>
        {% else %}
            <priority>0.8</priority>
        {% endif %}
    </url>
{% endfor %}

Edit:

This query does work but it's a slow bad way of doing it as it gets EVERY entry and filters after the fact:

{% for entry in craft.entries.order('id asc') if entry.section.type == "single" %}
    <url>
        <loc>{{ entry.url }}</loc>
        <changefreq>weekly</changefreq>
        {% if entry.section.isHomepage() %}
            <priority>1</priority>
        {% else %}
            <priority>0.8</priority>
        {% endif %}
    </url>
{% endfor %}

There's no such method available for craft.entries, at least it's not documented. But you can use craft.sections to get an array of section models and filter them with a conditional within a loop:

{# Get all Section #}
{% set sections = craft.sections.getAllSections() %}

{# Loop through all single sections #}
{% for singleSection in sections if singleSection.type == 'single' %}

    {# Get the first (and only) entry of that section #}
    {% set singleEntry = craft.entries.sectionId(singleSection.id).first %}

    {# Output #}
    {{ singleSection }}
    {{ singleSection.isHomepage() ? '(Home)' : '(not Home)'}}
    {{ singleEntry.dateUpdated.atom }}

{% endfor %}


Searching on multiple checkboxes I've got a question that I can't seem to get fixed all by myself... I've got a search form and each entry has got field with some checkboxes (in this case these are options). Now I'd like to search when they check multiple checkboxes but I can't seem to get that to work...
I've set up a form in which I'm fetching a parameter and just to test it with 2 checkboxes checked I've split them up in 'week1' and 'week2' like so:

{% set week_search_query =  week1 ~ ' ' ~ week2  %}

I've tried the same with 'and' and '&' in between the quotes but can't seem to get it to work, while with the 'week1' alone like so:

{% set week_search_query =  week1 %}

it works perfectly. (if I print out the content of 'week_search_query' in this case I get

  weken2017:41

with weken2017 as fieldname and 41 as value).
But what I'd like to to is search by 2 checked checkboxes at once as in the first example, so I can:

craft.entries.search(week_search_query)

All help is welcome, I feel like quite a newbie ATM :-)

Updating answer as question was updated

As I see it, you want to find any and all entries where the field weken2017 has either the value 42 or 43.

Assuming that I have understood this much correctly, {% set entries = craft.entries.search(['OR', 'weken2017:42', 'weken2017:43']) %}


Craft Commerce ajax add to cart, missing information I add items to my cart using ajax, following the code from this post

Update Commerce Cart using Ajax

But there are some things missing in the cart object returned on success, they are :

The URL of the page of the product added
The images, and all the fields from the product added
The name of the variant of the product added

Are these somewhere in the object returned ? Otherwise, how could I retrieve them ?

As Brad said in his answer, what you get back is the lineItem details - enough to update e.g. your totals, shipping quote etc.

The URL of the product, and the product fields etc, are not available in the JSON.  But it's hard to see why they would need to be - you're sending this ajax call from somewhere you already have a reference to the product/variant in your twig templates - why would you need this info repeated in the return object?

If you really need that stuff at that point, you're probably better off ajax loading in a twig template to get at the full product stuff.  If you could clraify what you're actually trying to do I can probably help better/describe what we've done.


Rebuild Search Indexes timing out After some issues with our host, our site has returned - but the search function hasn't.

Any search on either back or front end brings zero results - when the entries which fit the criteria do exist.

Each time I try and rebuild search indexes, I get a timeout, and my browser gives me an error - meaning I'd have to try again.

Any ideas of what I can try would be much appreciated.

Craft 3.1.2 added an index-assets console command that you can use instead of the web-based utility. (#3595)

Sounds like that will work better for you :)

Run this to learn more about it:

./craft index-assets --help


Over ride auto-generated alt tag on image added via Rich Text field When I add an image via a rich text (doing as port of a flexi layout approach) somehow an alt tag gets auto output, e.g:

alt="sketch2.jpg#asset:308

I wondered if there is a way to over ride or edit the HTML via the rich text field for the auto generated alt tag?

The Retcon plugin works great for DOM manipulation. You can override the attribute with a default value or remove it completely.

{{ entry.body|retconAttr('img', {'alt': entry.title}) }}

{{ entry.body|retconAttr('img', {'alt': false}) }}


How do I add commas to an output that returns a list of names? I have a simple for loop to get the names of countries from a category.

{% for name in country %} {{ name.title }} {% endfor %}

The output is typically returns the name of 1 country.  But, some entries are associated with more than one country.

For example:

  Belgium Czech Republic Denmark Greece Netherlands Norway Portugal

How do I template for an entry that returns 2-N country names by adding "," between each country and "and" before the last country?

This is what I want to output:

  Belgium, Czech Republic, Denmark, Greece, Netherlands, Norway and Portugal

You can use loop variables

{% set i = country|length %} // number of total items
{% set indexLast = i - 2 %}  // index of the last comma
{% for name in country %}
    {% if loop.last and i > 1 %} and {% endif %}{{ name.title }}{%if i > 2 and loop.index0 < indexLast  %},{% endif %}
{% endfor %}

Explanation:

if there is more than one item and it is the last iteration: add an and at the beginning
if there are more than 2 items (otherwise it's only one and) and the current loop index is smaller than count - 2 ( it should display nothing in the last iteration and only an and before the last)-> display a comma ,


The difference between username and loginName In the examples they're used mixed:

Registration

<input id="username" type="text" name="username"
{%- if account is defined %} value="{{ account.username }}"{% endif -%}>

Login

 <input id="loginName" type="text" name="loginName"
    value="{{ craft.session.rememberedUsername }}">

For the login form, a field named "username" can not be used, it should be "loginName". What is the difference between the two?

Because you can login with either your email address or your username.  And some sites will be forcing the username to be the email address.


Using Form to update User Profile and submit form Checking the best way to achieve this or if it can be done without a plugin.
I need to allow people to register and create user accounts on my site with various profile information.

Then I will have a form on the site available to users to submit which saves it in the backend and alerts by email. (A&M forms looks like it has this functionality). When a user logs in this form should be prepopulated with data from their user profile.

When the form is submitted - can it update their user profile also?

It is basically a form for users to order repeat prescriptions - so I'm thinking user profile to save the standard date then use that to prepopulate the a&m form. Is what I'm suggesting the best way to achieve this?

Yep, that's totally do-able. Check out this article to see how to create a registration form.

Then check out this article to see how to create the update profile form.

The thing to note is that any custom fields like address or city need to be pre-pended with fields.

So, let's say you want the user to enter their city. On your front-end form the markup looks like this:

City

<input id="city" type="text" name="fields[city]"
{%- if currentUser is defined %} value="{{ currentUser.city }}"{% endif %}>
    {% if currentUser is defined %}
        {{ errorList(currentUser.getErrors('city')) }}
    {% endif %}

... and so on.

Make sure that your field handle(s) in the CP align with what you call them on your front-end form.

Here is how you can check for the current user.

Here is another great example of how to populate custom fields in your profile/registration form.

Hope this helps!


Getting HTTP 500 error at end of update process when going from Craft 2 to Craft 3 with MAMP When I try to perform an update from Craft 2 to Craft 3 I am getting a 500 error at, what appears to be, the end of the process. No other info is given.

I am using MAMP Pro V4 for Mac.

Try switching MAMP out of Fast CGI mode. Go to the PHP Tab and select "Identical PHP Version for all hosts (Module mode)". Restart the servers and then. Then run the update.

You can normally switch back to Fast CGI mode at this point and it will continue to work OK. But if you do run into this, or a file upload problem, it's worth changing to Module mode temporarily as it often fixes whatever is causing the issue.


Using image transforms sometimes results in bloated file sizes. I'm in the process of setting up Asset image transforms for my site and was playing with the quality setting to find the right balance between file size vs. output image quality.

As part of the testing process I was outputting matching images at the same final transform size in Photoshop at various levels of "Save for Web..." quality. I was surprised to see that the images Craft was generating were consistently larger in file size  than the images Photoshop was generating with approximately the same final visual quality. Typically the difference was anywhere from 20-40%.

It feels important to note that I realize that Craft's image transform quality settings don't equate to Photoshop's "Save for Web..." quality settings (i.e. using a quality setting of 65 in Photoshop is not the same as using an image transform quality setting of 65 in Craft).

I tested a variety of image types at a variety of transform and quality settings and found the results to be roughly the same in every scenario.

I'm curious if anyone else has seen / noticed this issue and if there might be a fix.

Is Imagick installed on your server?

If not, Craft uses GD as a "fallback". Chances are that transforms with GD lead to poorer image quality and longer calculation times. I'm not sure about ICC profiles, but I think they only get included using Imagick (photos can look really bad if profile is missing unexpectedly!).


How can I install Craft Commerce 2 alpha release? I tried following the installation instructions here: https://docs.craftcms.com/commerce/v2/installation.html

When I run composer install craftcms/commerce, it says:

  Invalid argument craftcms/commerce. Use "composer require craftcms/commerce" instead to add packages to your composer.json.

So I then ran composer require craftcms/commerce, and it says:

  [InvalidArgumentException]   Could not find package craftcms/commerce
  at any version for your minimum-stability (alpha). Check the package
  spelling or your mini   mum-stability

I have added "craftcms/commerce":"@alpha" in the require field in composer.json also changed minimum stability to alpha ("minimum-stability": "alpha").

But it still is not working. Any thoughts? Thanks!

You have to contact P&T (at support@craftcms.com) directly to get installation instructions.


Server-side address validation in Craft Commerce 3 Was wondering how to do this in Commerce 3 as there were a few different older methods discussed here.

According to Luke, this is the preferred method for Commerce 3.

In a custom module or plugin:

Event::on(\craft\commerce\models\Address::class, \craft\base\Model::EVENT_DEFINE_RULES, static function(\craft\events\DefineRulesEvent $event) {
    $rules = $event->rules;
    $rules[] = [['firstName','lastName'], 'required'];
    $event->rules = $rules;
});

Some more details about what kind of rules you can add here, if you want something more complex than a list of required fields:
https://www.yiiframework.com/doc/guide/2.0/en/tutorial-core-validators


Global Dashboard Configuration Is there any way to change the default configuration for the Dashboard globally, or per user group?

I don't mind Sysadmins seeing the Blog & Tonic feed, but I don't want Members (who access the CP only to add calendar events) to see Blog & Tonic. It will just cause confusion for those users.

Have a look at One Dashboard which works nicely. I've used it to set each users Dashboard to show a collection of pre-defined Analytics widgets.


Template for submit via ajax to Guest Entries plugin I am a bit mystified by how to utilize templates for Guest entries plugin working fine for normal post saving custom fields.

When I use ajax to submit I get an XHR 200 response but an HTML response - no JSON. Ideally I don't want to redirect to another page but just manipulate the DOM and pass some variables into the page form JSON returned on success.

I have read and reread every ajax post but still can't get a pure JSON response

Is it necessary to utilize some kind of detection within the template for Craft ajax?

Just when I thought i had ajax understood...

Here is my JS:

$(document).ready(function () {
//validation rules
$("form#brick").validate({
    ignore: ":hidden",
    rules: {
        "fields[firstName]": {
            required: true,
        },
        "fields[lastName]": {
            required: true
        },
        "fields[email]": {
            required: true,
            email: true
        }
    },
    messages: {
        "fields[email]": "Email is required"
    },

    submitHandler: function (form) {
        // Prevent default posting of form
        event.preventDefault();

        var data = $(this).serialize();

        $.ajax('/', data, function(response) {
            if (response.success) {

                console.log(response);
                $('#thanks').fadeIn();
                $('#brick').fadeOut();
                console.log(response);
            } else {
                // response.error will be an object containing any validation errors that occurred, indexed by field name
                // e.g. response.error.fromName => ['From Name is required']
                alert('An error occurred. Please try again.');
            }
        });
    }
});

});

There are some problems with your JavaScript that I expect is the cause of your issue.

From your code I'm assuming you're using jQuery Validate to validate the form before submission. Your first issue is the line

event.preventDefault();

within the submitHandler() method – jQuery Validate will actually prevent the default form submission for you, so this line is redundant. Also, there is no variable called event, so that's going to cause trouble.

The second issue is that you're using the wrong syntax for the $.ajax() method. Considering your current code, I believe you want to use the $.post() method instead.

Finally, you're serializing the wrong object – $(this).serialize() should actually read $(form).serialize().

With the above issues fixed, your code should look like this:

$(document).ready(function () {

    $('form#brick').validate({

        ignore: ":hidden",

        rules: {
            "fields[firstName]": {
                required: true,
            },
            "fields[lastName]": {
                required: true
            },
            "fields[email]": {
                required: true,
                email: true
            }
        },

        messages: {
            "fields[email]": "Email is required"
        },

        submitHandler: function (form) {

            var data = $(form).serialize();

            $.post('/', data, function (response) {
                if (response && response.success) {
                    $('#thanks').fadeIn();
                    $('#brick').fadeOut();
                } else {
                    alert('An error occurred. Please try again.');
                }
            });

        }

    });

});

Finally, for some pointers on how you could handle errors within the response payload, see this thread.


Use of undefined constant JSON_HEX_TAG I'm running PHP 5.3.3, which the docs say is supported, but if I try to go to the main admin page or go to add a field, I'm getting an error:
    Use of undefined constant JSON_HEX_TAG - assumed 'JSON_HEX_TAG'

Everything I'm finding online points to this being an outdated PHP issue, but thought I would check since I am running a supported version of PHP.

Thanks!

You're likely missing the PHP JSON extension, which is a requirement to run Craft.


Specific word stops entry from saving I've just migrated a craft site to a staging server from a local environment and have come across an odd bug I have no idea what's causing it.

If I use the word "select" in a blog post, the entry doesn't save and instead goes to a 404 page. If I capitalise a letter, "Select" for instance, it saves fine.

It's a rich text field that has the content and this didn't happen on my local environment either. There doesn't seem to be any errors showing up in craft logs as far as I can tell either.

Does anyone have any suggestions?

Thanks.

This sounds like a mod_security issue.

You'll need to reach out to whoever manages your server and ask them to relax the security around saving data to all URLs under your /admin URL area.

What is happening behind the scenes is that the security on your server thinks that you may be trying to query the database and do something malicious. i.e. SELECT * FROM craft_users;


Search Error Appears on Blank Searches Impossible to invoke a method ("getUrl") on a null variable

That's the error message generated by a blank search and some searches.

Fuzzy search is enabled in config/general.php, and it works.  The search template is straight from the Craft CMS "search form" tutorial.

{% set query = craft.request.getParam('q') %}
{% set entries = craft.entries.search(query).order('score') %}

Search Results for "{{ query }}"

{% if entries|length %}
    {% for post in entries %}

{{ post.title}}

{{ post.postDate | date('F d, Y') }} Nicole

    {% endfor %}
{% else %}

You search for "{{ query }}" didn't retun any results

{% endif %}

{{ post.postImage.first().getUrl('thumbImage')}} works without error every place else.

Any ideas on what I am missing?

{{ post.postImage.first().getUrl('thumbImage')}}

Whatever entry post is referencing for whatever search term you're using when you get the error, doesn't have any postImage assets selected.

So when you call post.postImage.first(), that returns null and you can't call getUrl on null.

You can either make postImage required and make sure that all existing entries have at least one asset selected, or guard against it in Twig via:

{% set image = post.postImage.first() %}

{% if image|length %}
    {{ image.getUrl('thumbImage') }}
{% endif %}


Apply discount on login during commerce checkout process I assign users to specific user groups and then I created discounts that are applied to orders based on the user groups that the users are in.

I have a scenario where users add items to their cart while they are not logged in. Then when they are ready to do the checkout I show a login or registration page. The user then logs in and is then redirected to the view-cart page.

When they get to the view cart page there are no discounts applied. Discounts are only applied when an item is added or removed from the cart.

How can I reevaluate and recalculate any applicable discounts based on the user groups the user is in when the user logs in?

I have confirmed this would indeed appear to be a bug in Commerce.

A quick workaround would be to listen to login events and call some sort of update cart hack, but this is really a fix that should happen at the Commerce end of things.

I'll report it.

EDIT: Luke Holder comfirms he's found the bug and it will be fixed in the next point release coming soon.


Is there a way to output only the first paragraph of a Rich Text field? I have a rich text output section I want to limit to the first paragraph so I can link to a full version on another page. What's the best way to do this?

You can do this entirely with Twig.

First, use the |split filter to split your HTML into an array of paragraphs, on their closing
 tags:

{% set paragraphs = entry.myRichTextField|split('
') %}

Then, you can assign the first paragraph to a new variable using the |first filter. And don’t forget to bring back that missing
.

{% set firstParagraph = paragraphs|first ~ '
' %}

Finally, you can output that. Use the |raw filter so that Twig doesn’t encode the HTML entities.

{{ firstParagraph|raw }}


Can images embedded in a Rich Text field be resized on output? I see how to use Image Transforms when the image tag is its own field but don't see a way to handle images within Rich Text fields or force a size on upload.

I need to have the image dimensions match the size the client sized the image to in the Rich Text field. Is there a way to do this?

If you create an image transform in the control panel, the client will be able to choose that transform when selecting an image (in the bottom right corner). But there's no way to get Craft to transform the image based on the size the clients manually set the image to be in the rich text field.


How can I get the parent author from sprout forms to send to sprout mail? I am including a sprout form on my template like this:

...
{{ craft.sproutForms.displayForm('myForm') }}
...

I am submitting the form via ajax, and when the form is submitted I am trying to set the recipient in Sprout Email to the form's container author.

{author.email}

So it's not the author of the submitted form/entry, it's the author of the entry that the form is sitting on that I'm trying to access.

I'd really like to avoid passing in an email from a hidden input if at all possible. Thank you for any suggestions!

Update

For example, I am on the page a.html which  has an author of damon@email.com. On a.html there is a contact form. When a user submits the contact form, I want a confirmation email sent tothem, and then an email sent to the author of the entry that the contact form is on. The same contact form can live on any page, and each page could have different authors.

a.html has an author of damon@email.com
b.html has an author of foo@email.com

In the above case, a confirmation email needs to go whomever filled out the form, and then a notification email to each of the entries respectively.

Update 2

I am getting closer I think, but struggling to dynamically set the recipient.

Here is my form:

...
{% set form = craft.sproutForms.form('myForm') %}
<input type="hidden" name="action" value="sproutForms/entries/saveEntry">
<input type="hidden" name="handle" value="{{ form.handle }}">
<input type="hidden" name="entry" value="{{ entry.id }}">
<input type="hidden" name="author" value="{{ entry.author.id }}">

Then in my plugin I am doing this:

craft()->on('sproutForms.onBeforeSaveEntry', function (Event $event) {
    if (craft()->request->isSiteRequest()) {
        if (craft()->request->getPost('author') != '') {
            $owner = craft()->users->getUserById(craft()->request->getPost('author'));

            if ($owner) {
                if ($event->params['isNewEntry']) {
                    $entry = $event->params['entry'];

                    $entry->setContentFromPost(array(
                        'ownerEmail' => $owner->email, // damon@email.com
                    ));

                   // Set {ownerEmail} as recipient in notification?
                }
            }

In my ajax response I am seeing:

{"errors":[]}

In the sproutemail.log I am seeing:

[error] [plugin] No recipients found.

In the recipient field I have tried {ownerEmail} and {object.ownerEmail} both having no success.

I have also tried setting field values just in the off chance...

{% do craft.sproutForms.addFieldVariables({ entry: entry }) %}

The whole purpose of this is that I am trying to avoid putting a person's email in a hidden input. Just so that if a user of the site viewed the source the author's email wasn't right out in the open.

This can be done using an Invisible Field and the addFieldVariables tag.  Define the value you want as your email in your template:

{% do craft.sproutForms.addFieldVariables({
    'secretEmailAddress': entry.author.email
}) %}

Set the Invisible Field to target that value:

{secretEmailAddress}

And then customize the Notification Email Recipients field to target the handle of the Invisible Field:

{invisibleFieldHandle}

Another example of doing this dynamically from an Entry with a Form Relations field has been posted in response to another question here: https://craftcms.stackexchange.com/a/29553/115


htaccess www to non-www with subdomain Our client has (sadly) presented a new site URL as www.foo.bar.com instead of foo.bar.com. I need to use .htaccess to remove the www. The site works correctly if www is not prepended to the URL.

This question comes close but implementing with a subdomain doesn't work.

Here's my .htaccess:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /

    # Redirect to non-www domain
    RewriteCond %{HTTP_HOST} !foo\.bar\.com$ [NC]
    RewriteRule ^(.*)$ http://foo.bar.com/$1 [R=301,L]

    # Send would-be 404 requests to Craft
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
    RewriteRule (.+) index.php?p=$1 [QSA,L]
</IfModule>

To clarify, I would like to remove both www and index.php from all URLs. So:

http://www.foo.bar.com/yay -> http://foo.bar.com/yay

FWIW, this is hosted on Rackspace, which requires the Rewrite Base / directive.

This question comes close but implementing with a subdomain doesn't work.

It should work as long as you modify the rewrite rule to account for the subdomain:

RewriteCond %{HTTP_HOST} !^foo\.bar\.com$ [NC]
RewriteRule ^(.*)$ http://foo.bar.com/$1 [R=301,L]

The code you posted was missing the ^ before foo\.bar\.com on the RewriteCond line. The purpose of that conditional is supposed to be to catch incoming requests where the domain isn’t exactly “foo.bar.com” (so that it can redirect them to the correct domain on the following line). However without that ^, the conditional would only catch requests where the domain doesn’t end with “foo.bar.com”.  But “www.foo.bar.com” does in fact end with “foo.bar.com” so it’s not going to get caught.

Hope that makes sense.

Update:

Here’s a hostname-agnostic version that’s a little easier on the eyes:

RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]


How get custom user fields in a plugin? How get the custom user fields in a plugin? I can get the normal fields like firstName like this craft()->userSession->user->firstName but how i can get a custom field i tried craft()->userSession->user->customfieldname but that doesn't work.

The UserSessionService::getUser method returns a UserModel.

You can retrieve the custom fields from a UserModel as follows:

$userModel->getContent()->getAttribute('fieldName');

Or, following on from your example:

craft()->userSession->getUser()->getContent()->getAttribute('fieldName');


Mark a Commerce Order as Paid, via a custom plugin Checkout / Payment is being handled entirely by a 3rd Party. What would be the correct process to mark an Order as Paid via a custom Craft plugin?

The Order will already have been converted from a Cart to an Order and assigned an Order Status via a previous step.

The 3rd Party will be calling a series of API endpoints exposed by a custom Craft plugin to process the various steps of the Order.

EDIT: For future reference, base on Luke's answer below, this is the code I got to work...

$orderNumber = "XXXX-XXXX-XXXX-XXXX";

$order = craft()->commerce_orders->getOrderByNumber($orderNumber);

$transaction = craft()->commerce_transactions->createTransaction($order);

$transaction->status = Commerce_TransactionRecord::STATUS_SUCCESS;
$transaction->type = Commerce_TransactionRecord::TYPE_PURCHASE;

craft()->commerce_transactions->saveTransaction($transaction);

craft()->commerce_orders->updateOrderPaidTotal($order);

Your best bet would be to create a transaction for the full amount:

$transaction = Plugin::getInstance()->transactions->createTransaction($order);
$transaction->status = \craft\commerce\records\Transaction::STATUS_SUCCESS;
$transaction->type = \craft\commerce\records\Transaction::TYPE_PURCHASE;
Plugin::getInstance()->transactions->saveTransaction($transaction);
$order->updateOrderPaidTotal();


Loop through all created fields and get the field type I want to show some input fields on frontend template form.

  Type of input is dependent on the type of fields selected on the backend.

For example, if the text field is selected in the backend I will create a field of type="text". If a number field is selected I will show an input type="number" in the template.

I am trying to get the field type in my plugin.

$fields = Craft::$app->fields->getAllFields();
        foreach ($fields as $field) {
             $output[(int) $field->id] = array(
                'id'            => (int) $field->id,
                'handle'        => $field->handle,
                'name'          => $field->name,
                'instructions'  => $field->instructions
            );
        }

I checked the /vendor/craftcms/cms/src/services/Fields.php but not found any method.

Update:
I checked a few files and i found a method which returns the string.

$field->displayName();

Number
Lightswitch

Is it the only way to get the type of field.

Making sure you include use craft\db\Query; at the top of your Class, you can do something like this:

$fields = (new Query())
    ->select(['id','handle','name','instructions','type'])
    ->from(['{{%fields}}'])
    ->all();

foreach ($fields as $field) {
    $output[(int) $field['id']] = array(
        'id'            => (int) $field['id'],
        'handle'        => $field['handle'],
        'name'          => $field['name'],
        'instructions'  => $field['instructions'],
        'type'          => $field['type']
    );
}


Favicon in Control Panel I'd like to add my site's favicon to the admin part of the site.

I tried to do this using the "Site icon" option under general settings. That adds the icon to the sidebar but not as a favicon.

The only way I've found that works so far is by editing the CP's base layout template and adding it there, but that's obviously a bad idea, as that will get overwritten on update.

Anyone found another way to fix this?

If you have a favicon.ico at the base level of your public site I think that should do it. All I can tell you is that this is what works for me.


SSL now CP unknown errors I have a Craft 3 site that's been running on a production server. Recently we switched over to https but this has caused issues in the CP (multiple 'An unknown error occurred' red flags, can't view any of the individual entries or assets, CP utilities like clearing the cache tasks don't run).

Trying to debug it, this seems to largely resolve itself if I set enableCSRF => false in config/general. I can then use the CP to see & edit my entries & assets (although I still get an unknown error flag on the dashboard where the console shows a 400 error get-feed-items for the Craft News widget).

So seems to be related to the enableCSRF config setting. Whenever set it to true I get the error 400 items in the console. I've cleared the browser cache multiple times but that doesn't fix it. I've cleared the Craft cache via the cp (but had to set CSRF to false again otherwise the script doesn't run and gives the 400 error again). Lastly I've manually nuked the cpresources folder in order for it to rebuild.

Web dev isn't my strong point so looking for suggestions so I can try and understand what's going on and what to try next.

After much head scratching it wasn't an SSL issue. Litespeed had recently been installed on the shared server but was misconfigured.

  It appears the allowed header size default value was modified during
  the installation of LiteSpeed which caused the issue. We've now
  restored the default value and the functionality of the website
  appears to have come back.


How to build a web page using different sections created in Craft I am a beginner in Craft. I have a Craft website. There is an HTML design with me. From admin, I divided the HTML into sections and created entries based on that. All the coding related to each sections done.

My question is, from where we will combine these sections for creating a page on the website?

I want to replace some already existing sections with new sections created.
From which part I can find this one?

Actually, not all sections are created equal. Craft actually has three different types of sections:

Singles
Channels
Structures

Well, you need to work with dynamic URLs and Twig to show your sections at Web Page.
Here is the link of official documentation of Craft CMS:
https://craftcms.com/docs/2.x/sections-and-entries.html#sections


Editing a freeform submission entry I have a custom plugin where I get a freeform submission by token. I woud like to change a value in this submission and resave the submission. When I try this the old form data gets overwritten.
$submission = Freeform::getInstance()->submissions->getSubmissionByToken($submissionToken);

$submission->setFormFieldValues(['customField' => $customFieldValue]);

// method 1, doesn't accept type submission, should be form
Freeform::getInstance()->submissions->storeSubmission($submission);
// method 2, old data get's overwritten, current submissiontoken changes
Craft::$app->elements->saveElement($submission);

It looks like setFormFieldValues() has an optional second parameter related to overriding values...
public function setFormFieldValues(array $values, bool $override = true)
So, changing...
$submission->setFormFieldValues(['customField' => $customFieldValue]);
... to...
$submission->setFormFieldValues(['customField' => $customFieldValue], false);
may help with the override issue.


Live Preview in different languages on different top level domains Our website offers three different languages. Each language has it own top level domain (example: domain.de, domain.it, domain.fr). Everything works like it should, except the Live Preview function. We have already tryed the things described here: https://craftcms.com/support/cross-domain-live-preview and a few other tweeks we found in stackoverflow. Every solution we found, only works with subdomains.

As i understand, it's not possible because the browser does not allow cookies accross domains (Cross-Domain Policy).

Does anyone have experience with handling various languages and top level domains in Craft CMS? How can we handle this requirement?

With the current implementation of Live Preview in Craft, using Live Preview across different top-level domains isn't possible due to the cross-domain policy (as you found out) along with a few others.

We've got a few ideas on how we might address this in the future, but it will definitely be after Craft 3 comes out.


Multiple Relations Trouble I'm having trouble setting entries with multiple relations.
during testing I've hard coded the theme to 1 specific category
{% set themeID = "12309" %}
{% set theme = craft.categories.group('survivorThemes').id(themeID).all() %}

I then set this
{% set survivors = craft.entries.section('authors').includeInRecollection('1').relatedTo({ sourceElement: relatedAssetIds }).orderBy('lastName asc').limit(null).all() %}
and then a for loop
        {% for survivor in survivors %}
            {% set relatedIds = "" %}

{# this should work but doesn't #}
            {% set entries =
                craft.entries.section('survivorAssets')
                .relatedTo('and', { targetElement: themeID },{ targetElement: survivor })
                .orderBy('assetOrder')
                .all()
            %}

{# this should also work but doesn't #}
            {% set testEntries = craft.entries.section('survivorAssets')
                .relatedTo('and', {targetElement: survivor, field: 'relatedSurvivor'}, {targetElement: themeID, field: 'themes'})
                .orderBy('assetOrder')
                .all()  %}

            survivor: {{ survivor.title }}

            theme: {{ themeID }}

            ids: {{ relatedIds}}

            total results: {{ entries|length }}

            test total: {{ testEntries|length }}

                {% if entries|length %}
                    {% set activeClass = " active" %}
                    {% for entry in entries %}
                        {% set relatedIds = relatedIds ~ entry.id %}
                        {% if not loop.last %}
                            {% set relatedIds = relatedIds ~ "," %}
                        {% endif %}

              more code here

                    {% endfor %}
                {% endif %}

        more code here

        {% endfor %}

In the above loop I expect the entries to have results but I get zero results in my test div.

survivor: Judy Abrams
theme: 12309
ids:
total results: 0
test total: 0

Have confirmed that there should be 3 entries that match the entries or testEntries variable by looking at specific entries in the control panel.

The relatedTo parameter can take an object, an element ID or an array of element objects and/or IDs. In your case the latter is expected so wrapping your arguments in an array should fix the issue:

{% set entries = craft
                .entries
                .section('survivorAssets')
                .relatedTo(['and',{ targetElement: theme },{ targetElement: survivor }])
                .orderBy('assetOrder')
                .all() %}


How to receive email notification when an error or bad request happens? Is it possible to receive email notifications when there is an error or Bad Request issue in Craft CMS?
We had an issue where our contact forms were not working due to craft.app.config.general.[csrfTokenName] changing to craft.app.config.general.csrfTokenName. No warnings in the deprecated code section. Instead, potential customers would see a Bad Request message, but we had no idea for days.
I would like to be alerted if such an error occurs so I can fix the issue much quicker.
Similarly, if there is an error on the site anywhere, I would like to be alerted.
Is it possible?
Thanks

I'd recommend using a service like Sentry or Bugsnag that are tailored exactly for this situation and include some Craft integrations as well:
https://plugins.craftcms.com/search?q=sentry
https://plugins.craftcms.com/search?q=bugsnag