Frontend form database error with empty Users field Within a frontend Add Product form (using Craft Commerce) I'm having problems with a database error whenever a Users field is left empty.

Here's the field:

{% set teachers = craft.users.group('teachers') %}
<select name="fields[teacher][]">
<option value="">n/a</option>
{% for teacher in teachers %}
  <option value="{{ teacher.id }}">{{ teacher.name }}</option>
{% endfor %}
</select>

I've tried setting the empty value to zero, but no luck. The forms works fine apart from this, so I don't think it's anything specific to Craft Commerce.

Figured it out. If you want to return an empty Users field, the field name attribute has to look like this:

<select name="fields[teacher]" value="">

But if you want to return a non-empty Users field, the name attribute is different:

<select name="fields[teacher][]" value="{user.id}">

So, I'm starting with the first example, and using an onChange event to switch the name attribute depending on whether the value is a valid user ID or not. Here's my final template code:

{% set teachers = craft.users.group('teachers') %}
<select class="ui search dropdown" name="fields[teacher]" id="teacherselect">
<option value="nA">n/a</option>
{% for teacher in teachers %}
  <option value="{{ teacher.id }}">{{ teacher.name }}</option>
{% endfor %}
</select>

And the jquery if anyone wants it:

($(this).val() == "nA") ? $(this).attr('name', 'fields[teacher]') : $(this).attr('name', 'fields[teacher][]')

This works.


Craft CMS 3 storage doesn't exist or isn't writable by PHP I am going to do an internship in February where they work with Craft CMS and thus I am going to learn it at home with XAMPP ( localhost). However I've installed it and now it will simply give me the following error:

  D:\xampp\htdocs/storage doesn't exist or isn't writable by PHP. Please fix that.

I have tried to remove the "read-only ". Everything is on full control through the security tab. I got no clue how to "allow" this to write.

I'm on Windows 10, so if you're on another version of Windows, things might be slightly different.

If you right click on that "storage" folder, go to Properties, click the "Security" tab, click "Edit", click "Add", type "Everyone", then click "Check Names" so it finds the user (an underline will show up under it), click "OK", make sure "Everyone" is selected, then check the "Full control" checkbox under permissions, click "OK", then "OK" to close the final modal, that will give everyone access to write to that folder (including PHP/Craft).

Obviously, don't do this on production, but since you're on a local box you should be fine.


SproutForms: User permissions to edit form settings not being honored I am trying to setup a user permissions such that only a specific user group has permissions to create and edit SproutForms.

When editing the permissions for a user group, there is an option for SproutForms labeled Edit Form Settings. If I leave this setting unchecked, but check the Access SproutForms under the General heading so that the user may view form submissions, a user in this group is still able to create and edit forms.

Is this a bug? Running SproutForms version 2.3.2.

Any help would be much appreciated.

I ran into this as well. I only wanted to client to view the submissions but not edit the actual forms. I don't believe it's a bug they just didn't give it a separate permission.

Here's my workaround:

I edited all three sproutform templates in the _layouts folder.

base.html
elementindex.html
settings.html

I moved

forms: {
  label: "Forms"|t,
  url: url('sproutforms/forms')
}

within the

if currentUser.can('editSproutFormsSettings')

Now the "Edit Form Settings" permission includes the actual forms.


Matrix: get the index number of a certain block I have a matrix set up with some blocks in it, and one of those blocks is to add "steps" to a page in a matrix. Now I'm trying to get the number of the step so that they only have to enter the content of the "steps" block, and that it automatically numbers it.

For example:

The matrix has 2 block types: "steps" and "image".
If I make 2 "steps" blocks and 1 "image" block in this order: step - image - step, index.loop numbers the first step as one, and the 2nd step as three since image is in between them.

Is it possible to have the "steps" numbered by position in the "steps" loop, and not in the full matrix?

You can use a custom counter instead of using the loop.index value.

{% set step = 0 %}

{% for block in entry.matrixBlocks %}
    {% if block.type == 'stepBlockType' %}

        {% set step = step + 1 %}
        Current step: {{ step }}

    {% elseif block.type == 'otherBlockType' %}

        {# Don't increase step count #}

    {% endif %}
{% endfor %}


How do you get ahold of a TagModel in a template? I have a route that matches:

/blog/tagged/{tag}

And in my template I would like to pull up all blogs that are related to the tag:

{% if tag is defined %}
    {% set blogTag = craft.tags({ name: tag, group: 'blogTags' }) %}
    {% set filter = filter|merge({ relatedTo: blogTag }) %}
{% endif %}

{% for entry in craft.entries(filter).find() %}

But this doesn't work since craft.tags() gives me an ElementCriteriaModel, but I need a TagModel to work with relatedTo().

I can't figure out how to get the TagModel here.

I figured this one out right after I posted it.

{% set blogTag = craft.tags({ tag: tag, group: 'blogTags' }).first() %}

One mistake was searching for it with "name" instead of "tag".

The other mistake was that I needed to call first() to get the TagModel. Otherwise, craft.tags() just returns an ElementCriteriaModel.


Can't get Craft running on a remote server I have a Craft site that works great locally, but I can't get it running on a staging server. The virtual host is working and when I remove code from index.php in html it runs perfectly. Here is the error...

  Could not find your craft/ folder. Please ensure that $craftPath is set correctly in /var/www/vhosts/testsite/staging/html/index.php

I've seen the error reported online but no solutions, any ideas?

If you upload Craft, your folder structure should look like this (default):

  /craft/..
  /public/index.php

If this is not the case, you have to set $craftPath (in the index.php) depending on your folder structure. Check out the Installing section in the docs.

.

Example:

If your structure looks like this..

  /craft/..
  /index.php

..the path should be: $craftPath = './craft';


A more economical method of building an archive menu? I seem to be having trouble with the performance of my site (on localhost) after including this object. Im using it to build a menu for an archive of the posts section which has about 2,500 entries inside of it.

{% set allEntries = craft.entries.section('posts').limit(null) %}

{% for year, entriesInYear in allEntries | group("postDate.year") %}
    {{ year }}
{% endfor %}

This fetch request spits out the following:

  2016 2015 2014 2013 2012 2011 2010 2009

When I make this fetch request, my page is reload time is ~11s. If I comment out this request my page reload time is ~3s.

Is there a more economical way to return the years associated with my posts?

If you know which years should appear, and there are no breaks in the timeline, perhaps it would make more sense to do a simple numeric loop instead...

{% for year in (now.year)..2009 %}
    {{ year }}
{% endfor %}

That will count backwards from the current year to 2009.


Resaving Events Entries failed This question is identical to Resaving blog entries keeps failing except that I'm not finding any [error] or [warning] in my log entries.

I have changed my entry URL format for the section named Events from

{mainCategory.last().uri}/{slug}

to

{mainCategory.last().uri}/_entry

as described here: Is it possible to view 'Expired' entrys on the front end? and when I hit save on the section page, then it immediately gives the failed task: Resaving Events entries. Any thoughts?

UPDATE

OK, I did find this error:
2016/12/18 02:26:41 [error] [application] Encountered an error running task 422 (ResaveElements), step 2 of 197: Encountered the following validation errors when trying to save entry element "Transforming Work" with the ID "19":
 - URI "fort-collins/weekly/buddhist-meditation-classes/_entry" has already been taken.

I'm not sure quite what it means. There's only one entry named Transforming Work.

There's only one entry named Transforming Work.

That might be true, but you’re telling Craft to store the entry with an URI

fort-collins/weekly/buddhist-meditation-classes/_entry

Change your entry URI format back to something that’s going to be unique for each entry, probably you’ll want to replace the hardcoded string _entry with the dynamic variable {slug} again, or better, do what is actually described in that Stack Exchange answer you linked to and don’t use the default Entry routing at all (disable “Entries in this section have their own URLs”) and rebuild the route with a custom one (see the Craft docs on Dynamic Routes).


Using a Lightswitch to insert a class on a body's tag I'm trying to use a Lightswitch field to insert a class on my body tag if the field is turned on.

What would be a good Twig template code to do this?

Edit 1:

Thanks for answering, guys. I still couldn't manage to do it, though. My lightswitch field handle is named whiteText. If I do this:

<body class='{% if whiteText('1') %}white{% endif %}'>

it'll just say:

  The function "whiteText" does not exist

(which I assume seems logical for you guys, but not for me).

And if I use entry.whiteText it'll say:

  Craft\EntryModel and its behaviors do not have a method or closure
  named "whiteText".

I should also have some kind of "else" in the code, to output a clean -tag if the lightswitch is not switched on.

Edit 2:

I have now set up a global field. If I do {{ globalfieldhandle.lightswitchfieldhandle }} it outputs 0, even on the craft entry section I have it switched on (a single).

I need a way to make it say "1" if the lightswitch is turned on on the entry, and some help with the code to add a class on the body tag, and also the code for doing nothing if its not turned on.

Anyone?

The first answer to my question:

<body class='{% if lightswitch_field_handle %}class_name{% endif %}'>

seems like the right direction, but is it missing something?

Lightswitch fields save an integer to the database:

This integer can be checked just like a boolean, with Twigs if-tag:

<body class='{% if lightswitch_field_handle %}class_name{% endif %}'>

  1 = true  = on
  0 = false = off

.

Twig has also a ternary operator which is similar to php's ternary operator:

<body class="{{ lightswitch_field_handle ? 'class_name' }}">

<body class="{{ lightswitch_field_handle ? 'class_name' : 'alt_class_name' }}">

Answer to Edit 1:

Your example doesn't work because you aren't comparing: if value == 1, you are checking a function: if function(param) == true. Check out the Twig if documentation for more examples.

If entry.whiteText doesn't work, your section doesn't have such a field. If you added it to your main template, you should check if the field is defined.


How to use localized categories properly? I've setup a localized site (de/en) with custom routing for my categories (which are marked as translatable). I use a tag route for my categories which points to the same template as my structure. Everything seemed to work fine but then I realized that the custom filter (via relatedTo) also outputs entries that don't belong to the current category locale.

To make it clear I'll try to give a rough schemata of my setup (using Craft Pro 2.3.2640):

section projects:

has the entry url format:
  de -> projekte/{slug}
  en -> projects/{slug}
entry template path:
  projects/_entry

single projectsIndex:

has the entry url format:
  de -> projekte
  en -> projects
entry template path:
  projects/index

routes:

de -> projekte/(tag)
  template path: projects/index
en -> projects/(tag)
  template path: projects/index

category:

doesn't have a it's own url
category field is marked as translatable

category entries (german version and the english translation):

 - de -> kultur      en -> culture    | (resp. title and slug)
 - de -> industrie   en -> industry   | (resp. title and slug)
 ...

project entries:

 - Entry A:
     de -> category relations ['industrie', 'kultur']
     en -> category relations ['industry']
 - Entry B:
     de -> category relations ['kultur']
     en -> category relations ['culture']

template projects/index.html:

...
{% set _filter = tag|default(null) %}
{% set _category = craft.categories.slug(_filter) %}
...
{% for entry in craft.entries.section('projects').relatedTo(_category) %}
   ...

urls (here comes the trouble):

 - /projekte
     -> lists german version of 'Entry A' and 'Entry B'  (expected)
 - /en/projects
     -> lists english version of 'Entry A' and 'Entry B' (expected)

 - /projekte/kultur
     -> lists german version of 'Entry A' and 'Entry B'  (expected)
 - /en/projects/culture
     -> lists english version of 'Entry A' (NOT expected) and 'Entry B'

...'Entry A' on '/en/projects/culture' shouldn't show up just because there's the 'kultur' category attached to the german version of this entry!

I already tried to explicitly restrict the '_category' by using the '.locale' method but that didn't help either. Now I wonder if I'm doing something fundamentally wrong or if this is a bug by craft itself.

Any tips are appreciated.

Thanks

Update:
Answering my own question here.

To answer my own question see below:

As carlcs pointed out correctly the problem actually isn't located in getting the category - which works just well and is the right way to do it - but in how the relation to the entries is done.

I should check if the tag (coming from the url) actually resolves to a "real" category, otherwise just all entries will be shown.
just handling over the category to the .relatedTo method on craft.entries won't do it because that just fetches all entries related to this category irrespective to its locale - sourceLocale: craft.locale needs to be set.
Still not finished; because we want to "find elements related to the given element, where the given element is the target of the relation" – target in this sense is the category – we need to define it as tagetElement in the relatedTo method.

...

Getting the entries should now look like this:

{% if categories|length %}
    {% set entries =
              craft.entries.section('projects').relatedTo({
                 targetElement: categories,
                 sourceLocale: craft.locale
              })
    %}
    {% for entry in entries %}
    ...
    {% endfor %}
{% endif %}

...

And the actual title of my question should be "How to do category relations with locales" ;)


Combining Multiple Relation I am trying to accomplish targeting but wondering if there is a way to combine these two? I took a look around and in the Craft 3 docs but I am a bit turned around on this, really would appreciate some help with it.

{% set parts = craft.categories.group('part').slug( urlSlug2 ) %}
{% set models = craft.categories.group('model').slug( urlSlug3 ) %}

{% set entries1 = craft.entries.section('flightcompany').relatedTo({
    targetElement: parts,
    field: 'partsModels.part'
}).limit(5).all() %}

{% set entries2 = craft.entries.section('flightcompany').relatedTo({
    targetElement: models,
    field: 'partsModels.model'
}).limit(5).all() %}

You might have seen Passing Multiple Relation Criteria  in the docs

{% set entries = craft.entries.section('flightcompany').relatedTo([
    'and',
    { targetElement: models, field: 'partsModels.model' },
    { targetElement: parts, field: 'partsModels.part' }
]).all() %}

You can as well take a look at the Db::parseParam the and|or syntax is the same for this field


Is it possible for an Element Type to return multiple content tables with the getContentTableForElementsQuery() method? I'm building a plugin where each Element created has a unique content table associated with it.  Each individual Element behaves as needed, however, when I try to create an index page that returns all of the records of this Element Type, Craft seems to assume that I'm using the default content table unless I tell it differently in the getContentTableForElementsQuery() method.

However, the results that are being returned have Elements with multiple content tables.

Am I overlooking anything here or is there a different way I should be thinking about this?

You can only return a single content table per element query.

If you need to join multiple content tables, you have two options:

Use multiple element queries, one for each group of elements that share a content table. Disadvantage of this approach is, you won't be able to order elements in SQL.
Just don’t join in any content tables in the initial elements query, and let your elements lazy-load their content rows if any custom fields are actually accessed on the elements. You can do this by having your element type’s getContentTableForElementsQuery() function return null. The only disadvantage here is that you won't be able to order/filter by custom field values, since those tables won’t have been joined in.

If you go this route, you will need to make sure that your model that extends BaseElementModel is overriding the getContentTable() function (which it should be anyway, if you’re using custom content tables). That way it will know which table to pull data from if any custom field values are requested from it.

In your case, if each element is going to have its own content table, then option #2 is probably going to be your best bet.


Freeform Lite update on Craft 2 deleted tables I am on Craft 2.6.3015 and have Freeform 1.3.0 installed. I'm trying to update to the latest Freeform Lite 1.8.7 but it consistently fails.

When I try on my local environment I just get the message:

  Craft was unable to install this update :(
  The site has been restored to the state it was in before the attempted update.
  There was a problem updating your database.

But on my remote server it deleted two thirds of the tables in the db.

I actually have 7 similar sites where I have done this same update no problem but this one site fails every time. I'm not sure what the difference could be.

I wonder if I can get my hands on an intermediate version of Freeform to try updating to if that would help?

But on my remote server it deleted two thirds of the tables in the db.

That sounds like some update failure happened, Craft tried to roll-back and restore the database from its pre-update attempt database backup because https://docs.craftcms.com/v2/config-settings.html#restoreDbOnUpdateFailure is set to true, then plot twist another failure happened before it could restored and left the database in an inconsistent state.

There are tons of reasons an update might fail to go through, and nearly as many for why a restore would fail, but a good place to start would be your craft/storage/runtime/logs files as well as your web server's log files.


Plugin init check if current page is dashboard Is there an easy way to check if the current page is the Dashboard?
I have a widget that needs several Javascript resources but if I include them in the widget library I get a google maps error that I should not do that.
You have included the Google Maps API multiple times on this page. This may cause unexpected errors.

I could make a workaround and set a static public variable to false after the first include but that would be kinda dirty.

So all I want to know id there is something like

function init()
{
    if (craft()->isDashBoard()) {
        //include all JS ressources
    }
}

or if there is a better way to include Javascript.

Nope, but you can use the {% includeJsFile %} tag to include the file(s) from your widget template. In whatever template you render in your widget's getBodyHtml() method, add this:

{% includeJsFile "https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY" %}

If you need to queue up several files, you'll need several {% includeJsFile %} tags. There's also a {% includeCssFile %}, if you need to add some external CSS, as well.


Yii Toolbar triggering mixed content warning in CP I've enabled Show the debug toolbar on the Control Panel in my Craft Admin account in a local development environment that uses SSL. As soon as I enable it, I get the following error each time I load any page in the CP:

VM1685:1 Mixed Content: The page at 'https://domain.dev/admin/myaccount' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://craft3.dev/actions/debug/default/toolbar?tag=5a495cbcf3e15'. This request has been blocked; the content must be served over HTTPS.

SSL seems to be set up and working fine. I have the siteUrl variable in my general.php set up with an https url as well:

'siteUrl' => 'https://domain.dev',

What could be triggering this warning?

On a multi-site setup, you need to use the multi-site array syntax for the siteUrl config setting like so:

'siteUrl' => [
    'siteHandle1' => 'https://foo.com/',
    'siteHandle2' => 'https://bar.com/',
],


How can I programmatically add a tab to entry type? I'm trying to create a plugin that adds a tab full of fields to entry types but I can't seem to get it working. I tried assembleLayout but that replaced all the fields with my new fields rather than adding a new tab to them.

I'm trying different combinations of FieldLayoutTabModel->setFields() but that throws an error about a fieldId property which leads me to believe I don't quite have the data types right. Any help would be appreciated.

I eventually figured this out. Here's the code that's working for me:

$newFields = array(
  0 => '12', // $field->fieldId
  1 => '15'  // $field->fieldId
);

// First we get all sections and loop through them
$allSections = craft()->sections->getAllSections();
foreach ($allSections as $section)
{
  // Then we get all EntryTypes of each section and loop through those
  $sectionEntryTypes = $section->getEntryTypes();
  foreach ($sectionEntryTypes as $entryType)
  {
    // Grab the current layout and tabs
    $currentLayout = $entryType->getFieldLayout();
    $currentTabs = $currentLayout->getTabs();

    // This will the array passed to assembleLayout
    $postedFieldLayout = array();

    // Loop through each tab and build our array
    foreach ($currentTabs as $tab) {
      $fields = $tab->getFields();
      foreach ($fields as $field) {
        $postedFieldLayout[$tab->name][] = $field->fieldId;
      }
    }

    // Append the new fields we want to show to that array
    $postedFieldLayout['newFields'] = $this->newFields;
    $requiredFields = array();

    // Assemble the layout
    $fieldLayout = craft()->fields->assembleLayout($postedFieldLayout, $requiredFields);
    $fieldLayout->type = ElementType::Entry;
    $entryType->setFieldLayout($fieldLayout);

    // Save it
    if (craft()->sections->saveEntryType($entryType))
    {
      Craft::log('Successfully appended fields.');
    }
    else
    {
      Craft::log('Could not append the fields.', LogLevel::Warning);
    }
  }
}


What's that |t - filter for? I found this part of code in the documentation

{% set title = "Cocktail Recipes"|t %}

What does |t mean there?

It's the short syntax for the translate filter. Set up a translation file as described in the docs and the string you apply that filter to is translated according to it.


User not being logged out when visiting {{ logoutUrl }} link I have a login area on a site which basically just shows a users profile fields. I'm using the {{ logoutUrl }} tag for my logout link and when the user goes to the logoutUrl they're redirected to the homepage however if they visit the profile page URL again, they can still see the content (as if they're logged in) until they do a hard refresh (CMD + SHIFT + R). This seems to be the case in three different browsers. I have tried both of the following to determine if the user is logged in:

{% if craft.session.isLoggedIn %}

And

{% if currentUser %}

Both seem to be effective at showing the content once they login but it's as if the session is being cached or something as these tests are still true after logging out.

Note this happens when I either click a link to the profile URL or manually type it in the address bar. I am not clicking back in the browser.

Also I have also set a custom path with "logoutPath" in the config but this doesn't seem to be affecting the issue I'm having.

Any help would be greatly appreciated!

Turns out this was caused by me setting a "Cache-Control: max-age" header which I was testing with Google Page Speed and I forgot to move it. This meant the browser was caching everything including the session cookie.


My Entry URL Format needs are too long for the field restrictions I'm trying to set the URL of my product entry's to be dynamically created based on 3 category fields and 2 number fields. The category fields are required, but I need to add some logic for the number fields.

It's all taking up so much space that upon saving the section's settings, the URL Format field cuts off some of my code. I'm sure there is a great reason that this field has a character limit so is there anything else I can do? I tried importing a macro, but couldn't get that to work. Do I have to create a plugin?

This is the content I need to use in my Entry URL Format that is too long with my variable names:

some-text-here/{%if object.mfgCategory.first.slug=="1hack"%}hack{%else%}{mfgCategory.first.slug}{%endif%}-{%for c in object.series%}{c.slug}-{%endfor%}{sizeCategory.first.slug}-{%if object.num1=='0'%}00{%else%}{number1}{%endif%}-{%if object.number2=='0'%}00{%else%}{number2}{%endif%}

You could refactor it using ternary syntax and see if it fits. Otherwise you could also do it with a plugin and listen to beforeSaveEntry events.


Including and reusing common code per matrix block In each matrix block, I'm allowing users to set a background image, background color etc with a settings field.

In each matrix block template, I have:

{% block content %}

  {% set backgroundColor = '' %}
  {% set backgroundImage = '' %}

  {% for row in block.settings %}
    {% set backgroundColor %}background-color: {{ row.backgroundColor }};{% endset %}
    {% set backgroundImage %}background-image: url({{ row.backgroundImage.first().url }});{% endset %}
    ... more fields go here...
  {% endfor %}

  <div style="{{ backgroundColor }} {{ backgroundImage }}">
    ... content here ...
  </div>

{% block content %}

Rather than repeating {% for row in block.settings %} in each template, is there a way that I could write it once and reuse it using a single include call?

I could use

{% include "_widgets/_settings" with {
  backgroundColor: backgroundColor,
  backgroundImage: backgroundImage
} %}

But that doesn't really reduce the amount of code duplication. Ideally I like to use a single of code to make these variables available.

Take 2:

I think you may be looking to use a Twig Macro. Here's the gist of that approach, but I don't fully understand the layout of your template yet, so my answer may be a bit out of context until I do.

You'll need to create your macro higher in your template or in a separate file and import it into the template you are working in. (See the docs linked above on how to import a macro for your situation.)

You could then simplify your block output to something like this.  I'm using fairly verbose names for this example but you can shorten the variable names to have less code if you prefer.

{% import "_widgets/_settings.html" as settingsMacro %}
{% set settings = block.settings %}

  ... content here ...

In your macro file, you'll take those settings and process them as you need to:

_widgets/_settings.html

{% macro backgroundColor(settings) %}
  {% set backgroundColor = '' %}

  {% for row in settings %}
    background-color: {{ row.backgroundColor }};
  {% endfor %}
{% endmacro %}

{% macro backgroundImage(settings) %}
  {% set backgroundImage = '' %}

  {% for row in settings %}
    background-image: url({{ row.backgroundImage.first().url }});
  {% endfor %}
{% endmacro %}

I think, due to how many matrix blocks are fairly short templates, the amount of code you may need to avoid reuse still may be a couple lines after you import a macro and call the specific macros.  But like the include, this could be another way to help ensure consistency in the code being used in multiple places. Hopefully this gives you a few more ideas to work with to find a satisfying solution. I'd need to have a better understanding of your full template picture to offer a more specific solution on how to implement.

Take 1:

If I understand correctly, I believe one way you can do what you are trying to do is by using the include with syntax and making sure you are passing your variables to the include template:

{% include "_widgets/_settings" with {
  backgroundColor: backgroundColor,
  backgroundImage: backgroundImage
} %}

This assumes that you are defining backgroundColor and backgroundImage before your include, and that the include has the following code:

 ... content here ...

Also note, adding the underscore to your folder path hides all files within it.  So, if you don't want to have to add underscores in front of every file, you still have hidden files if they are within a hidden folder, i.e: _widgets/settings


Multi-Region & Multi-Language I'm trying to setup a multi country site running off one Craft install.

example.com
ca.example.com
uk.example.com

Each countries content will be translated into five languages (English - en, Spanish - es, French - fr, German - de, Japanese - ja).

example.com/en
example.com/es
example.com/fr
example.com/de
example.com/ja

ca.example.com/en
ca.example.com/es
ca.example.com/fr
ca.example.com/de
ca.example.com/ja

uk.example.com/en
uk.example.com/es
uk.example.com/fr
uk.example.com/de
uk.example.com/ja

Entries will be translated into all five languages. But, entries should also have the ability to display in one or two or all of the countries etc. I understand how the locales (translations) functionality built into Craft can handle the languages but how would the countries be handled at the same time?

I think this is partially related to a question I raised recently, even though my site won't have that many languages per country but some countries will have 2 languages.

How can I add in new Locales to the locale list?

Then you would do something like this in your config

return array(
    'example.com' => array(
        'siteUrl' => array(
            // Global locales
            'en' => 'http://example.com/en/',
            'es' => 'http://example.com/es/',
            'fr' => 'http://example.com/fr/',
            'de' => 'http://example.com/de/',

            // Canada locales
            'ca_en' => 'http://ca.example.com/en/',
            'ca_es' => 'http://ca.example.com/es/',
            'ca_fr' => 'http://ca.example.com/fr/',
            'ca_de' => 'http://ca.example.com/de/',

            // UK locales
            'gb_en' => 'http://uk.example.com/en/',
            'gb_es' => 'http://uk.example.com/es/',
            'gb_fr' => 'http://uk.example.com/fr/',
            'gb_de' => 'http://uk.example.com/de/',
        ),
    ),
);

This should work, I haven't tested it as yet as my site is still in planning stages and I have not gotten into the development phase as yet.

Edited answer based on comment.

For all countries to use the same English, you can set your array to look like below, however this will not allow individual countries to have different English copy since we are pointing them all to the same Locale now.

return array(
    'example.com' => array(
        'siteUrl' => array(
            // Global locales
            'en' => 'http://example.com/en/',
            'es' => 'http://example.com/es/',
            'fr' => 'http://example.com/fr/',
            'de' => 'http://example.com/de/',

            // Canada locales
            'en' => 'http://ca.example.com/en/',
            'ca_es' => 'http://ca.example.com/es/',
            'ca_fr' => 'http://ca.example.com/fr/',
            'ca_de' => 'http://ca.example.com/de/',

            // UK locales
            'en' => 'http://uk.example.com/en/',
            'gb_es' => 'http://uk.example.com/es/',
            'gb_fr' => 'http://uk.example.com/fr/',
            'gb_de' => 'http://uk.example.com/de/',
        ),
    ),
);


Add variable to purchasable variant to modify price? Is it possible to somehow (plugin or otherwise) modify the price of a lineItem/variant based on variables like material or any other additional modifier (basically affecting the same stock of items).

For example:
Pillow (with variants being color)
— Stuffing material
— Print yes/no

The pillow base product itself is a finite number of items for each color, but the stuffing isn't fixed in that sense, effectively being infinite in terms of stock.

Would it be possible to create separate products and use the Multi Add plugin for this, rather than doing some form of (preferably simpler) custom approach?

I think Multi Add will be the simplest approach here - it really won't be hard with that, and Luke repeated recently that multi-add will become core, so apart from some possible minor template modification later, it seems a sensible way to build this - and will be simpler (going forward as  well) than writing a new plugin for it, where you'll have to take a lot more care with your extra logic for shipping/tax etc.  Multi add just adds multiple products, but leverages core ine very other way, so it's a very robust solution.


Avoiding initial load for image transform I'm using the element API to get the url of an asset from angular with:

'image' => $entry->playerImage->first()->getUrl("square"),

Problem is until i visit that image in the browser the url doesn't work, does someone know of a nice way of dealing with this?

You can tell Craft to generate new image transforms right when getUrl() is called by setting the generateTransformsBeforePageLoad config setting to true. Assuming you still want the default behavior on your main website, you can set the setting programatically from your endpoint config with ConfigService::set():

'endpoint/path' => function() {
    craft()->config->set('generateTransformsBeforePageLoad', true);

    return [
        // ...
    ];
},


How to filter the plugin store by price We have a tight budget for a new Craft 3 site. How can the paid plugins be filtered from the store, so we can review only the free ones?

I'm afraid you can not. But a bit of PHP and the plugin store's API url shows you the list of plugins of which the first edition is free (or go to this page):

<?php

 $perPage = 100;
 $page = 1;

 $done = false;
 while (!$done) {
   $url = 'https://api.craftcms.com/v1/plugin-store/plugins?perPage=' . $perPage . '&page=' . $page . '&orderBy=name&direction=asc';
   $response = json_decode(file_get_contents($url));

   if (isset($response->plugins) && !empty($response->plugins)) {
     foreach ($response->plugins as $plugin) {
       if ($plugin->editions[0]->price === null) {
         echo '' . $plugin->name . '
';
         echo $plugin->shortDescription . '
';
         echo 'handle . '" target="_blank">Show me more

';
       }
     }
   }

   if ($response->totalResults <= ($perPage * ($page))) {
     $done = true;
   }

   $page++;
 }


Craft Commerce: where to modify data sent to gateway (need to send customer data)? I'm using Braintree with Craft Commerce using this Omnipay Braintree Gateway for Craft Commerce
https://github.com/samuelbirch/craftcommerce-braintree

It's working well, but I noticed that some customer data is not passed through to Braintree at the time of a successful purchase. Specifically, the customer information that is mapped from the customer parameters in the transactions sale call.

Working directly with Braintree API it would be done as part of the sale method that includes amount and creditCard etc on the transaction.

Braintree_Transaction::sale([...], array('customer' => array()));

I'm a bit stuck trying to find where to actually make a modification to pass this data through in the context of Omnipay and Craft Commerce. Does anyone have an idea of where to start? I realize this is a vague question... please comment if there is something specific that I can clarify to make this question more answerable.

Update:

It looks like maybe what I should be using is a Craft Commerce hook. Probably commerce_modifyGatewayRequestData. So I'm starting there, but if anyone has tips it would be appreciated!

Ok so it works pretty much how the documentation would lead you to think.

This is for Commerce V1 but apart from hooking up to the event, it should be much the same for V2.

public function commerce_modifyGatewayRequestData($data,$type,$transaction)
{

        // Dump the data to see what is there...you can do what you like to $data and then you return it at the end...
        BusinessLogicPlugin::log("commerce_modifyGatewayRequestData - UNMODIFIED DATA");
        BusinessLogicPlugin::log("data");
        BusinessLogicPlugin::log($data);
        BusinessLogicPlugin::log("type");
        BusinessLogicPlugin::log($type);
        BusinessLogicPlugin::log("transaction");
        BusinessLogicPlugin::log($transaction);
    }

    # Example...
    # TRUNCATE any over-sized data eWay might not like....
    # Data limits come from here: https://eway.io/api-v3/#direct-connection

    if(isset($data['Customer']['FirstName']))
        $data['Customer']['FirstName'] = substr($data['Customer']['FirstName'], 0, 49);

    ...etc

        // Dump the modified data for checking if you need to...

        BusinessLogicPlugin::log("commerce_modifyGatewayRequestData - MODIFIED DATA");
        BusinessLogicPlugin::log("data");

    // Now actually return the modified data...
    return $data
}


How can I record sales data from Stripe Checkout and then restrict access to content based on the item purchased? I have a client that is going to use Stripe Checkout (https://stripe.com/checkout).  We are trying to figure out how we can simply record the sale data into Craft.  We know of other plugins that use Stripe, but we really want to use Stripe Checkout as it is great for mobile.

How can we write data to an entry after the Stripe sale?  We would
need basic things like Customer Name, Item(s) purchased, Order
Total.  The items would all be entries in Craft already.
How can we restrict content viewing based on the items purchased?
Basically if you buy Product X which is an entry page of content,
how can I secure that entry so only people who have a confirmed
purchased can view the template?  Since there will be about 10
products, we really can't use User Groups for this.  We need the
permission to be on the item purchased level.

Any help is greatly appreciated.  If we need a custom plugin for this would anyone be interested in making one?  Should be pretty simple using the Stripe API I would imagine.

My understanding of Stripe Checkout is that it doesn't actually charge the user's card. It simply authorises it, and returns a token which you can then use in a server-side script to capture the payment using the Stripe API.

As such, you'll need a server-side component, in the form of a plugin. Charge might provide a decent starting point for that.

I don't think Charge works with Stripe Checkout as standard, but it's probably worth having a chat with the developer (Joel Bradbury) about the costs of adding this functionality.


Can SEOmatic pull from a Category Field to fill Entry - SEO Keywords or SEO Description? Under SEO Entry Meta...

How do you set SEO Description and SEO Keywords?

I see that they can pull from Text, Rich Text, Tags and Matrix fields, can they pull from a Category field?

Currently, no, SEOmatic cannot pull from a category field. You have two options:

Use the Preparse Field, and have that set to be whatever you want it to be (pull output from a Category, whatever): https://github.com/aelvan/Preparse-Field-Craft
Do it manually via Twig in your templates: https://github.com/nystudio107/seomatic/wiki/10.-Dynamic-Twig-SEO-Meta


Cannot delete user that was subscribed to a subscription A user was subscribed to a subscription with 30day trial.
User decided to unsubscribe "Immediately" within 30day trial. Now In CP I cannot delete this user.

I check user, then delete, and confirm delete, then the success message says "Users deleted" , but the user remains there and is not deleted.

Commerce: 3.0.6

Stripe for Craft Commerce: 2.2.3

CraftCMS: 3.4.5

Issued also occurred on Commerce: 2x version.

Is there something I'm missing or not doing properly before a user can be deleted?

This is a known bug: https://github.com/craftcms/commerce/issues/1048

And some more characters for Stack Overflow's benefit.


How can I reroute this querystring URL? In my routes file I have this:

'micros-test/guest-booking/(?P<bookingId>[a-z0-9-]*)' => 'micros-test/guest-booking',

Which works fine for URLS like this:

  /en/micros-test/guest-booking/some-valid-alphanumeric-id

However I need to add another that I can't get working, this time with a querystring value, such as this:

  /en/micros-test/guest-reset-password?token=some-valid-alphanumeric-id

How can I get that to route to my endpoint and pass on the token parameter?

I've tried this but to no avail:

'micros-test/guest-reset-password/?token=(?P<token>[a-z0-9-]*)' => 'micros-test/guest-reset-password',

What have I got wrong there?

Edit - looks like it's the specific use of token as a parameter that's causing the problem.

The route doesn't need to account for the get parameters, so it only needs to be micros-test/guest-reset-password.

You then fetch the parameter using craft.request.getParam('token').


Latency issues on local development server I do craft development on a local setup (using a virtual .dev host). The one very annoying issue I experienced is a large latency (~10s) I get while using the backend – f.e. saving an fresh entry or creating a new field. The latency vanishes as soon as I disconnect from the internet. Is there any "call home" function build into craft that causes the delay?

In the end I resolved my problem - which was unfortunately not related to craft at all. For unknown reasons there it was just quite evident visible.

Facts:
I'm running MAMP on a local OSX (Yosemite) setup. My craft website is running on a virtual domain pointing to localhost.
PHP 5.4
Mysql 5.x
Craft 2.3.26 Pro version

Issue:
Long latency (~10s) when editing an entry/adding stuff.

Solution:
In the end it was related to OSX issues with resolving a vhost address and resulting in loopbacks. A detailed description of the issue und how to resolve it can be found on stackoverflow.


How to order numbers naturally? my entries have simple numbers as title (1, 2, 3, ... 10, 11 etc.). I'd like to order them naturally and not 1, 10, 11, 2, 3 etc. Is Craft allowing this?

I think the simplest solution is to use a plugin like Twig Better Sort or SuperSort. With those you would query for your entries as normal and then apply the Twig filter to sort the array.

{% set entries = craft.entries.section('mySection') %}
{% set entries = entries|supersort('natsortAs', '{title}') %}


'onBeforePerformAction' alternative for craft 2.4.0? Is there an alternate event for onBeforePerformAction? I want to handle an onDeleteEntry, but apparently that doesn't work on a bulk delete (deleting from the check boxes).

No, there isn't. That's why onBeforePerformAction was introduced in 2.5.

I would highly recommend that you update Craft to the latest version (2.6.2944). In addition to all of the cool features that you are missing out on, there was also a critical security update released in 2.6.2791. Without that update, you may be leaving sensitive data exposed.


Adding images directly to public folder I have over 9000 photos that I need to add to my site however using the upload feature in assets is taking an extremely long time. I have tried to just simply add the images to the correct folder in public but they are not showing up on craft. Is there something additional I must do for them to show up or is using the upload feature the only way for photos to show in assets?

You need to use the Update Asset Indexes tool in Settings in the control panel:

  Whenever there are files within your asset source that were not added directly by Craft (e.g. via FTP), you will need to tell Craft to go and look for them. You can do that from the “Update Asset Indexes” tool within Settings.


Getting Matrix content from within a relationship field Here are my channels and fields I need to get to work together.

Blog Channel (blog)

Matrix Field (bodyMatrix)

Gallery Block (gallery)

Gallery Field (galleryInclude [entries])

Gallery Channel (gallery)

Matrix Field (galleryMatrix)

Slide Block (slide)

Slide Image Field (slideImage [assets])
Slide Text Field (slideText)

In my Blog Channel, I have a Gallery block inside a Body Matrix field. This Gallery block contains just an Entries relationship field that is pulling from my Gallery channel.

Inside the Gallery channel is a Matrix field as well, with a single block for slideImage and slideText.

This being my second day working with Craft, but years of experience with EE, how do I pull in the content from that Gallery entry and it's Gallery Matrix?

I've been able to pull in that Gallery title, but can't at all get the Gallery Matrix to output anything.

{% for gallery in block.galleryInclude %}
  {{ gallery.title }}

    {% Gallery Matrix %}

    {% end Gallery Matrix %}

{% endfor %}

I'm not even sure when I use 'gallery' above, if that's the right variable to use, but it works.

Twig is quite different from the EE parser – much more in line with how PHP is interpreted (Twig actually compiles to PHP before rendering).

First, the use of gallery in your for loop is arbitrary – its just the name you pick for the variable containing the currently iterated item, and its completely up to you. So this would work just as well:

{% for galleryEntry in block.galleryInclude %}
    {{ galleryEntry.title }}
    ...
{% endfor %}

Second, there are a couple of issues with your code. For one, you'll need to use another for loop to access the slides inside the galleryMatrix field. Note that you can use "block" as the variable name here as well (unless you need to access any of the outer block variable's properties), but let's call it "slide" for clarity:

{% for slide in gallery.galleryMatrix %}
    ...
{% endfor %}

Note that if your galleryMatrix field contains multiple block types and you're only interested in the "slide" block type, you can for test the slide.type property inside the loop, or use the type method to filter the galleryMatrix field:

{% for slide in gallery.galleryMatrix.type('slide') %}
    ...
{% endfor %}

Furthermore – this is a common gotcha for new Craft users – even if there's only 1 asset, you'll always need to loop through any Asset field; you can't just put assetField.getUrl(). So, you'll need another loop to pull your slide image(s) inside the galleryMatrix loop:

{% for image in slide.slideImage %}

{% endfor %}

Sidenote; when there's only a single asset you could also do the following, but as you'll need an if statement the amount of code won't be any less:

{% set slideImage = slide.slideImage.first() %}
{% if slideImage %}

{% endif %}

Putting it together, here's what your full code should look like (not tested, but should work based on the info you gave):

{% for gallery in block.galleryInclude %}
    {{ gallery.title }}

        {% for slide in gallery.galleryMatrix %}
            {% for image in slide.slideImage %}

            {% endfor %}
        {% endfor %}

{% endfor %}


Listing all entries which belong to an entry Trying to list all the entries which belong to an entry. Currently I have the following field format:

Product

Has an 'retailer' entries field.

Retailer

Normal entry.

On the retailers _entry.html page I'm trying to display all the products which belong to said retailer. But the code I'm producing is running into trouble:

retailers/_entry.html

    {% set relatedProducts = craft.entries.section('products').relatedTo(entry) %}

    {% for entry in relatedProducts %}

Some great entries

    {% endfor %}

This code seems to be showing the title but not actually looping over the length of the array?

I had a similar problem to yours, and here's what I ran into.

It may be that you're using entry for your main info on the retailer entry page? Because {{ for entry in relatedProducts }} would return one result (the retailer entry). So instead, use a different variable for the loop.

Try something more along the lines of this:

{{ entry.title }}

{{ entry.body }}

{% if craft.entries.section('products').relatedTo(entry)|length %}
  {% set relatedProducts = craft.entries.section('products').relatedTo(entry) %}

Some great entries

  {% for relatedEntry in relatedProducts %}
   {{ relatedEntry.title }}
   {{ relatedEntry.body }}
  {% endfor %}
{% endif %}

Also, note that I wrapped the whole thing in an if-check. It checks to see if there are related products first, and then, if there are, sets the variable and runs the loop.

And your H3 should be outside the loop, otherwise it'll show up on every pass around.


Next block inside of a loop I’m struggling with getting the next block inside of a loop of a Matrix-Field. I’ve tried this:

{% set nextBlock = entry.articleContent.offset(1).limit(1) %}
{% if nextBlock.type == "textBox" %}
 {{ nextBlock.textTitle }}
{% endif %}

This produces an ArgumentCountError. Can someone help me with this issue?

Try doing something like:

{% set nextBlock = block.getNext() %}

https://craftcms.com/docs/templating/matrixblockmodel#getNext


Trying to access 'title' attribute via getEntryTableAttributeHtml. Any idea how? I am trying to get access to the attribute title using this, but does not work. If I switch out 'title' for slug, uri, etc. It works. But not title. Anyway I can do this?

public function getEntryTableAttributeHtml(EntryModel $entry, $attribute)
{
    switch ($attribute) {
        case 'title':
            return $entry->title . ': Something appended to title';
            break;
    }
}

Update

Added in return $entry->title . ': Something appended to title'; to the case to show I want to append something to the title.

I want to be able to just append some text, icon, or html to the titles in the entries list in the CP.

If you wanna change the title one way is override the __toString() method on your model.

/**
 * @return string
 */
public function __toString()
{
    return (string)$this->name;
}

If you wanna chage the status icon next to the title you can override the getElementQueryStatusCondition function on your ElementType class

public function getElementQueryStatusCondition(DbCommand $query, $status)
{}

Regards


Make segment in the middle of a route optional In the following route configuration i want to make the height segment optional.
So that

/images/400/200/placeholder.png
/images/400/placeholder.png

are both possible with one route.

$event->rules['/images/<width:\d+>/<height:\d+>/<imageName:([-\w.]+)>'] = 'module-name/image';

I tried the answer from this question Is it possible to define optional route segments? but couldnt bring it to work.

Your regex is going to become more complex and potentially less specific if you try to address both scenarios in a single route as the height and width parameters match numbers and the final segment of your URL matches any characters that would be found in a URL segment.

It may be easier to handle this as two rules, the more specific one first:

'/images/<width:\d+>/<height:\d+>/<imageName:([-\w.]+)>'
'/images/<width:\d+>/<imageName:([-\w.]+)>'

Making this two rules you get around needing to matching both a number OR other characters in the third segment. If the second and third segment are numbers and the fourth segment is present, your first rule will match. If the third segment is not a number and there is no fourth segment, your second rule will match.

Also, with two rules you can easily test if height exists or not in your controller or template. If you combine that third segment into a compound rule, you may need additional logic in your template to sort out what value you are working with.


Get field type in templates I need to get the field type in my templates like I used to do: field.getField.type but that does not seem to be working in Craft 3 anymore. The result is always null. It also seems that the »type« column is gone completely from the craft_fields table.
How do I get the field type in Craft 3?

There might be other ways, but here's one possibility:
{{ craft.app.fields.getFieldByHandle('yourFieldHandle').className() }}

This will return a string of craft\fields\PlainText, craft\fields\Lightswitch etc, which you can then use in conditionals/switch statements.


Delete items from frontend with ajax I'm trying to delete items through the frontend with ajax. It's working now but want to be sure if this is a safe method:

$(".delete-file").click(function(){
    var data = {
        entryId: $(this).attr("data-id"),
    };

    data[window.csrfTokenName] = window.csrfTokenValue; // Append CSRF Token

    $.ajax({
        context: this,
        type: "post",
        dataType: "json",
        data: data,
        url: "/actions/entries/deleteEntry",
        success: function(data, response){
            $(this).parents('.account-item').remove();
            console.log("success", response, data);
        }
    });
});

That looks perfect!

Obviously this code doesn't prompt the user to confirm deletion, but that can easily be added. (Or perhaps you stripped that out of your example.)

You are specifically doing two things right here:

Hitting deleteEntry directly. This ensures that Craft follows all of its necessary internal procedures to properly delete the entry (and kill any relationships it may have).
Including the CSRF token information. Not sure if it's currently required for hitting a native Craft method, but it certainly will be when Craft 3 rolls out. Good future-proofing!

Looks great Johannes, go for it!


Use own/custom field inside Craft Table I made my own, fairly simple field inside a Module for Craft 3.x.

What settings do i need to define to make it usable inside a table?

I think you just can't: allowed field types seem to be hardcoded in craft\fields\Table::getSettingsHtml().
See https://github.com/craftcms/cms/blob/develop/src/fields/Table.php#L215 for details.
You might create a CustomTable field that inherits the Table class and overrides its getSettingsHtml() methods to allow you custom field type, but that seems overkill. It may be easier to just use a matrix field instead of a table field.


How to use an asset as featured image in different entries I have currently the problem, that I can't use the same asset in different entries as featured image.

Craft Pro Version: 3.0.9

My setup is the following:

Volumes:

Local, Base URL: @web/uploads, Type: Local, File Path: @webroot/uploads

Created Fields:

Featured Image, Type: Asset, Limit: 1, Volume: Local

Created Section:

Articles, Type Channel, Added Featured Image to the post type

Now I have uploaded some dummy images. (e.g. Image 1, Image 2, Image 3)
After this I have created some article entries.

Article 1 - Image 1
Article 2 - Image 2
Article 3 - Image 3

Backend Preview:

Frontend Preview:

When I change the Article 1 - Featured Image from Image 1 to Image 2 it looks good in the backend but not in the frontend.

Backend Preview:

Frontend Preview:

The frontend snippet to show the entries is the following:

{% set latestArticles = craft.entries({section: 'articles', limit: 6}).orderBy('id desc').all() %}

    {% for entry in latestArticles %}

        {% set asset = entry.featuredImage.one() %}

{{ entry.title }}

                        {{ entry.teaser|length > 200 ? entry.teaser|striptags|slice(0, 200) ~ '...' : entry.teaser|striptags }}

                            Read more...

                        9 mins

    {% endfor %}

The question is now the following:

Is it an user handling?! :D
Is it not possible to assign one image to multiple entries?
Is there any workaround? (please don't tell me, to upload the image again ;) )

Thanks!

You can assign an image to as many entries as you like; what's happening is for some reason, Craft appears to be unable to generate the appropriate image transform. It's very likely some kind of local dev environment setup issue.

For whatever reason, it's unable to access the AssetsController to generate the transformed image on the frontend, as seen in that 404 url.


Save multiple records at once I would like to be able to save multiple records at once. What is the best way of doing this? I can of course iterate over my records and use the save function for each one. However, this is not very good for performance. The other option I can think of is to create my own database query using the insertAll command. This would be better for performance.

Is there any built in function to batch save multiple records at once or is the insertAll alternative the way to go?

Thanks for your time.

You could use a task within your plugin for better performance when looping through your records.

Check the TasksService docs and also PowerNap, an example plugin that uses a task.


Will a change to verificationCodeDuration be updated retrospectively? I've amended the time people have to verify an account, using:

'verificationCodeDuration' => 'P7D',

But, I've done this retrospectively, after the verification emails have all gone out (quite a lot of them). Will this new verification time be applied to verification links that have already been sent out? Or will I need to get those emails sent again, as only new verification links will have this applied?

If you check UsersService->isVerificationCodeValidForUser(), you can see that it's taking the current date/time and subtracting the verificationCodeDuration config setting value, then comparing that to the verificationCodeIssuedDate time that is saved for that user in the craft_users table.  If the issued date/time is greater than the result of the subtraction date/time, then it's still valid, otherwise, not.

So because it's checking at runtime against the current date/time, the new verificationCodeDuration value will immediately take affect for any existing verification codes on a user.


Page ignoring template One of my clients' sites is https://anovaworks.com/. The second section on the homepage looks like this:

There's some small black text in the top left of the image that's coming from a matrix field.

It's supposed to look like this, and if you go to https://anovaworks.com/index.php or https://anovaworks.com/?, it looks correct:

I cannot figure out what's causing this. Anyone have any ideas?

Template code:

        {# blue circle svg #}
        {% for matrix in entry.homepageTagline.all() %}

{{ matrix.firstLine}}
{{ matrix.secondLine }}

        {% endfor %}
          <button class="button">{{ entry.homepageTaglineButtonText }}</button>

Your <div class="cell small-12 medium-7 large-5 circle-container"> is well displayed in the source code, but not in the inspector; Try to remove and/or fix what interfere with this piece of HTML (JS?).

Edit: If I disable JavaScript on my browser, everything is fine on your site.


Conditionally show table column headings Is there a way to conditionally display a table column heading if the table field row has been entered? i.e.

if my table has up to 3 columns
and I fill in ALL the fields like this I'd see

ch1 | ch2 | ch3

a   |  b  |  c

but, if I only fill in 2 columns without conditionals I'd see this

ch1 | ch2 | ch3

a   |  b  |

I'd like to conditionally only show the column headings/rows populated like this:

ch1 | ch2 |

a   |  b  |

Is that possible?

This works for me:

{% set showCol1 = false %}
{% set showCol2 = false %}
{% set showCol3 = false %}
{% set showCol4 = false %}
{% set showCol5 = false %}

{% for row in entry.fieldname %}
{% if row.col1|length %}{% set showCol1 = true %}{% endif %}
{% if row.col2|length %}{% set showCol2 = true %}{% endif %}
{% if row.col3|length %}{% set showCol3 = true %}{% endif %}
{% if row.col4|length %}{% set showCol4 = true %}{% endif %}
{% if row.col5|length %}{% set showCol5 = true %}{% endif %}
{% endfor %}

        {% if showCol1 %}Col 1	{% endif %}
        {% if showCol2 %}Col 2	{% endif %}
        {% if showCol3 %}Col 3	{% endif %}
        {% if showCol4 %}Col 4	{% endif %}
        {% if showCol5 %}Col 5	{% endif %}

{% for row in entry.fieldname %}

        {% if showCol1 %}{{ row.col1 }}	{% endif %}
        {% if showCol2 %}{{ row.col2 }}	{% endif %}
        {% if showCol3 %}{{ row.col3 }}	{% endif %}
        {% if showCol4 %}{{ row.col4 }}	{% endif %}
        {% if showCol5 %}{{ row.col5 }}	{% endif %}

{% endfor %}


Is it possible to exclude multiple sections from an entry search query? I'm trying to build a search function that excludes results from certain sections all together. This is the code I was trying to use.

{% set entries = craft.entries.search(query).section('not testimonials, not authors').id('not 2').order('score') %}

When I use just one section, it works fine:

{% set entries = craft.entries.search(query).section('not authors').id('not 2').order('score') %}

Any thoughts on how I could construct this query?

The trick is to add and once before the first not

{% set entries = craft.entries.search(query).section('and, not this, not that') %}


Anyone have a createCommand example? So I am using a plugin to import data and it isn't assigning the values (asset is inside of Matrix) so I am going to modify the plugin and add code to lookup values that I need to assign to MatrixBlockModel and then re-save the item.

I looked up how to create a command and based on that I wrote 3 lines of code but I have no idea on how to iterate through the results. Here is the sample code:

$query=craft()->db->createCommand()
  ->select('id, folderId, filename, kind')
  ->from('{{ assetfiles }}')
  ->where('filename= :fileName', array(':fileName' => 'somefilename'));

How do I iterate through the results and how can I access info from the query?

I'd suggest reading through the Yii QueryBuilder docs, which is what the code you've written is using.

->from('{{ assetfiles }}')

should be:

->from('assetfiles')

And if you want multiple rows returns as a a result, you need to add a:

->queryAll();

to the end of the statement.

From there, you can do a foreach loop to access the results of your query:

foreach ($query as $row)
{
    $id = $result['id'];
}


Using action as a key in a query string I've been tasked with recreating an API within our Craft 2.X installation. For whatever reason, the API specifies the resource it is requesting with the query string parameter action. For example, instead of baseurl.com/api/users, they have it set up as baseurl.com/api?action=users

I thought I'd be okay if I used the ElementAPI plugin, set up an endpoint, and parsed the query string to figure out which set of elements to return as JSON. But it turns out that action is a very special query string parameter to Craft. When it receives a request containing action, Craft goes looking for a controller that will match it. I believe that Craft uses this pattern to handle a lot of basic business logic for the CMS. This seems like a very difficult branch of code to subvert -- this check fires before just about everything else.

Things I've tried, without luck:

Changing the action trigger in the config file, in hopes of removing the magic from "action".
Setting up a route in routes.php that goes directly to a plugin. Didn't work because UrlManager only fires after processActionRequest, which is the source of the error.
Asking the people who maintain the API to change the endpoints they're looking for.

Assuming that I'm required to use "action" as a key in my query string, how can I accomplish that in Craft 2?

Thanks in advance for any advice.

I think you're going to have to go up the chain to where the request starts - i.e. the server config. Rewrite all urls matching api?action=... to somewhere else. If you're using nginx it'd be something like

rewrite /api/$arg_action last;


Would you use a Structure as navigation over multiple sections (channel entries, indexes and singles)? I'm setting up my first Craft project and I have a lot of different content. I have around 6 different Channels (News, Events, Blog, Pages, Products, Staff) and ~10 Singles.

I have this idea of using Structures as my sorting and "Navigation" "content types" only. Meaning I'll for example have one Structure called "Navigation" in which I have the default "Title" field and one "Entries" field (for linking to other entries in channels and singles). This I'll output in my template and fetching each linked entries page.link to build my main site navigation.

This should give my client the ability to control the main navigation structure of the entire site 100% with sorting, linking and naming each navigation item ("Title").

Is this a good approach on using a Structure this way? Or will the extra field "Entries" give me a massive query count when the Structure contains (let's say) 100 entries?

Structure for "sorting-only"

I haven't tried the approach that you are thinking of yet, but your concerns regarding the query count are not that unfounded. You would need to use the relatedTo() parameter with the ElementCriteriaModel you create on your pages (to get the single's content)
on your navigation include (even if you only want to get the entries URL) and relations can have a rather big performance hit. Hopefully this is not true for a simple relation like this; otherwise, you'd still have the cache tag. But I'd suggest you to cache the whole include (this is a perfect example for caching being really useful). Additionally setting the limit to '1' will probably help to keep the query count low if the cache is cleared.

{% cache for 3 years %}

    {% set pages = craft.entries.section('pagesSectionHandle').level(1) %}

    {% for page in pages %}

        {% set params = {
            relatedTo: { sourceElement: page, field: "entriesFieldHandle" },
            limit: '1'
        } %}

        {% set linkedEntry = craft.entries(params).first() %}

        {# Get the title from the structure (why set this twice?) #}
        {{ page.title }}

        {# Get the title from the entry #}
        {{ linkedEntry.title }}

    {% endfor %}

{% endcache %}

Structure containing "all the content"

What I'd suggest you to do is to not only use the structure as a "sorting only" structure, but to also add content directly to it.

Use entry types for your singles, if you need to load individual templates for them, and further entry types for your channel index pages. If it's thought-out carefully (modular site design) you probably won't end up with lots of entry types.

Combining those two

If you have a need to link to specific channel entries from your navigation, you could make an entry type in your structure specifically for those links to channel entries. All other content could still be added directly to the structure itself as described above.

I think that being able to edit the content directly in the pages structure is a very convenient and less geeky like experience for the client.

Edit:

This is what Naboovalley and I came up with in the chat (we should have done this before spamming the comments section). It "will give you a fully dynamic menu for your client linking between Singles, Channels and even other Structure entries":

{% cache globally for 3 years %}
{% set entries = craft.entries.section('navigation') %}

    {% nav entry in entries %}

            {# Check for entry type / get related entry #}
            {% if entry.type == 'linkedChannelEntry' %}
                {% set linkedEntry = entry.entriesField.limit(1).first() %}
            {% endif %}

            {% if linkedEntry %}

                {# Link to a linked channel entry #}
                {{ linkedEntry.title }}

            {% else %}

                {# Link to a structure entry #}
                {{ entry.title }}

            {% endif %}

            {# Repeat this for child entries #}
            {% ifchildren %}

{% children %}

            {% endifchildren %}

    {% endnav %}

{% endcache %}


Bullet-proofing tags with punctuation I have a route set up with a tag:
news/tag/[tag] => news/_tag

How do I generate urls that will match that route for all possible tags (including tags with punctuation)?

How do I resolve that url back to a tag (including tags with punctuation)?

Note that twigs url_encode filter href="{{tag.name|url_encode}}" will generate urls that don't route to the template for some tags.

To generate the url, use the slugify plugin: href="{{tag.name|slugify}}". Slugify uses Craft's slug technology, so the slugs are always recognized by the router.

To resolve the url back to a tag, use search in the news/_tag template:

{% set thisTag = craft.tags.search('name:"'~tag~'"').first() %}

craft.tags.name(tag).first() will often work, but not for all slugs, so this is also possible, and may be more efficient if that is an issue:

{% set thisTag = craft.tags.name(tag).first() %}
{% if not thisTag %} {% set thisTag = craft.tags.search('name:"'~tag~'"').first() %} {% endif %}


8MB memory limit on asset uploads? I'm trying to upload a 40MB video through the assets tab in the admin panel, but I get an error saying "The file "x.mp4" could not be uploaded, because it exceeds the maximum upload size of 8.0 MB."
In my php.ini file it looks like I've got it set to 265MB and i'm not sure where else to check. Here's what my php.ini file looks like:

allow_url_fopen = Off
allow_url_include = Off
display_errors = Off
enable_dl = Off
file_uploads = On
max_execution_time = 30
max_input_time = 60
max_input_vars = 1000
memory_limit = 128M
session.gc_maxlifetime = 1440
session.save_path = "/var/cpanel/php/sessions/ea-php71"
upload_max_filesize = 256M

Craft has a maxUploadFileSize config setting, but it is set to 16MB by default.  Maybe someone has changed it to 8MB for your install, though.  It would be in craft/config/general.php.


Rich Text field is producing weird space character instead of   Example from the frontend

Example in dev tools

If I "view-source" on the page

Example from Rich Text Field

Example from Rich Text Field HTML

This is a Rich Text field within a matrix, it's output in the template like this: {{ block.text }}

If I pass the "|raw" filter I get the same.

If you notice, the Rich Text Field has a   before the closing </p>, which isn't output in the markup, instead I get this strange character.

I had a similar thing with hacksaw recently bringing up this character here:
https://github.com/ehousestudio/craft_hacksaw/issues/16

Any ideas on how to resolve this?

I did contact Craft about this near the time this question was posted, they were not sure why it was occuring.

I found that this issue was environment specific, it was specifically happening locally on MAMP4, with 5.6.* using NGINX.

I was unable to find the cause of the issue, but, in the end it was not happening on server environments so I decided to give up.


Use of tag.slug instead of tag.title in a custom route I've followed this guide for creating a routes to list entries with specific tags. It is working fine except that I have muli-word tags so using the tag token from Settings -> Routes gives me urls like

mysite.com/tags/my%20tag%20name

I'd like to us the tag.slug instead which should allow me to have urls end in .../my-tag-name instead, but I can't figure out how to do it.

Is there a way to refer to tag.slug in craft/config/routes.php?

If so what should the custom route look like:

'tags/what goes here?' => 'tags/_tag.html',

Updated

The template code is:

{% extends "_layout" %}

{% block content %}

{% set tag = craft.tags.title(tag).first() %}

{% if not tag %}
    {% exit 404 %}
{% endif %}

Entries tagged with “{{ tag.title }}”

{% set entries = craft.entries.relatedTo(tag).order('title') %}

{% if entries | length %}

        {% for entry in entries %}
            {{ include('./partials/entryListItem.html', {'entry': entry}) }}
        {% endfor %}
{% else %}

No entries could be found with that tag.

{% endif %}

{% endblock %}

and the include points to:

{{ entry.title }}

             continue reading

        {% if entry.tags | length %}

          {% for tag in entry.tags %}
            {{ tag.title }},
          {% endfor %}

        {% endif %}

The route is set in the dashboard tags/(tag token) points to tags/_tag.html

If I change the route to tags/(slug token) I get template error: variable tag does not exist.

You do not have to change your route. Instead modify your template where you are linking the tag.

Instead of using

{{ tag.title }},

Use

{{ tag.title }},

UPDATED

To clarify the above snippet goes in the template that generates the link to take the the user to your _tag.html template, not in the _tag.html template itself.

Your route should be as below:

UPDATE 2

Above snippet updated to match your example above.

UPDATE 3

As the tag variable made available to your template is now the tag’s slug, make sure to update the code to query for the tag model to use the slug param.

{% set tag = craft.tags.slug(tag).first() %}


Multi Site Multi Domain Probably this one is repeated, but I couldn't find an answer for it yet.
I have a multi-site in Craft CMS 3.15, one that is in English and another one in Japanese.
So the English page, which is the default, is www.mysite.com, and my other site, is working fine if the domain is www.mysite.com/jp
However, I want to change the domain for the Japanese site to be www.myjapanesesite.com/home and is not working as I expected as the browser says that there have been too many redirects.
How can I make this possible on Craft? Is there anything else I should config in Craft or in the htaccess file?
The redirects section from my htaccess looks like this:
<IfModule mod_rewrite.c>
   RewriteEngine On

   RewriteCond %{HTTP:X-Forwarded-Proto} !https
   RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

   RewriteRule ^(autodiscover) - [L]

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

   RewriteCond %{HTTP_HOST} !^www. [NC]
   RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$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>

While the Base URL for my English site is https://www.mysite.com and the Japanese one is https://www.mysite.com/jp (I have tried to change it to www.myjapanesesite.com/home but that's when it doesn't work).
Thanks in advance
Note: I have set the alias for this site www.myjapanesesite.com in SiteHost (the hosting service)

I believe you need to use tweak the config/general.php file in order to have a baseUrl for a site that is a different domain name.
'siteUrl' => [
    'english' => 'https://www.mysite.com/',
    'japanese' => 'https://www. myjapanesesite.com/',
],

See documentation at: https://docs.craftcms.com/api/v3/craft-config-generalconfig.html#siteurl


Stripe: Craft Commerce_OrderModel and its behaviors do not have a method or closure .... I'm trying to accept Stripe payments and am stuck in a loop where I have optimal behavior on the dev and staging versions, but then things broke in production and got the following error message:

Craft\Commerce_OrderModel and its behaviors do not have a method or closure named 'firstName'

Can someone give me some direction around this? Again, it only happens in production, and obviously, we need to be able to receive payment from customers. Thanks!

Are you sure all environments are identical? (Same templates, versions, plugins, configs, etc.)

Best way is to check your craft.log file and turn on devMode so you can get a proper dump as to what's causing your problem.


Plugin service and variable I have a service called useTR.php. It has a public method exampleService().

In the variables folder I have added the following code in my KGVariable.php (KG is my plugin name)

public function sayHello() {
    return craft()->useTR->exampleService();
}

In my templates folder I have an html that gets loaded after a form submission and that html has the following code.

Thank you {{ craft.KG.sayHello() }} will contact you soon

When this HTML is loaded, I get the following error:

  Twig Runtime Error – Twig_Error_Runtime
  Calling unknown method: craft\web\twig\variables\CraftVariable::keyword()

What am I doing wrong? Kindly help (I am a beginner at Craft). Thanks.

There's a lot going on here, but a) assuming you're really using Craft 3 and b) you generated your plugin, service and variable scaffolding on https://pluginfactory.io, this should work:

KGVariable.php Variable

<?php

namespace kg\variables;

class KGVariable
{
    public function sayHello()
    {
        return \kg\KG::$plugin->useTR->exampleService();
    }
}

UseTR.php Service

<?php

namespace kg\services;

use craft\base\Component;

class UseTR extends Component
{
    public function exampleService()
    {
        $result = 'hello';
        return $result;
    }
}

Then using this in a template will return hello:

{{ craft.kG.sayHello() }}


Filter Entries within a page dynamically based on category I'm creating a portfolio page, and I have a summary list of project entries displayed. At the top of the page, I've got a dropdown displaying a Category field. e.g. craft.categories.group('industry')

My question: Is it possible to display/filter entries of a particular category dynamically/immediately when a dropdown entry is selected (using only Twig)? Or do I have to use Javascript?

Sorry for this basic question.

You will need to use some JavaScript, since all twig code is parsed on the server and sent to the browser as HTML.


What is the Control Panel URL? The installation instructions say: "A few seconds later, you should have a working Craft install!
 ... If it was successful, Craft will redirect your browser to the Control Panel." My installation route was Terminal, and all I have at the end is "*** installed Craft successfully (time: 53.862s)". So, please help me to find the URL where I can start learning to use this design facility. Thanks in advance.

The default URL to access Craft is /admin.

Note also this can be changed to anything you like using the cpTrigger config variable.


vhost.conf and general understanding I am new to craft CMS and installed it in an Amazon EC2 instance via Composer.
This worked.
My vhost.conf looks like this
<VirtualHost *:80>
ServerName craft.example.com
DocumentRoot /var/www/vhosts/viacraft/www-craft-test
ServerAdmin tristanvii@example.com
ErrorLog /var/www/vhosts/logs/error_log_viacraft
<Directory /var/www/vhosts/viacraft/www-craft-test>
        AllowOverride All
</Directory>
RewriteEngine On
RewriteCond %{SERVER_NAME} =craft.viainfo.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

Database setup worked and passed.
Then according to the manual I called
https://craft.example.com/index.php?p=admin/install
which leads to an File not found error.
Then I put a hello.php in /var/www/vhosts/viacraft/www-craft-test but https://craft.example.com/hello.php did not worked which I did not understand.
Then I put the hello.php in /var/www/vhosts/viacraft and it worked which is strange because the web directory in the vhost.conf is /var/www/vhosts/viacraft/www-craft-test and not /var/www/vhosts/viacraft/
Any ideas to this behaviour?
Then I managed to start the whole thing by entering
https://craft.example.com/www-craft-test/admin/dashboard
Why do I have to enter my webfolder www-craft-test in the path to call the dashboard???
I made my first entry - a blog and when I press Preview the following page is called
https://craft.example.com/www-craft-test/admin/entries/blog/17-my-first-blog
with the error

Page Not Found
Template not found: blog/_entry

I am not in development mode.
Settings/Site This site has its own base URL is UNCHECKED
This is my .htaccess in the www-craft-test folder
 <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>

In the templates folder there is still the original index.twig file.
A bit confused, happy to get some helpful ideas?
Thanks
Tristan

Your virtual hosting config looks good to me.  However, how are you running SSL?
You've only shown the port 80 / non-SSL config and it shows a redirect to https so the DocumentRoot probably differs between port 80 and 443 versions vhost stanzas.
Make sure DocumentRoot is the same in both places and you should be able to load up Craft without the www-craft-test prefix.


How to output only the first instance of a Matrix block type field I've got a Matrix block in my Latest News/Index template and I can't figure out how to only output the first instance of a block type field.
Here is my code, working great except it outputs the first 250 characters from ALL {{block.newsContent}} content block fields not just the first. I know this is what my code is actually set up to do, but I can't figure out how to only output the first one!

{% for block in entry.newsBlock %}
    {% switch block.type %}

        {% case 'nbTitle' %}

 {{ block.newsTitle }}

{{ entry.postDate | date("d-M-Y") }}

        {% case 'nbContent' %}

{{ block.newsContent | striptags | slice(0, 250) ~ '...' }}

    {% endswitch %}
{% endfor %}

The {{block.newsContent}} part outputs every instance of that field, but I only need the first, as it's the 'excerpt' intro to the complete article.

Here is the front end:
https://www.ancamotion.com/latest-news

Any help appreciated, thanks!

You can either use external bool variable

{% set firstNbContentDisplayed = false %}
{% for block in entry.newsBlock %}
    {% switch block.type %}
        {% case 'nbTitle' %}
            ...
        {% case 'nbContent' %}
            {% if not firstNbContentDisplayed %}
                {% set firstNbContentDisplayed = true %}
                ...
            {% endif %}
    {% endswitch %}
{% endfor %}

or if possible in your case separate nbContent and limit it to 1

{% for block in entry.newsBlock %}
    {% switch block.type %}
        {% case 'nbTitle' %}
            ...
    {% endswitch %}
{% endfor %}

{% for block in entry.newsBlock.type('nbContent').limit(1) %}
    ...
{% endfor %}


Calling plugin controller externally fails with 500 error UPDATE: Question edited to be clearer.

I had an issue where it seems calling a plugin’s controller via an URL caused the site itself to throw a 500 error (i.e. not being accessible at all).

The plugin loads external cinema events (as an XML) and creates entries for films and shows. I’ve made it accessible in the CP, where I hit a button to update, and it will return a log which gets printed out in the CP. Triggering it from the plugins page in the CP works perfectly. Now I wanted to create a cronjob that loads the external data on regular intervals – basically calling the plugin. After some trail and error, I managed to make the plugin’s controller callable from the outside.

So my question is – is there anything special to be aware of when calling plugins from the outside? Is there a difference if it’s called as a cronjob or if it’s done manually through the browser.

Here is the code of the controller:

<?php
namespace Craft;

class UpdateProgram_ProgramController extends BaseController
{
  // Allowing to be called without being logged in
  protected $allowAnonymous = true;

  public function actionUpdate()
  {
  // Disabling having to call the plugin by POST, to access directly by URL
  // this->requirePostRequest();

    $log = craft()->updateProgram_program->update();

    // If there are entries in the log, changes have happened
    if ( count($log) ) {
        craft()->userSession->setNotice(Craft::t('Program updated.'));
        craft()->urlManager->setRouteVariables(array(
           'log' => $log
        ));
    }
    // Otherwise, give an error message
    else {
        craft()->userSession->setNotice(Craft::t('Nothing to update!'));
    }
  }
}

And this is how I'm calling it from the cronjob:

MAILTO=[my.email@address]
# Run updateProgram every night at 3am
0 3 * * * wget http://[my.site]/actions/updateProgram/program/update > /dev/null

When trying it from the browser, I used the same URL

So my question is – is there anything special to be aware of when calling plugins from the outside?

Not particularly.  They're both hitting the same controller endpoint in your plugin, but there are about a million flags/options you can pass into wget to change it's runtime behaviors you might want to play with.

Personally, I stick with using cURL for cronjobs.

Regardless, the behavior you describe sounds like a webserver/Apache crash or segfault.  If they are long-running scripts and you inadvertently triggered them multiple times, maybe you hit some hard resource limits. If that's the case, the underlying error message would be in your web server's error logs for the 500 Internal Server Error.

If it were Craft generated 500 ISEs, then the underlying error message would be in craft/storage/runtime/logs.


Getting orders by property in Commerce 2 from Plugin In Commerce 1 i can select orders by a specific property as follows:

$criteria = craft()->elements->getCriteria('Commerce_Order');
$criteria['orderStatusId'] = 1;
return craft()->elements->getCriteria('Commerce_Order', $criteria);

How can i do this in Commerce 2?

use craft\commerce\elements\Product;

$products = Product::find()->orderStatus(1)->all();


How to keep the setPasswordPath config when reset password link is expired? In config.php file, setPasswordPath is set to match a custom template. This is working fine by following the reset password link sent by email (for a front end user).

But after I've changed the password (with users/setPassword action), if I click again on the reset password link in the email, I am redirected to a page within the default Craft template that inform me that the verification code is now wrong.

How can I also set a custom template for this page?

Pretty sure the invalidUserTokenPath config setting is what you're looking for.


Craft renders unwanted quotation marks on some tags Breaking my head over this.

On one of the tags in the HTML template. The {% for image in category.CategorieImage %} loop. Craft seems to generate 2 unwanted quotation marks ("). These characters are messing up the lay-out as the generate an unwanted line/paragraph.

                {% for image in category.CategorieImage %}

                {% endfor %}

                    {{ category.title }}
                    {{ category.categorieDescription[:80] ~ '...' }}

                    {{ entriesNbr }}Mythes

This is what's rendered on the final page in Safari using the developers panel:

                "  "

                    Sales
                    Over succes in sales zijn vele mythes. Velen zijn inmiddels zo geworteld dat ze ...

                    5Mythes

I've used CODA to show any unwanted (invisible) characters but none seems to be there.

I believe the quotation marks are misleading... What you're seeing in the Safari developers panel is simply a blank space, and Safari is putting quotes around it because it's being interpreted as a "string" by the browser.

Equally, your visual layout is probably just getting screwed up because of empty space between your HTML tags. If you tightened up your HTML tags and removed any spacing in between, the layout might look as you expect it to.

You can easily trim whitespace around Twig tags by using spaceless, or adding dashes.

{% spaceless %}

{% endspaceless %}

Remove whitespace before:

{%- for entry in entries %}

Remove whitespace after:

{% for entry in entries -%}

Remove whitespace before & after:

{%- for entry in entries -%}


Translating Craft form error message labels I am trying to change the label for Craft's form errors. My site local is currently fr_CA, and when I try to submit a form with an error, the error message returned is in french, but the label of the field is in english.

I have managed to translate field labels for plugins, such as the Contact Form plugin by P&T, without any issues by using static translations. All I simply did was create a file with the plugin translation category as a name such as 'contact-form.php' and it works flawlessly.

However, with the forms included in Craft, it doesn't seem to work. For example, with the user registration form, if I submit it without a password, it will come up with an error saying the password needs to have at least 6 characters. Here is the message I receive :

  New Password doit comporter au moins 6 caractères.

The 'New Password' is in english while the rest of the message is in french.

If I try to create a file called 'site.php' or 'app.php' in the translations folder under the right locale, it doesn't translate the 'New Password'. Here is the content of the file :

<?php

return [
    'New Password' => 'Nouveau mot de passe'
];

It's like none of the translations supplied to Craft are being recognized. Has anyone run into this problem or have a solution?

You can't translate that field. I've tried it too once but it can't be done right now without effort because craft\elements\Userhas no attributeLabels() function in it in order to translate the attribute so all Yii2 does is to change newPassword to New Password but it doesn't translate anything.

You can either submit a feature request for it or do some hacky stuff.

I submitted a feature request in their git

Edit 13.08.2018 This commit changed it, you'll be able to translate those messages now


Remove item from cart Ok, I'm getting pretty crazy here. I'm trying to remove a variant from the cart. Adding works fine, like this:
<input type="hidden" name="purchasableId" value="{{ variant.id }}" id="{{ variant.sku }}">
<input type="submit">

(variant is an item from product.variants)
However, when I want to remove an item, I do it like this:
<input type="hidden" name="lineItems[{{ variant.id }}][qty]" value="0">
<input type="submit">

But nothing gets removed. The weird thing is, when I query for lineItems, there's an item with the id "92". The id from the variant is 19874. So that's the id I use in the hidden qty field. I have absolutely no idea where this 92 comes from. It is not the variant id. It's alo snot the product id. I don't know what it is. What am I doing wrong here?

You can remove a line item by including a remove parameter in the request. This example adds a checkbox the customer can use to remove the line item from the cart:
{% set cart = craft.commerce.carts.cart %}
<form method="post">
    {{ csrfInput() }}
    {{ actionInput('commerce/cart/update-cart') }}
    {% for item in cart.lineItems %}
        <input type="number" name="lineItems[{{ item.id }}][qty]" min="1" value="{{ item.qty }}">
        <input type="text" name="lineItems[{{ item.id }}][note]" placeholder="My Note" value="{{ item.note }}">
        <input type="checkbox" name="lineItems[{{ item.id }}][remove]" value="1"> Remove item<br>
    {% endfor %}
    <button type="submit">Update Line Item</button>
</form>

You can check more on this on craft commerce documentation by using below link.
https://craftcms.com/docs/commerce/3.x/orders-carts.html#carts


Slow Category Loading I have the following category https://www.ticketstoday.co.uk/theatre which has around 600/700 Entries, this is paginated at 30x Entries a page. Unfortunately, it's loading rather slowly. It's not a huge entry count so I'm unsure what's happening.

  {% set entries = craft.entries ({
          section: 'events',
          limit: '30',
          order: 'postDate desc',
          with: ['eventMediaTile'],
          relatedTo: category
      }) %}

  {% paginate entries as pageInfo, pageEntries %}
  {% do seomatic.helper.paginate(pageInfo) %}

  {% for entry in pageEntries %}
    {% include '_card' %}
  {% endfor %}

Is there anything at all I can do to speed up the query, or, is it a limitation of Craft?

  Added Card Template below

{% if entry.eventPercentageSaving > 0 %}

{{ entry.eventPercentageSaving }}% Off

{% endif %}
{% for asset in entry.eventMediaTile %}

{% endfor %}

{{ entry.title }}

{{ entry.eventVenueName.one().title ?? 'N/A' }}, {{ entry.eventCity.one().title ?? 'N/A' }}

From £{{ entry.eventMinimumPrice }}

You could eager load a little more to speed things up. Especially your eventVenueName and eventCity

For your query, try:

{% set entries = craft.entries ({
        section: 'events',
        limit: '30',
        order: 'postDate desc',
        with: [
            'eventMediaTile',
            'eventVenueName',
            'eventCity'
        ],
        relatedTo: category }) %}

Then in your _card do:

    {% if entry.eventPercentageSaving > 0 %}

{{ entry.eventPercentageSaving }}% Off

    {% endif %}

    {% set cardImage = entry.eventMediaTile[0] ?? null %}
    {% if cardImage %}

    {% endif %}

{{ entry.title }}

{{ entry.eventVenueName[0].title ?? 'N/A' }}, {{ entry.eventCity[0].title ?? 'N/A' }}

From £{{ entry.eventMinimumPrice }}

If you turn the debug toolbar on your front-end (under your user's preferences) before implementing, and look at the query count, you should see a significant drop.

If this isn't enough, you could start caching. Andrew has a great article on this.


Sub domain install options How can I setup sub domains on a single domain to allow development of multiple Craft client sites. I tried dev1.domain.com and dev2.domain.com and it tells me I need to upgrade license since I need the pro features. Sites are still on development. What is best naming convention?

Have staging or dev in the name, as in blah.dev.domain.com or blah.staging.domain.com  It needs to be a full sub-domain, not a partial like you had in your example.


Entry Form doesn't save the entry and goes to 404 page I have a frontend Entry Form that will not save an entry and goes to a 404 page.

Basically i have this:

<form method="post" accept-charset="UTF-8" enctype="multipart/form-data" class="add-a-resource__form">
{{ getCsrfInput() }}
<input type="hidden" name="action" value="entries/saveEntry">
<input type="hidden" name="redirect" value="/resources/thank-you">
<input type="hidden" name="sectionId" value="4">
<input type="hidden" name="enabled" value="1">
<input type="hidden" name="typeId" value="4">
<input type="hidden" name="fields[topContent]" value="test">
</form>

And in the log in the session array i have:

'9df612913c35fa7bdbde58405537f412__timeout' => 1479139200,
  '9df612913c35fa7bdbde58405537f412Yii.CWebUser.flash.error' => 'Couldn’t save entry.',
  '9df612913c35fa7bdbde58405537f412Yii.CWebUser.flashcounters' =>
  array (
    'error' => 0,
  ),

I am logged in as an admin so have permission to write to the channel, the details are right in the hidden fields, but when i submit the form, it goes to a 404 page no matter what i put in the redirect input.

Any ideas?

Right, the issues was that there was a validation error on a field, but the form didn't reload and display those errors, it just went to a 404 page.


Bootstrap 4 Accordion with Matrix (and SuperTable) I'm attempting to use a combination of SuperTable and Craft's Matrix to create a reusable Bootstrap 4 Accordion element, but I'm hitting a wall.

My code so far:

{% for row in entry.contentBuilder.all() %}
    {% for block in row.components.all() %}
        {% switch block.type.handle %}
            {% case 'accordion' %}

                                            <button class="btn btn-link" data-toggle="collapse" data-target="#collapse{{ loop.index }}" aria-expanded="true" aria-controls="collapse{{ loop.index }}">
                                                {{ block.accordionTitle }}
                                            </button>

                                            {{ block.accordionCopy }}

        {% endswitch %}
    {% endfor %}
{% endfor %}

The above is obviously producing several container divs, and not the desired card divs. I've hit a snag attempting to go several layers deep with for loop nesting and if conditionals to get it right, but it's messy and nothings come worked so far.

Essentially, the idea is that my SuperTable field contentBuilder is added to the Entry layout, so that a user can create several rows and have content types to pick from. In contentBuilder is a row (field) called components, of which accordion is a Matrix field. None of this would even be necessary if Neo was ported to Craft 3 :/ I'd worked out a perfect content builder with Neo before.

Anyone have any ideas how to go about this?

I'd break up the forloops a bit so you're outputting the panel container and the accordion wrapper markup once. Then for each accordion (supertable row) you're outputting that markup as many times as it's needed.

I haven't used Bootstrap JS packages for a long time, so I was a bit thrown by the amount of divs you have. (I use this accordion package for how simple it is. It's an oldie, but a goodie and is still being maintained.)

{# Matrix loop of blocks #}
{% for row in entry.contentBuilder.all() %}

    {% switch block.type.handle %}
    {% case 'accordion' %}

                         {# Supertable loop of accordions #}
                         {% for block in row.components.all() %}

                                         <button class="btn btn-link" data-toggle="collapse" data-target="#collapse{{ loop.index }}" aria-expanded="true" aria-controls="collapse{{ loop.index }}">
                                              {{ block.accordionTitle }}
                                          </button>

                                         {{ block.accordionCopy }}

                        {% endfor %}

    {% endswitch %}
{% endfor %}


Is there a query parameter to get categories that are related to anything else? I'm looking for a way to query all categories that have at least one relation.  I'm not looking for the relatedTo() parameter, which would give me categories related to something specific.

Basically, if we talk in Wordpress terms, I'm looking for hideEmpty = true.

Is there anything like that in Craft?

Something like: craft.categories.group('products').hasRelated()

Add this to your chain...

.yourCategoryField(':notempty:')

It's not very well documented, but you can see it described in this old SE thread. In the docs, it's mentioned very briefly here.