Craft 3: Searching within back-end & front-end isn't giving all entries/results Searching within Control Panel as well as the front-end is not going through all entries. When I try searching in the Content tab I see the pages are listed but when I try to search for the entry it won't give it as a result.

It seems to be only on entries that were created a long time ago.

It seems also that a re-save fixes the problem, but doing that for 10K+ entries is a pain. Hope you can help me to do something like Rebuild Search Indexes that was possible before 3.2.2.

Thank you!

You can use the craft resave/entries console command and it will (among other things) update the search index table with the latest information for your entries.


Moving Craft assets from one S3 bucket to another I have the task of moving a large amount of assets ~50gb from one amazon s3 bucket to another on another AWS account. I've figured out how to copy the files via S3 COPY, but I'm just wondering will it simply be a case of changing the API credentials in Craft to the new bucket? Will this retain all the assets links?

Yes that’s all you need to do. It also works the same if moving to/from a local directory or Google Cloud Storage, or even a subdirectory of any volume type. The index of file paths is relative to the root of the volume for the source, so if the volume changes it doesn’t matter.


product types with and without variants I have two product types. One has variants. One has not.

So I try to write an image tag that works for both.

{% set imageThumb = item.defaultVariant.variantThumb.one()  %}

For the product with one variant this returns:

  Impossible to invoke a method ("one") on a null variable.

This works only for the product type with multiple variants. defaultVariant doesn't seem to be present on products with just one variant.

Trying to fit both cases with one and with multiple variants:

{% for item in craft.products.all() %}
   {% if item.defaultVariant | length %}
     {% set imageThumb = item.defaultVariant.variantThumb.one()  %}
   {% else %}
      {% set imageThumb = item.variantThumb.one()  %}
   {% endif %}
      <img src="{{ imageThumb.url }}"
 {% endfor %}

This code is not working. How do I have to write this?

The problem is that item.defaultVariant will always be true even for products without visible variants (see docs on that), so you can't test for it.

You don't really need to test for it though - just look first for images held against the product, and fallback to images held against the default variant like this:

{% for item in craft.products.all() %}
    {% set imageThumb = item.variantThumb|length ? item.variantThumb.one() :
        item.defaultVariant.variantThumb|length ? item.defaultVariant.variantThumb.one()
    %}
    <img src="{{ imageThumb.url }}">
{% endfor %}


If other languages are not defined show english Is it possible to get the english content on the, for example, Spanish site if the Text for the specific language is not defined yet?

I do not mean a redirect! The English version should be displayed until the Spanish content has been inserted.

It would be great if someone has a Idea! Thanks!

You could choose which value to translate your content into using the |t($lang) filter based on some condition. You condition could be a lightswitch field on each entry saying whether it's been translated or not, or check if a content field is empty or not.

So something like

set lang = entry.lang

if entry.isTranslated == false {
   set lang = 'english'
}

{{ content|t(lang) }}


Translating validator errors Is there a way to add the validator strings into the translations?

$message=$this->message!==null?$this->message:Yii::t('yii','{attribute} cannot be blank.');

/* craft/app/validators/CRequiredValidator.php - line 70 */

I'd like to translate that text without changing any of the code (which might be overwritten and lost with an update)

Yii already provides translations for those in multiple languages.  Check in the craft/app/framework/messages folder to see a list of locales it supports.

If you want it in a locale they haven't translated, yet, then you can provide your own static translation and Craft will use it.


Add a user to a userfield when there's a pending user on there I have this code to save a new user onto a userfield on another user:

    $employees   = $currentUser->employees->ids();
    $employees[] = $employee->id;
    $currentUser->getContent()->setAttributes(['employees' => $employees]);
    if (!craft()->users->saveUser($currentUser))
    {
        Craft::dd($currentUser->getErrors());
    }

Which works fine, however if there's a pending user in the employees field it's not returned in the ids() array. How do I get all user ids from the employees field, not just active users?

Edit: got it:

    $employees   = $currentUser->employees->status('*')->ids();

To mark this as answered, my solution was to use this code to get the current employee IDs regardless of status.

$employees   = $currentUser->employees->status('*')->ids();


Creating JS slideshow with Twig "for" loop I have an entry with a matrix field called quantification containing plain text and asset field.

Im looping through the matrix field and for each asset quantification I have a new gallery. Each div id needs to be unique, for example
,
, etc. Within the for loop I think I can use
 for that, right?

But here comes the tricky part, at least for me. I also have some JS code (look here: http://help.dimsemenov.com/kb/royalslider-jquery-plugin-faq/how-to-add-multiple-sliders-to-one-page-and-style-them-differently) which initiates each gallery. How do I dynamically add slider1, slider2, etc since this part of the code lives outside of the for loop?

Any suggestions with respect to the stylesheet, as I need to add them too there. At this point I'm going for hardcoded.

You didn't mention you want to style your sliders differently. I don't think you have to address them separately form your JS and CSS, if they should all look just the same.

HTML:

{% for slider in entry.myMatrixField.type('slider') %}
    <div class="royalSlider">
    </div>
{% endfor %}

JS:

$('.royalSlider').royalSlider({
  controlNavigation: 'bullets'
});

CSS:

.royalSlider {
  width: 300px;
  height: 200px;
  background: red;
}


How to query entries by field values I have some entries with a multi-select field called "gallery". We can choose many images to this field.

I have a given image, how can I query entries whose "gallery" contains this given image? Thx!

I have tried like this with no success:

Entry::find()
  ->section($section)
  ->galleryImages('contains' . $image->id)
  ->all();

There is a related to parameter you can use

Entry::find()
  ->section($section)
  ->relatedTo(['targetElement' => $image->id, 'field' => 'galleryImages')
  ->all();


Bootstrap 3 Navbar dropdown problem I have included the navigation using Bootstrap 3 navbar. It is put together using Craft entries. I need the 'What we do' dropdown to be triggered when pressing the text or caret arrow but at the minute they are displaying as two different menu li as shown.

{% set entries = craft.entries.section('navigation') %}

            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#collapse-ptm" aria-expanded="false">
                Toggle navigation

            </button>

            {% nav entry in entries %}

                    {{ entry.title }} {% ifchildren %}

                            {% children %}

                        {% endifchildren %}

            {% endnav %}

If i'm understanding this correctly, it looks like you just have your loop starting a little early in the markup, so at the moment you are creating a new
 item for every entry.

Does moving the {% nav entry in entries %} loop within the first
 help at all? like this:

 {% nav entry in entries %}

        {{ entry.title }}
        {% ifchildren %}

               {% children %}

        {% endifchildren %}

 {% endnav %}

Additionally

Whilst writing this answer out I noticed that your {% endifchildren %} tag comes before a closing
 tag, so it might just be that:

     {{ entry.title }}
     {% ifchildren %}

              {% children %}

          {# endifchildren was originally here #}

     {% endifchildren %}


Unable to Update Entry - Table doesn't exist I am trying to update an entry in a structure but getting the error:

CDbCommand failed to execute the SQL statement: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'nisp.craft_matrixcontent_colcontent' doesn't exist. The SQL statement executed was: SELECT `elements`.`id`, `elements`.`type`, `elements`.`enabled`, `elements`.`archived`, `elements`.`dateCreated`, `elements`.`dateUpdated`, `elements_i18n`.`slug`, `elements_i18n`.`uri`, `elements_i18n`.`enabled` AS `localeEnabled`, `content`.`id` AS `contentId`, `matrixblocks`.`fieldId`, `matrixblocks`.`ownerId`, `matrixblocks`.`ownerLocale`, `matrixblocks`.`typeId`, `matrixblocks`.`sortOrder`
 FROM `craft_elements` `elements`
 JOIN `craft_elements_i18n` `elements_i18n` ON elements_i18n.elementId = elements.id
 JOIN `craft_matrixcontent_colcontent` `content` ON content.elementId = elements.id
 JOIN `craft_matrixblocks` `matrixblocks` ON matrixblocks.id = elements.id
 WHERE ((((((elements_i18n.locale = :locale) AND (content.locale = :locale)) AND (elements.archived = 0)) AND (elements.enabled = 1)) AND (elements_i18n.enabled = 1)) AND (matrixblocks.fieldId=:matrixblocksfieldId1)) AND (matrixblocks.ownerId=:matrixblocksownerId1)
 GROUP BY `elements`.`id`
 ORDER BY `matrixblocks`.`sortOrder` LIMIT 100. Bound with :locale='en_gb', :matrixblocksfieldId1='285', :matrixblocksownerId1='1656'

The table it mentions is a matrix related table which does not exist - it was deleted a while back.
It was used in a Matrix - Super Table - Matrix test but I was getting errors with it and decided not to use this then so deleted it.
I only started to get this error when I added a new Matrix Field to this entryType. But I have emvoed the Matrix field and now I am still getting the error and can't update.
Any idea's as to the resolution?

Does your database have InnoDB enabled and are all of Craft's tables using it (except for searchindex, which is MyISAM)? Sounds like maybe when you deleted the field some cascading deletes that are set on foreign keys didn't occur and that can happen if you're on MyISAM (which doesn't have foreign key support).


Craft Commerce carts containing out-of-stock products Customer 1 adds a product to their cart. Does not complete their order.
Customer 2 purchases the remaining stock of that product, completing their order.
Customer 1 returns to the store the next day, picking up where they left off.

What should happen in Craft Commerce? Will Customer 1 be allowed to purchase the now out-of-stock product?

The next time the cart 're-calculates' - so really any process on the cart such as updating it etc, the out of stock product will be detected and removed from the cart.

If somehow they get straight to the attempt order completion stage, then I am pretty sure an error is raised (& returned in flash) and the order won't complete.


convert_encoding is screwing up Spanish-language characters Standard "when article has no summary, output the first 200 characters of the body minus HTML" logic going on here. We're implementing some Spanish-language features for the first time and, while special characters are stored fine in the database (utf_unicode_ci collation) and they output fine on the front end when convert_encoding isn't applied, they come out garbled when convert_encoding is applied.

My code is:

{{ item.articleBodySpanish.type('bodyText')[0].bodyText|striptags|convert_encoding('UTF-8', 'HTML-ENTITIES')|slice(0, 200)|default('Lee mas') }}...

I have an entry where the database contains this for articleBodySpanish:

Empuja sus puños contra los postes y sigue insistiendo en que ve a los fantasmas.&nbsp;Empuja sus puños contra los postes y sigue insistiendo en que ve a los fantasmas.

With the code above, the output I get is as follows:

Empuja sus puÃ±os contra los postes y sigue insistiendo en que ve a los fantasmas. Empuja sus puÃ±os contra los postes y sigue insistiendo en que ve a los fantasmas.

If I remove the |convert_encoding('UTF-8', 'HTML-ENTITIES') the output becomes this, so I can't even just take it out to moot the issue:

Empuja sus puños contra los postes y sigue insistiendo en que ve a los fantasmas.&nbsp;Empuja sus puños contra los postes y sigue insistiendo en que ve a los fantasmas.

What can I do here?

You shouldn't need any convert_encoding here. From your results, the special characters are coming out fine, it's your &nbsp that is your problem.

For this to go you can use the |raw Twig filter.


Search ranking challenge The search ranking built into Craft orders site content searches by score...but that compromises the "exact match" searches that users might make for significant page titles that don't get searched for as often, but contain key words that are often searched. Is there a way around this? to allow the user to set the search by "exact match"? or to set the site to pick one or the other as its standard?

thanks,
Karin

I'm not sure I'm following the question 100%, but if you want to search for an "exact match" you can use put your search term in quotes.  i.e. "search for this exact phrase".  And if you want to find an exact match in a particular field, you can use fieldHandle:"exact match".

You can see the full search syntax list here: https://craftcms.com/docs/searching


Is it possible to compose a DateTime object from a string? I experienced that there is a difference between real DateTime objects (as now is one) and strings composed to "fake DateTime objects" (ie. {% set myDate = '2014/06/24' %}).

Sometimes it makes no difference and you can use one or the other. The date() filter for example works fine with both. But this isn't always the case, the localeTime() method is an example that exclusively takes real DateTime objects.

Applying a date or date_modify filter to the myDate (string) variable is apparently not sufficient to convert it. The only solution I found is to modify now or fetch a DateTime object from an entry field, but I am looking for a way to generate one solely with twig in the template.

.

Edit:

Thanks for your answers so far, but I still don't get this to work. For me it always results in the following template error when I use a DateTime method on a manually composed DateTime object:

  Method "localeTime" for object "DateTime" does not exist

Here my example code for easy reproducibility. I more and more believe this is rather a problem with those DateTime methods and not with the way I compose the object.

{# Set var to string in supported format #}
{% set myDatetimeString = '2014-06-24 23:40' %}

{# Use date() function to convert string to DateTime object #}
{% set myDatetimeObject = date(myDatetimeString) %}

{# Alternatively use date_modify filter to convert string to DateTime object #}
{% set myDatetimeObject = myDatetimeString|date_modify('+0 day') %}

{# DateTime method doesnt work with these "objects" !! #}
{{ myDatetimeObject.localeTime() }}

{# But DateTime methods work with the `now` DateTime object #}
{{ now.localeTime() }}
{{ now.day() }}
{{ now.iso8601() }}

In Twig, the date_modify filter returns a DateTime object. Also, date is not just a filter, but also a function. The date function accepts any a DateTime object or a string in a supported format, and returns a DateTime object. Example:

{{ date("+2 years") }}

This should give you a DateTime object set for 2 years from when it's triggered.

Why is localeTime missing?

The now variable is not a regular DateTime object from PHP. It's actually an extended class ( \Craft\DateTime ). So it won't have all the convenience functions you get from now or a date field from an entry. Instead you would need to do it manually (I'm not sure if you can overwrite a function or filter in Twig). Fortunately, the locale's format string is available as a variable.

{% set myDatetimeString = '2014-06-24 23:40' %}
{% set format = craft.i18n.getTimepickerJsFormat() %}
{{ myDatetimeString|date(format) }}

You can even shorten it like this:

{% set myDatetimeString = '2014-06-24 23:40' %}
{{ myDatetimeString|date(craft.i18n.getTimepickerJsFormat()) }}

To replicate localeDate, use this:

{% set myDatetimeString = '2014-06-24 23:40' %}
{{ myDatetimeString|date(craft.i18n.getDatepickerJsFormat()) }}


EmailModel - Unexpected character "$"? This is probably a newby question, but, I am just trying to add a basic email send test and my twig page does not like the dollar signs.  Is EmailModel built-in to craft or is there a plugin I need?

I am just trying to add this code to a basically empty twig page:

$email = new EmailModel();
$email->subject = "Thanks!";
$email->htmlBody = "
Congratulations!
htmlBody .= "
Hello World
";
$email->fromEmail = "email@domain.com";

thanks for the help...

Chip

You can't use PHP in a Twig template.

A plugin Craft plugin would be the easiest way to pull off what you're looking for.  I've added an answer to your other related question.


Using an Entry's Added Form in a template in Sprout Forms Using Sprout Forms and have added the Form Name > Select a Form to the Entry's field layout.

After I select a form on this Entry, what do I hook into to get this to display on my template?

I know from the documentation that you can specifically pass in the form's Handle {{ craft.sproutForms.displayForm('myForm') }}, but what do I need to do to get the drop-down form to display if there is one selected?

To dynamically display a Form that you've related to an Entry using a Sprout Forms Form relations field you can pass the handle of the form to the displayForm() tag in your template:

_entry.html

{% set formHandle = entry.formFieldHandle.first().handle %}

{{ craft.sproutForms.displayForm( formHandle ) }}

There is a doc page that describes this here: Relations Field on Entry Page and depending on where you want to redirect the user after they submit the form, Sprout Forms also supports relative redirects.


Commerce: Remove tax adjuster from line item in plugin I need to remove adjusters from each line item if a certain condition is not met. I see that in the CP you can manually remove them by editing the line item but hunting down this code in Commerce's codebase has proven difficult.

Here's some of my code. I'm intending to keep certain adjusters from appearing for all line items before they save. How can I do this?

use yii\base\Event;
use craft\commerce\services\LineItems;
use craft\commerce\events\LineItemEvent;
use craft\commerce\models\OrderAdjustment;
use craft\commerce\models\LineItem;

Event::on(
    LineItems::class,
    LineItems::EVENT_BEFORE_SAVE_LINE_ITEM,
    function(LineItemEvent $event) {

        $lineItem = $event->lineItem;
        foreach ($lineItem->getAdjustments() as $adjustment) {
            /* @var OrderAdjustment $adjustment */

            if ($someExampleCondition) {
                // remove adjustment
            }

        }

    });

But when I inspect an OrderAdjustment model or LineItem model, I don't see any methods about removing or setting adjusters, only getting them.

There is a way to do this, obviously, it is worth noting that the code below is written to be easy to understand and could be improved. Also, it is worth noting that there are plenty of things to think about when implementing something like this.

Take careful consideration about how this will affect all parts of the e-commerce experience, whether that is carts, orders, adding to cart in the front end and cart management in the control panel.

The following code will remove a tax adjustment based on the SKU of the line item and the name of the tax adjustment, your criteria may obviously vary.

use craft\commerce\elements\Order;
use craft\commerce\Plugin;
use craft\events\ModelEvent;
// ...

Event::on(Order::class,
    Order::EVENT_AFTER_SAVE,
    function(ModelEvent $event) {
        $lineItems = $event->sender->getLineItems();
        $adjustments = $event->sender->getAdjustments();

        // No need to do anything if this is an order or there aren't any line items or adjustments
        if (empty($lineItems) || empty($adjustments) || $event->sender->isCompleted) {
            return;
        }

        // Figure out which line items we want to remove tax from
        $removeTaxFromLineItemIds = [];
        foreach ($lineItems as $lineItem) {
            if ($lineItem->getSku() == 'MY-EXAMPLE-SKU') {
                $removeTaxFromLineItemIds[] = $lineItem->id;
            }
        }

        if (empty($removeTaxFromLineItemIds) ) {
            return;
        }

        // Loop through adjustments and remove the tax adjustments for the line items we determined above
        $taxNameToRemove = 'My Tax';
        foreach ($adjustments as $key => $adjustment) {
            if (in_array($adjustment->lineItemId, $removeTaxFromLineItemIds) && $adjustment->type === Tax::ADJUSTMENT_TYPE && $adjustment->name == $taxNameToRemove) {
                unset($adjustments[$key]);
                Plugin::getInstance()->getOrderAdjustments()->deleteOrderAdjustmentByAdjustmentId($adjustment->id);
            }
        }

        $event->sender->setAdjustments($adjustments);
    }
);

This code can be used inside a custom plugin or module.

Hope this helps.


Accessing structure descendants data I have a structure with 1 main Entry and 3 descendants underneath it but I have trouble accessing the data in matrix fields in the entries. I'm trying to do this all on one page:

{% set tabs = entry.descendants %}
     {% for tab in tabs %}
          {{ tab.title }}
     {% endfor %}
{% endfor %}

I can get as far as the tab title, and it displays fine. But I want to access the matrix fields in the descendants. Here are the blocks in my field with the handle 'tab'.

So to summarise, I have a structure:

and then I want to use all those descendant data all one one page but I'm having trouble accessing it.

You would loop through the Matrix field within each tab the same way you’d do it for any other element.

{% set tabs = entry.descendants %}
{% for tab in tabs %}
    {{ tab.title }}
    {% for block in tab.myMatrixFieldHandle %}
        {% if block.type == 'about' %}
            ...
        {% elseif block.type == 'team' %}
            ...
        {% elseif block.type == 'clients' %}
            ...
        {% endif %}
    {% endfor %}
{% endfor %}


Multilang Bug with Matrix, Neo, SuperTable (with Video) We have a big problem with CraftCMS and Multilang.

We have the default language German (DE) in Craft.
We have news entries with matrix fields
We create a new language English (EN) as second language
We activate this language (EN) in the News section
We open an existing news entry and click on the second language (EN)
The content of the matrix field does not exist
We go WITHOUT saving back to the source language (DE) and save the post
We switch back to the second language (EN) and now the Matrix Content is here

For us it seems that the Autosave function, which is triggered when you add a new language to a section, does not process the matrix fields (Neo + SuperTable same problem) properly.

The Problem is on all our client sites which use multilang.

Here is a Video
https://www.dropbox.com/s/7jzg6ts3l90xze1/craftbug.mov?dl=0

You're essentially running into this bug: https://github.com/craftcms/cms/issues/16

It has been fixed for the upcoming Craft 3, but the fix was involved likely won't be backported to Craft 2.


Cache closing tag error I'm trying to using craft caching to cache a page without query string vars.

This tag

{% cache using key craft.request.path  %}

{% endcache %}

throws an error

Unexpected token "name" of value "using" ("end of statement block" expected)

This example is right from the Craft Docs, https://craftcms.com/docs/templating/cache

If I remove the "using ..." everything works fine.

Any ideas?

Make sure you're running the latest version of Craft.  using key didn't come until Craft 2.2.


With a categories field, how do I query only the *selected* categories? Suppose we have a category group that allows for any number of levels to its structure. We also have a category field that allows for choosing any number of categories from that group.

In our example, we want to select three categories: one is a level 1 category in that group, another is a direct child of a different level 1 category and the third is a level 4 category from another branch in the category group (all three are in different branches for this example).

The question is: How do we query the category field to only return the categories we selected—the categories we actually clicked on when selecting categories? (Craft 3)

Here's how to isolate only your chosen categories. This works off the premise that if a related category is a parent of one of the other related categories, it is not a category you chose.
{% set relatedCategories = entry.myCategoryField.with(['parent']).all() %}
{% set parentCategories = relatedCategories | map(c => c.parent) %}
{% set chosenCategories = relatedCategories | diff(parentCategories) %}


How do I hook into Capture form onPost event? I am writing a new plugin to hook into a POST event from a bespoke form plugin called "Capture". The Capture plugin fires two different events; the code taken from /craft/plugins/capture/services/Capture_SubmissionsService.php

public function onBeforePost(Event $event) {
    $this->raiseEvent('onBeforePost', $event);
}

public function onPost(Event $event) {
    $this->raiseEvent('onPost', $event);
}

I called die(); inside each one so I know they are being called.

My new plugin is very simple. I would like to be able to hook into the onPost event and receive the form data. My plugin is very simple for now as I am just concerned with hooking into the event. The below example has getName, getDeveloper, getDescription, getVersion etc removed for ease of reading. This is the only file in my plugin: /craft/plugins/myplugin/MyPlugin.php

<?php
namespace Craft;

class MyPlugin extends BasePlugin {

   public function init() {
      craft()->on('capture.onPost', function(Event $event){
         die('onPost <pre>'.print_r($event,true).'</pre>');
      });
   }
}

But this doesn't seem to be get called. I am assuming that I need something other than capture.onPost.

I have used the following docs, but would appreciate any help.

https://craftcms.com/docs/plugins/hooks-and-events

https://craftcms.com/docs/plugins/events-reference

I found the answer in a bit of a clumsy way, but the capture plugin has two services, capture_forms and capture_submissions. The first deals with saving the forms within the CraftCMS admin, the latter is for dealing with the form submissions.

I had to simply change my listener to craft()->on('capture_submissions.onPost', function(Event $event){...}); and I can see the event data.


Merge two arrays of ElementModels? I have two queries on related entries (using Many to Many plugin) to find both related and then reverse related entries:

{% set relatedArticles = article.relatedArticles %}

{% set reverseRelatedArticles = craft.entries.relatedTo(article) %}`

I want to merge these two ElementCriteriaModel, removing any duplicates before processing them further. I've tried this:

{% for item in reverseRelatedArticles %}
    {% if item not in relatedArticles %}
        {% set relatedArticles = relatedArticles|merge([item]) %}
    {% endif %}
{% endfor %}

But it doesn't remove the duplicates. Adding find() to the queries to turn them in to an array doesn't work either. Any way I can do this?

EDIT: I tried this, too:

{% set relatedArticles = article.relatedArticles.find()|merge(craft.entries.relatedTo(article).find()) %}

Yep, there's a great mystery about how the in containment operator actually works with objects. Twig Docs say it's possible:

  You can use this filter to perform a containment test on strings, arrays, or objects implementing the Traversable interface.

but I also tried this (multiple times) and did't get it working. I eventually always ended up using a workaround. In your case I'd do the following and use the entry's ID in the conditional:

{# Get arrays of entries #}
{% set entriesA = craft.entries(paramsA).find() %}
{% set entriesB = craft.entries(paramsB).find() %}

{# Prepare merge #}
{% set entriesBIds = craft.entries(paramsB).ids() %}
{% set allEntries = entriesB %}

{# Merge arrays #}
{% for entry in entriesA %}

    {# Don't merge duplicates #}
    {% if entry.id not in entriesBIds %}
        {% set allEntries = allEntries|merge([entry]) %}
    {% endif %}

{% endfor %}


Examples for Globals I just check the CMS. It looks great.

One question about the Globals: Where could they be used?

I found them in a Navigation-Example. Do you have other examples for me?

That's the beauty of Globals... they can be used anywhere!

Common usage examples include (but not limited to):

Content in your header
Content in your footer
Content in your sidebar
Anything else that appears frequently in your website

It's not a strict rule, but Globals tend to work great in situations where you only need a small amount of content to be commonly repeated throughout your site.


Craft 2: possible to control plugin triggering order? I have a Craft site which has 2 different plugins listening to the same event (the Contact Form beforeSend event).
The outcome is one is being triggered before the other and this is causing issues. Is there any way of specifying the priority of one plugin over the other or ensuring that they happen in a specific sequence?
Cole

Unfortunately, nothing I'm aware of for Craft 2, I'm afraid.
In Craft 3, there's still not a great solution, but there is a $append parameter where you can kind of force it to go to the top of the list: https://github.com/yiisoft/yii2/blob/master/framework/base/Event.php#L103
But that would stop a plugin that was loaded after yours to use the same parameter and come out on top.


Problems transferring updates back to live server For quite a long time i've updated and amended Craft by taking a copy of the files and database (.zip) from the live server, making the updates/changes/amendments locally and then transferring everything back (.zip).

Just recently i've had a couple of instances where i've made amendments and updates to an older site (Craft 3.1x to 3.4x) and everything has been fine locally. I then deploy the updated version back to the live environment and immediately get the error Craft can’t connect to the database with the credentials in craft/config/db.php.

I know this is a familiar error for some but i've only recently started seeing it.  I've spent a long time looking for and trying fixes but nothing seems to work for me!?

Mac OS Catalina
MAMP Pro 5.7
PHP 7.2.22
MySQL 5.7.26

Like I say, this is actually quite a new problem for me and I don't know what has changed?  Any help is very much appreciated.

From Craft Support:
Assuming the credentials in your .env are correct on that site, could you run ./craft clear-caches/all (or manually empty your web/cpresources and storage/runtime


Plugin (SyncDB) issue breaking site and unable to do anything I was in the process of setting up the UNION co SyncDB plugin and must have misconfigured something as I now get the following error: "Undefined index: skipTables" and seem to be completely locked out of both the admin and site.

This is the first time I've encountered something like this where I got completely locked out (I would have assumed I'd be able to still access admin to disable the plugin manually) and now have no idea how to disable the plugin and either load the site or get into admin.

Help would be very much appreciated.

It seems like the easiest way to address this issue is to remove the dependency from your composer.json file and to then run

composer update


Search entries based on two form values I have a form that consists of two dropdown boxes. These dropdowns contain values that relate to two sets of categories for one type of entry.

So when the search form is submitted there are two params that are passed, an interest and a destination.

The result I need, if I were to write it literally would be:

Select all the courses where INTEREST = [interest] AND DESTINATION = [destination]

Having a hard time figuring out how this is done in Craft.

Any help appreciated.

According to this page, this is how it's done:

{% set entries = craft.entries.search('interest:interestSearchValue destination:destinationSearchValue) %}

So, using the posted variables:

{% set entries = craft.entries.search('interest:' ~ craft.request.param('interest') ~ ' destination:' ~ craft.request.param('destination')) %}


Tasks either don't start or don't run as background processes I'm using Laravel Valet for my Craft development environment (which is awesome, btw) except for an issue with Tasks not kicking off. I initially stumbled upon the problem while using the Import plugin. The task created by the plugin would never start. Instead, it would sit in a "Pending" state.

I figured this was a bug with the plugin, because other tasks seemed to start and run just fine. I then also discovered another task-related problem with P&T's example task plugin, "Power Nap", where running the task would cause the whole site to hang.

What gives?

Both of these issues aren't present when running the site with MAMP. I've narrowed it down to something to do with Valet (which is using Caddy to serve PHP sites).

The issue seemed to stem from the fact that Caddy serves up PHP with fastcgi, instead of Apache or Nginx, and something to do with http requests used to start the task. AJAX requests (what my other functioning task plugins were using to kickoff) were unaffected.

Following a suggestion found here: https://stackoverflow.com/questions/11758334/fastcgi-finish-request-creates-hung-connection-when-open-session-exists

I've placed

session_write_close();
fastcgi_finish_request();

at the top of the runStep($step) function in each plugin's Task class and it resolved the issue!
Though, I'm not sure if either of the lines above have other implications.

Update
I should add, that from what I can tell, the above snippet does cause issues with tasks on Apache setups. (tasks will start yet never finish). Unless you are using Caddy Server in production, (you're probably not and using Valet for development) the snippet above should only be used as a temporary hack to get through your tasks.


Can I make Redactor add a 'title' attribute to img-tag? If I add an image to a rich-text field, I can set it's title. On the front-end however, the img-tag only gets an alt-attribute. I would also like the title-attribute to be set. Is this possible with a Redactor config-file, and if so, how?

None of the settings you can put in your Redactor config-file will do what you want. You can write a redactor plugin to do this, and then include your redactor plugin as a Craft plugin. One Craft plugin that does this is RedactorClips.

If your Craft plugin is mycraftplugin, and your redactor plugin files are myredactorplugin.css and myredactorplugin.js, then you store the redactor plugin files in the resources directory of your craft plugin, and in the craft plugin init() function, you call:

craft()->templates->includeCssResource('mycraftplugin/myredactorplugin.css');
craft()->templates->includeJsResource('mycraftplugin/myredactorplugin.js');


Deploying Craft on Apache Server - Error code 255 I'm trying to deploy our Craft 3 site on an Apache server. When running composer install I get the following error.

  @php nys-setup update
  Script @php nys-setup update handling the post-install-cmd event returned with error code 255

Does anyone know what the reason could be or where I could get more detail on the error?

That error was due to the php version not being specified when I had executed the command. I've tried running it with the specified path to the current php version and it seemed to work.


Umlauts in asset file-paths - Broken filenames on server I have some issues with the asset handling of files containing Umlauts. Specifically it seems that the uploaded files on the server get renamed to a "broken" filename.

Zweigänger-1960.jpg becomes ZweigaÌnger-1960.jpg

No issues in the DB fields.

What could be the reason for that? What I'm overlooking? Also a solution similar to "limitAutoSlugsToAscii" would work for me or even renaming the files according to a pattern.

I ran into the same problem lately, but got no clues from the accepted answer.

As of Craft 2.4 though, is a config setting that limits asset filenames to ASCII, so I'm happy with this workaround:

'convertFilenamesToAscii' => true

When storing assets in folders derived from the entry slug, you will additionally need to add the following:

'limitAutoSlugsToAscii' => true

Minor hassle: These settings naturally won't rename existing files and entries, so you need to touch each one in the control panel to take effect.

(I'm not completely convinced this filename issue is Craft's fault, since the file paths are broken/garbled in Coda, Safari and Safari for iOS – but work just fine in Firefox and Chrome by way of in-browser url-encoding.)


Guest Entries plugin with Paypal integration? I was wondering if someone with Paypal/PHP experience could give some suggestions on how to integrate Paypal with the Guest Entries plugin...

I want to use the Guest Entries plugin to build a job listing (it has been done before, check it out http://pasesetter.org/jobs) and would have to charge a small fee for users (no registration required) to submit job listings.

Before the entry/listing becomes published, users would be redirected directly to PayPal where they can make the payment. Paypal already has an auto-return option for websites payments, so users are redirected back to the site after payment.

Any guidance would be highly appreciated!

Hope that its not too late. I would not use paypal. Use stripe instead. You can then redirect the user to the Charge plugin by Squarebit.co.uk after the entry has posted. Once payment is made, change the status of your entry to enabled. Much cleaner and stripe is easier to work with.


Craft Commerce Trigger Event to Re-save All Products Because Commerce doesn't support Twig product title formatting right now, I built a custom plugin to automatically update the title field upon save of a product.

Here is the part from the plugin where I am hooking into the commerce_products.onBeforeSaveProduct event:

craft()->on('commerce_products.onBeforeSaveProduct', function(Event $event) {
    $product = $event->params['product'];

    if (count($product->collection))
    {
        $collection = $product->collection[0]->title;
        $titlePieces[] = $collection;
    }

    $modelNumber = $product->modelNumber;
    $titlePieces[] = $modelNumber;

    $titleSuffix = $product->titleSuffix;
    $titlePieces[] = $titleSuffix;

    $product->getContent()->title = implode(' ', $titlePieces);
});

All that works great when I manually edit a product, but we have about 500 products in the system right now, and nobody really wants to open up every entry and manually save it. The hope was that we could do something in the CP to trigger an event to re-save all product entries.

I went into the Commerce settings for each Product Type and re-saved the settings, which did trigger a "Resaving Furniture products" task. But, that didn't appear to update the title field for all the products.

Any other ideas on how I could avoid manually re-saving all entries?

There are probably many approaches, but you could write a simple console command (great guide here: https://spin.atomicobject.com/2015/06/16/craft-console-plugin/) in a plugin to do this.

Here's one I prepared earlier to use as an example...in my case I am doing this because I am using a pre-parse field that pulls in some external markdown content, but the principle is the same (assuming re-saving the entries updates the title field as you hope - but should take only a few mins to try!) - you'll need to adapt for commerce (Commerce_Product I think):

<?php
namespace Craft;

class BusinessLogicCommand extends BaseCommand
{
public function actionResaveFODEntries()
{
    print("### Resaving entries for Fundamentals Of Digital\n(So search indexes are updated by causing PreParse to re-pull in the generated content).\n\n");

    $criteria = craft()->elements->getCriteria(ElementType::Entry);
    $criteria->section = 'fundamentalsOfDigital';

    foreach ($criteria as $entry)
    {
        $success = craft()->entries->saveEntry($entry);

        if (!$success)
        {
            print("Failed to save entry $entry->title\n");
        }
        else
        {
            print("Saved $entry->title\n");
        }
    }
  }

}

To actually run the command I do this:

php yiic-env.php --env="console" businesslogic resaveFODEntries

...note the use of a specific environment, console in there - this is defined in my config/general.php with appropriate settings


Redactor splitting nested  tags I have a little issue with Redactor. Whenever I have a link within a link:

main link link within link

Redactor automatically modifies it to this:

main link link within link

Is there a way to stop this auto-modification?

The template engine (Twig) doesn't do anything like that – my guess is that the links only appear to render like your second example, because you're looking at the markup in your browser's dev tools, and modern browsers (e.g. Chrome) do a pretty good job of rendering invalid HTML.

Take a look at the raw source code (i.e. "View source" in your browser), and I suspect the actual rendered HTML will look exactly like your first example.

In any case, nesting <a> tags is not allowed and a very bad idea – so I'd recommend not doing it all :)


Image Transform 404 From User Session I am trying to load an image transform and continually get a 404 which references an issue with the UserSessionService. I have a attached a screen shot as well as twig template for one of the transform.

{% set contributor = entry.contributorProfile.first() %}
{% set headshot = contributor.headshot.first() %}

{% set thumb = {
    mode: 'crop',
    width: 200,
    height: 200,
    quality: 80,
    position: headshot.focusPctX ~ '% ' ~ headshot.focusPctY ~ '%'
} %}

<aside class="contributor-excerpt">
    <img src="{{headshot.getUrl(thumb)}}" alt="">
</aside>

You can't use FocusPoint like that with the default Craft Transforms, which might be your problem. You'll need to use Imager to get the position as a percentage supported.

Something like:

{% set image   = entry.listingImage.first() %}
{% set max479  = craft.imager.transformImage(image, {width: 480, height: 200, mode: 'crop', jpegQuality: 70, position: image.focusPctX ~ '% ' ~ image.focusPctY ~ '%'   }) %}
{% set min480  = craft.imager.transformImage(image, {width: 700, height: 250, mode: 'crop', jpegQuality: 70, position: image.focusPctX ~ '% ' ~ image.focusPctY ~ '%'   }) %}
{% set min700  = craft.imager.transformImage(image, {width: 960, height: 250, mode: 'crop', jpegQuality: 70, position: image.focusPctX ~ '% ' ~ image.focusPctY ~ '%'   }) %}
{% set min960  = craft.imager.transformImage(image, {width: 1280, height: 250, mode: 'crop', jpegQuality: 70, position: image.focusPctX ~ '% ' ~ image.focusPctY ~ '%'  }) %}
{% set min1280 = craft.imager.transformImage(image, {width: 1500, height: 250, mode: 'crop', jpegQuality: 70, position: image.focusPctX ~ '% ' ~ image.focusPctY ~ '%'  }) %}

{# standard Imager image transforms #}
<picture>
    <source media="(max-width: 479px)" srcset="{{ max479.url }}">
    <source media="(min-width: 1280px)" srcset="{{ min1280.url }}">
    <source media="(min-width: 960px)" srcset="{{ min960.url }}">
    <source media="(min-width: 700px)" srcset="{{ min700.url }}">
    <source media="(min-width: 480px)" srcset="{{ min480.url }}">
    <img src="{{ min1280.url }}" alt="" />
</picture>


Flushing logs halfway through a request? Sometimes I have long running requests that do imports or similar.

Currently logging using MyPlugin::log is only actually written to file once the request is done.

Is there a way to trigger log-flushing mid-request?

You should be able to do that with something like this:

Craft::getLogger()->flush();


Can you add anchors in redactor? I know if I turn off Purify HTML I might be able to get anchors working in Redactor rich text fields, but I want the ole client to be able to insert anchor links.

Does a plugin for this exist, or is it possible to make an 'insert anchor' button on my own easily?

I ended up getting this great plugin called Redactor Extras
https://github.com/elliotlewis/Redactor-Extras

Installed easily, and it has a properties option that it adds to rich text fields that lets you add a class or id to a piece of text. I just add id=something and then link to #something. Works like a charm for adding anchors!


striptags but leave link test in between I have a rich text (redactor field) that I'm using striptags on to remove the html markup from the front end. However I noticed for links it whips out the link and the text in between. Is this something I can fix with a regular expression? Can you even do that with a twig filter? If so does anyone have an example?

Here is my code:

{% set articleText = myFirstMatrixBlockWithType.blogArticleText %}
{% if articleText | length > 200 %}
    {% set articleTextTrim = articleText | slice(0, 200) ~ '...' %}
    {{ articleTextTrim | striptags }}
{% else %}
    {{ articleText | striptags }}
{% endif %}

Actually, excluding certain tags from being removed is built into the striptags filter.

You can use it like this:

{{ articleTextTrim | striptags('<a>') }}


Crop & Aspect Ratio Icons This is a very loosely associated question but looking at the plugin page for Pimp My Matrix, they depict icons for Crop Position, and Crop Aspect Ratio:

Are these custom fields from somewhere or is it possible somehow to add your own icons for something which looks to be essentially a radio button or select type of field?

This looks like the Button Box plugin, also from the team who developed Pimp My Matrix.


Craft 3 on new MAMP Pro 5 installation: "iconv(): Unknown error (22)" problem in /vendor/twig/twig/src/Extension/CoreExtension.php I have been fighting with a Craft 3 upgrade of a Craft 2 site on a local dev environment for a while now, though much of the time the problems turns out to be MAMP Pro 5 and/or FastCGI PHP. I'm not sure what's going on with the latest error, and the exact error returns no Google search results at all, so am at a loss for how to proceed.

The error in full is this:

PHP Notice – yii\base\ErrorException
iconv(): Unknown error (22)
1. in /Users/mydir/Sites/mysite/vendor/twig/twig/src/Extension/CoreExtension.php at line 1000

where line 1000 is the return line in this function:

function twig_convert_encoding($string, $to, $from)
{
    return iconv($from, $to, $string);
}

The error only shows up on some pages, not all. Can't figure out a pattern of commonality there. From Googling iconv (where I do see it is a known problem child but couldn't spot anything that shed more specific light) I guess it's a character-encoding utility. We do have some Spanish-language content on the site, but the actual Spanish-language channel displays fine, for whatever that's worth. If it matters at all, all my database tables are encoded UTF8, though collation is sometimes utf8_general_ci and sometimes utf8_unicode_ci.

The whole stacktrace is of core Twig files, no template files where I could go in and flail around with some troubleshooting code to try to narrow down the problem.

Thanks very kindly in advance for any thoughts or ideas. It's begun to feel as if I'll never get this site upgraded (and here's where I'd add the grimacing emoji if this community did not frown-emoji on such things).

Per my earlier comment, the convert_encoding filter is causing this, I think only in newer versions of Twig than what my live site running Craft 2 uses.

I guess that probably somewhere in my site content, one of our content managers somehow inserted a character that convert_encoding is choking on. Rather than figure out where that is, and know that the site would blow up again the next time they did it, I've replaced bodyText|striptags|convert_encoding('UTF-8', 'HTML-ENTITIES')|slice(0, 200)|default('Read more') with
bodyText|striptags|slice(0, 200)|default('Read more')|raw, and while I have not tested this thoroughly to know that it works as intended in all cases, it's at least not blowing up an index listing of 100 articles because (I suspect) one entry has some weird character in it any longer.


Override SuperTable reverse related entries limit I've got two kinds of channel entries: Bills and Legislators. Legislators have a SuperTable of votes. Each vote is related to one Bill. I want to get all the votes associated with a particular Bill and display them on that Bill's page, but I can't fetch more than 100 items. Here's my current code:

{% set reverseRelatedVotes = craft.supertable.getRelatedElements({
    relatedTo: {
        targetElement: entry,
        field: 'scorecardVotes.bill',
        },
    section: 'legislators'
}).limit(null).order('lastName ASC') %}

limit(10) works as expected, but anything over the standard Craft limit of 100 returns 100. How can I get all the related votes for a given Bill?

Figured it out - I needed to remove the limit earlier in the process: adding 'limit' => null after line 72 of SuperTableVariable.php did the trick.

I'll submit a pull request to that effect as soon as I figure out how to do that.


Set dynamic class in for Loop I have this simple element model and I'm trying to add dynamic class within loop.
So every time a model outputs, It outputs dynamic class. Can't go for another loop within loop, in case I could, therefor It'd be easy.

            {% set tags = slide.foodTags %}
            {% if tags %}

            <div>
                  {% for tag in tags %}
                        <span class="{# dynamic-class #}">
                            {{ tag.title }}
                        </span>
                  {% endfor %}
            </div>

           {% endif %}

I can't comment yet to reply directly to Mats Mikkel Rummelhoff's comment above, but just in case someone comes across this and is looking to alternate styles instead of basing it on the loop.index count.

You would do so using the Twig odd or even tests

{{ loop.index is odd ? 'odd' : 'even' }}

or

{{ loop.index is even ? 'even' : 'odd' }}

There is no loop.odd key


Child categories appear as their parent when selected In an entry, when selecting a child category, the parent is shown as the selected item. This prevents the use of any child categories. Any help would be appreciated.

Use Case:

Selection Modal:

Selection within the Entry

Do you have a limit of 1 set for the number of categories? Selecting a child category (Pacific Northwest) selects the parent as well, and if there is a limit of 1, then only the parent end up selected.

To work around this, you could model the regions with a structure rather than categories. Picking elements from a structure does not select the parent as well, so with a limit of 1 it would be possible to select Pacific Northwest.


Git Workflow and Multi Environment - how to approach I'd like to be able to use git version control with Craft. Is this possible and if it is what is the best approach to ensure that all files/assets and the database are properly synced across local, staging and production servers?

Matt has a point, this is similar to What's the best practice for handling data migration and organization across development environments?, but that question focuses mainly on how to handle the database (definitely see those answers).

More generally speaking...

Multi-Environment Config

Set yourself up with Multi-Environment Configs in both craft/config/general.php and craft/config/db.php so that you don't have to be updating path settings every time you migrate data between environments.

Be sure to set some Environment-Specific Variables for the site URL and server path for each environment. That way you can use those variables in the control panel settings (the Site URL setting in the Setting → System → General and Assets paths in Settings → Assets → Your asset settings).

Here is a sample general.php file

return array(

    '*' => array(
        'omitScriptNameInUrls' => true,
        'usePathInfo'=> true,
        'cpTrigger' => 'example-admin',
        'allowAutoUpdates' => false,
    ),

    'example.dev' => array(
        'devMode' => true,
        'useCompressedJs' => false,
        'allowAutoUpdates' => true,
        'environmentVariables' => array(
            'siteUrl' => 'http://example.dev/',
            'sitePath' => '/Applications/MAMP/htdocs/example/html/',
        ),
    ),

    'staging.example.com' => array(
        'environmentVariables' => array(
            'siteUrl' => 'http://staging.example.com/',
            'sitePath' => '/var/www/vhosts/staging.example.com/html/',
        ),
    ),

);

And an example db.php file

return array(

    '*' => array(
        'tablePrefix'   => 'craft',
    ),

    'example.dev' => array(
        'server'        => 'localhost',
        'user'          => 'root',
        'password'      => 'root',
        'database'      => 'example_dev',
    ),

    'staging.example.com' => array(
        'server'        => 'localhost',
        'user'          => 'example_staging',
        'password'      => '********************',
        'database'      => 'example_staging',
    ),

);

For more on Multi-Environment Configs see Multi-Environment Workflows on Straight Up Craft

Version control with Git

You can definitely use Git. I version everything except for user file uploads and /craft/storage and it works great.

My master .gitignore file in the root of my project looks like (specific to my setup, YMMV)

.DS_Store

# Node/Sass
node_modules
html/css/public/main.css.map

# Config
dandelion.yml
sftp-config.json
craft/config/db.php

Then in each directory I want to ignore the contents of (craft storage and user uploads) I put a .gitignore file with...

# Ignore everything
*

# But not this file
!.gitignore

And as Matt pointed out in his other comment on your question, do see the answers on the related question What's the best practice for upgrading a versioned Craft site?


Apply imageTransform on twitter media feed {% set response = craft.twitter.get('statuses/user_timeline', { tweet_mode:'extended', count: 20 }) %}
            {% if response.success %}
            {% for tweet in response.data %}
            {% if tweet.extended_entities.media is defined %}
            {% for item in tweet.extended_entities.media if item.type == 'photo' %}

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

This throws a Runtime error: Impossible to invoke a method ("getUrl") on a string variable ("http://pbs.twimg.com/media/DlAIWwkUcAAY_3u.jpg").

What other method is possible?

Using the Imager plugin:
{% set externalImage = 'http://pbs.twimg.com/media/DlAIWwkUcAAY_3u.jpg' %}

{% set transformedImages = craft.imager.transformImage(externalImage, [
                { width: 200, height: 200 }])
              %}
         {% set response = craft.twitter.get('statuses/user_timeline', { tweet_mode:'extended', count: 20 }) %}
            {% if response.success %}
            {% for tweet in response.data %}
            {% if tweet.extended_entities.media is defined %}
            {% for item in tweet.extended_entities.media if item.type == 'photo' %}

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

Craft's built-in transform functionality doesn't support transforming external URLs. You could use my Imager plugin to do this instead.

EDIT:

Based on your example, you'd use Imager something like this:

{% set response = craft.twitter.get('statuses/user_timeline', { tweet_mode:'extended', count: 20 }) %}
{% if response.success %}
    {% for tweet in response.data %}
        {% if tweet.extended_entities.media is defined %}
            {% for item in tweet.extended_entities.media if item.type == 'photo' %}
                {% set transformedImage = craft.imager.transformImage(item.media_url, { width: 200, height: 200 }) %}

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

So, the essential part is that you need to pick up the url to each item in the loop (item.media_url, if that's what the twitter plugin returns), and do the transform inside the for loop.


A Structure section with an entry to a channel index I don't have commenting privileges yet, so couldn't comment on either of these posts (here and here) regarding an entry in a Structure section that links to a Channel index. Between the two posts above I think I mostly understand what's going on, but have a question about an entry type for an entry in a Structure that essentially refers to a page that is a listing of Channel entries (basically an index page for the channel).

My situation: I have an About section with a few subpages that are dropdowns links under "About" in the main navigation bar: Vision, Leadership, and Qualifications. Vision and Qualifications are basically static pages, but the Leadership page lists a number of people (with corresponding images/titles/bios). So, I created a Channel section called "Leadership", each entry containing an individual. In the About section (Structure type) I created two entry types: "about" and "leadership". The "about" entry type has fields such as "body", "hero image", and "subheader" and is used for the static entries Vision and Qualifications. However, for the "leadership" entry type I'm uncertain what fields I should put in it. Since that one entry in the "About" section exists for the purposes of building the navigation, there isn't really any content in that entry. It's just there for the navigation link, and to get the user to a template (in my case templates/about/_types/leadership.html) that will output the individuals from the "Leadership" channel.

Does it make sense that I would just create a "leadership" entry type with no assigned fields (other than the default title), or is there a better way to approach this?

I like what Matt P wrote in his answer:

try to consider how someone [else] will find the logic of the CMS design

The other factor you want to consider in information architecture is you only want store data once in the database. So how you intend to pull that data out also is going to influence your decision on how you store it.
The good news there is Craft really lets you pull data from virtually any place in the system very easily so it kind of comes down to an organizational choice. You have 2 options: Matrix or Entries.
Matrix Fields
You might consider a matrix field because these attach right on the entry itself. That way, a user edits the Leadership entry directly, they'll find the data there, in an intuive away. The other bonus is you can move the entries up and down in a certain order or turn them off right in the context of previewing the page.
Matrix is a good option if the data is more-or-less confined to that entry and you don't need to access the data anywhere else in the system.
Entries
If you need to relate content back to each other, or you find the leadership team data needs to exist in a context outside that particular page, it's probably the best option to bring them in as a channel (or structure).
Craft 2.5 made a huge change as to the way you can edit related entries right in the same entry. You might want to consider using an "entries" field that relates back to your Leadership channel and let the user pick exactly which team members you want to spit out on that page. The other benefit is in this way, you can open up  those "related" entries right from the Leadership entry, much like a Matrix block would—enhancing usability—but you still keep them as entries.
TL;DR
I don't know how many people are on the leadership team but if you have but more than a couple dozen, it might make sense to keep them as entries. Otherwise if you don't plan to use that data anywhere else in the system, a matrix field could be a nice option too.


Utime failed: Operation not permitted in craft/app/helpers/IOHelper.php on line 1540 I'm trying to install craft, but I have 4 errors like this on the screen:

Utime failed: Operation not permitted in craft/app/helpers/IOHelper.php on line 1540

What are possible causes, and how can I fix it and install properly craft?

It looks like a permissions related issue.  Check the user:group owner of all of the files in the craft/app folder and make sure that they are set to the same user:group that your PHP installation is running as.


How to calculate the number of days left? I want to calculate the remaining days between the current day (now) and a future date set as a date field in {{ inschrijven.datumEvenement }} globals

{{ inschrijven.datumEvenement.diff(now).format('%d') }}

This is what I came up with but it doesn't generate the right number of days left.

Using now = 05-15-2015, inschrijven.datumEvenement = 08-30-2015 the above tag generates "14".

You want to use "a" as your DateInterval format parameter instead of "d".

Also, you may need to use Twig's date function on the end date, which "converts an argument to a date to allow date comparison".

This should give you the correct number of days between now and the future date:

{{ date( inschrijven.datumEvenement|date ).diff( now ).format('%a') }}

or

{{ date( inschrijven.datumEvenement|date ).diff( now ).days }}


Craft\Exception on saving entries having images I have created a new entry in which user can also add images(already uploaded or new upload)
I can save entry successfully if I don't add any images to it. When I add any image and try to save the entry following error is displayed-

Craft\Exception
This file type is not allowed

Earlier different error was displayed which was related to imagick.
Since I have installed imagick and it's php extension, the error is replaced by this new error.

I'm going to go out on a limb and say you're trying to upload a file type that isn't allowed under that Asset fields "Restrict Allowed File Types?" section.


Private plugin distribution in Craft CMS 3 what is the best way to install private plugin in Craft CMS 3? The private plugin is installed in private GitHub repo, but we don't have a custom packagist that we would use, therefore I wonder if there is any option to enable private plugins via composer/plugin-installer?

I haven't done this with Craft, but with another Laravel project I was able to add a package from a private repo as follows:

1) In composer.json, after the require array, add a new repositories array:

"require": [
  ...
],
"repositories": [
  {
   "type": "git",
    "url": "https://github.com/YOURGITHUBNAME/your-repo.git"
  }
]

2) In the "require" array, add your package:

"require": [
  "YOURGITHUBNAME/your-repo": "*",
  ...
]

3) Here's the under-documented trick you need to do to get it all working: you must create a "release" in github, and the release name must be the letter "v" followed by the version number (e.g. v1.0.0). So go to your repo, click the "Releases" link, then click the "Draft a new release" button. It asks for a tag version and a Release title... I can't remember which of these is the critical one, so just put v1.0.0 into both of these fields.

4) Now if you run composer install it should (hopefully) bring in your private repo package. Might need to provide some kind of authorization / API key to access it if it's a private repo (I'm not sure how exactly this works, but should be fairly easy to find documentation on).


Is there a 'slug' for assets? I'm trying to create a site with a gallery, and am investigating the possibility of getting Craft to treat an asset as an entry so I can display a detail page for an image without having to create an entry for it specifically.

I think it might do what I need, but I've fallen at the first hurdle whereby according to the documentation (unless I've missed it) assets don't have a slug. I could use ID, but the client will want keywords in the URL blah blah.

If I pull an asset and output {{ asset.slug }}, it does return what I'd want it to. The problem is, if I edit the title, that value isn't updated and there doesn't appear to be a way to get to it.

Is it possible to get to this somehow?

Could you add your own field to use as a slug?

When you edit an Asset Source in Settings you get the Field Layout tab same as you do for Entries. You could maybe add something there and then combine this with a Route somehow?


Craft 3 doesn't translate static strings I am making a website with Craft 3 and I have some static text that needs to be translated.

I followed Craft's documentation on it. I created my translations/fr/site.php file and use the {{ 'String'|t }} format to translate my strings.

I tried everything I found on the web, but I can not make it work. My strings stay in english and doesn't translate. It doesn't even seem to access the site.php file.

I tried to clear my cache, restart my Docker container, change the folder name to fr-CA instead of fr ...

I found another member here that had the same problem as me, but he updated Craft and it worked. My Craft configuration is up to date...

Is there something I am missing?

Thank you.

I'm simply trying to follow the docs as good as possible.

Try the following:

Example String we'll be using: "cheese" | "fromage"

in your config/general.php make sure you have your siteUrl set as an array with at least two entries, example:'siteUrl' => ['my_site_en' => 'http://localhost:1234, 'my_site_fr => 'http://localhost:1234/fr/'];
in your translations/fr/site.php make sure it only contains the following

<?php

return [
  'cheese' => 'fromage',
];

in your twig file add the following <h1>{{ "cheese"|t }}</h1>

4. important: Access your Control Panel (cpTrigger in config/general.php for the first part of the URL), => http://localhost:1234/%CP_TRIGGER%/settings/sites and make sure you have 2 sites, both in the same group, one in en, one in fr & their URLs must also be set!   It should look similar to this

As long as all 4 steps are followed, it should work.

Hope this helps!


Adding more data to the "commerce/cart/update-cart" action Is it possible to add additional data to the "commerce/cart/update-cart" callback? For instance, we want to include an Asset field so we can populate a cart modal with the item's image in one call?

Or is there a better way to tackle this type of functionality?

You could either extend the craft commerce update-cart controller
or get the specific fields via element-api what will unfortunately result in an extra api call.


Including Entry Property in Object I'm trying to get the category title to render within the following object but it's just returning it as the static string instead of the {{ category.title }} actually rendering.

{% set seo = craft.seo.custom(
    'Welcome back, {{ category.title }}',
    'Test Meta Description!'
) %}

You want something like this:

{% set seo = craft.seo.custom(
    'Welcome back, ' ~ category.title ~ ', Test Meta Description!'
) %}

Or even more clear (to me anyway):

{% set seo = craft.seo.custom(
    "Welcome back, #{category.title}, Test Meta Description!"
) %}

More here: https://twitter.com/nystudio107/status/938018528527036416?s=21


Double storage of values in table-field I'm currently creating some standard templates which should help to find good defaults for matrix output. This is where I stumpled upon the somehow weird structure of table data.

Here's a simplified structure of what I want to build:

{% for row in table %}

  {% for data in row %}
    {{ data }}
  {% endfor %}

{% endfor %}

Outputting table content like this:

{% for row in table %}
  {{ dump(row) }}
{% endfor %}

shows me that each row has double entries:

array(6) {
  ["col1"]=> string(7) "Hamburg"
  ["col2"]=> string(7) "1730000"
  ["col3"]=> string(7) "2600000"

  ["city"]=> string(7) "Hamburg"
  ["population"]=> string(7) "1730000"
  ["urbanPopulation"]=> string(7) "2600000"
}

While this might make sense in some cases, I don't get it. Why is this behavior and in which cases could the convention "col1", "col2", etc. make sense?

On first sight, this choice is very unfortunate as it prevents dynamic table output. Sure, you could use hacks like loop.index to target these, but that makes the code very unreadable and ugly.

Does anyone have the same issue with this?

The data is not stored twice in the database. I suspect that craft adds the additional array items when prepping the data, so that they can be referenced by either column number or column title.

But with a little finesse, you might be able to do something like the following, using key, value in the for loop and twig's slice filter:

    {% for row in entry.myTableFieldHandle %}

            {% for key, data in row if key|slice(0,3) == 'col' %}
                {{ data }}
            {% endfor %}

    {% endfor %}


Does Craft automatically sanitize user input? Can I rely on Craft to clean user input, is safe to save the following data like in the below example function, if not, what is the Craft best practice for cleaning(making it safe) user input?

public function actionCustomSaveUser(){

    $user = new User();
    $user->newPassword = $_POST['password'];
    $user->username = $_POST['username'];
    // and more $_POST ...

    Craft::$app->getElements()->saveElement($user, false);
    // etc...

}

First of all I would access the post using this format

Craft::$app->getRequest()->post('username')

Craft then extends the YII 2 request object. Does it sanitise input, not really, but models can set validation rules like this

https://forum.yiiframework.com/t/how-does-yii-handle-data-sanitization/83006


SQL error when trying to use sortOrder on Matrix related block (Craft 2) I'm getting the following SQL error when trying to simply order related entries in a Matrix block. Anyway around this?

  CDbCommand failed to execute the SQL statement: SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'sortOrder' in order clause is ambiguous. The SQL statement executed was: SELECT elements.id, elements.type, elements.enabled, elements.archived, elements.dateCreated, elements.dateUpdated, ...

This is what's throwing the error:

{% set package = craft.entries({
relatedTo: block,
order: 'sortOrder'}) %}

So this was me being a bit of a numpty here. I was calling the field the wrong way. Doing the following obeys the sort order from the field:

{% for entry in block.hostingPackage %}


Are values in Asset fields held globally for a particular Asset? I have a few fields assigned to an Asset Source, which allow the user to alter the appearance of the image (large, small, portrait, landscape) etc. on the front end.

I'm not sure if this is a bug or intended behaviour, but when I enter a field value as an editor to a particular instance of an Asset, if that Asset then appears elsewhere in a different entry, it appears to inherit the field values of the Asset where it was used previously.

I need to be able to have an image in one entry set to, for example, 'large', but also have that same image appear on another entry but set to 'small'.

Assuming this is intended behaviour, how can I get around this?

The fields attached to an asset source will be connected to the asset, and will follow the asset no matter where it's used. So yes, this is the intended behavior.

If you need to specify on an entry basis what size an image should have, you need to add a field for selecting size on the entry type. Say you have a field "Main image" in your entry type, you'd add a "Main image size" field to the same entry type.

If you're making a gallery or something, instead of having one assets field where you select all images, you could create a matrix field that has one column for (one) asset and one column for size instead, and add each image as it's own row.


How to limit navigation by entry type I couldn't find this anywhere so I thought I would post the answer. How do you limit the output of a navigation element to a specific entry type.

This question is explicitly for the navigation element - I only want to show a specific entry type in a navigation element.

Both of these work:

{% set sectionNamePages = craft.entries.section('sectionName').type('entryTypeA').level(1) %}
{% for page in sectionNamePages %}

{{ page.getLink() }}

{% endfor %}

{% set sectionNamePages = craft.entries.section('sectionName').level(1) %}
{% for page in sectionNamePages.type('entryTypeA') %}

{{ page.getLink() }}

{% endfor %}


How to find logged IP address from SproutForms sent email I see in the documentation for Sprout Forms that IP address is recorded for sent emails. Is this the IP address of the person submitting the form or the IP address of the server sending the mail? Is there a way I can see the IP address of a user who submitted a form on my site with Sprout Forms?

https://sprout.barrelstrengthdesign.com/docs/email/sent-emails.html#tracking-info

The ipAddress of the user submitting the form is stored in the sproutforms_entries.ipAddress column.

Right now, you'd have to look in the database or create a custom report to view the data. I've opened an issue to add that data to the default report so it can be seen more easily:
https://github.com/barrelstrength/craft-sprout-forms/issues/275

You can use Sprout Reports to create a custom report integration using Twig, PHP, or MySQL.


How do I access AJAX data within a controller method? I have a JavaScript file which sends an array of data to a controller:

Craft.postActionRequest('wineNotes/wineSpreadSheet/saveWines', data, ...)

The structure of the data variable is as follows:

var data = {
    Data: sData
}

... where sData is an array of temp variables sData(temp1,temp2,...) and the structure of each temp object is like this:

temp = {
    "wine":        ht.getDataAtCell(i,0),
    "country":     ht.getDataAtCell(i,1),
    "region":      ht.getDataAtCell(i,2),
    "note":        ht.getDataAtCell(i,3),
    "tastingdate": ht.getDataAtCell(i,4),
    "rating":      ht.getDataAtCell(i,5),
    "maturity":    ht.getDataAtCell(i,6),
    "conclusion":  ht.getDataAtCell(i,7)
};

How can I access the parameter temp.wine for each temp in the sData array within the following method of my controller?

public function actionSaveWines()
{
    // ???
}

I know the data structure is kinda wierd its actually an array of arrays. Read the below code and you might understand.

for(i=0;i<NumRows;i++)
        {
            temp = {
                "wine":ht.getDataAtCell(i,0),
                "country":ht.getDataAtCell(i,1),
                "region":ht.getDataAtCell(i,2),
                "tastingdate":ht.getDataAtCell(i,3),
                "rating":ht.getDataAtCell(i,4),
                "maturity":ht.getDataAtCell(i,5),
                "conclusion":ht.getDataAtCell(i,6),
            };
            sData.push(temp);
        }

        var data = {
            Data: sData,
        }
        Craft.postActionRequest('wineNotes/wineSpreadSheet/saveWines', data, function(response) {

        });

Any properties of the object you pass into Craft.postActionRequest()’s second argument will be available to Craft as POST parameters, so you can get to them with HttpRequestService::getPost():

$sData = craft()->request->getPost('Data');

foreach ($sData as $temp)
{
    $wine = $temp['wine'];
    // ...
}


Craft Equivelent of EE addon CE Image Bulk Tag? I'm preparing to migrate an old ExpressionEngine site to Craft and there are channels with images that are being resized by wrapping the rich text editor with ce image bulk tag like this:

{exp:ce_img:bulk attributes="class='img-responsive'"}
 {brand_copy}
{/exp:ce_img:bulk}

Is there an easy way to accomplish the same thing in Craft.. apply bulk transforms to images in a  rich text editor?

Need this for legacy content that will be moved in with feedme, new content will have a matrix set up using a different entry type.

You can do the same thing using the Retcon plugin for Craft. Have a look at the wiki entry for the transform filter for more details.


Trigger Info window in Smart Map using external navigation I would like to trigger an info window in Smart Map using a navigation that lives beside the map. I've managed to figure out how to use the zoomOnMarker function, however, the info window does not pop with this function.

{{ entry.title }}

When conducting a proximity search, it's common practice to display a list of nearest locations, alongside a map displaying markers of nearest locations.
You may want each marker's info bubble to open when clicking on the text link.
You'll need a JavaScript function to handle opening the info windows.
function openInfoWindow(mapId, fieldHandle, entryId) {

    // Prep to open info window
    var markerName = mapId + '.' + entryId + '.' + fieldHandle;
    var map        = smartMap.map[mapId];
    var marker     = smartMap.marker[markerName];
    var infoWindow = smartMap.infoWindow[markerName];

    // Close all open info windows
    for (var i in smartMap.infoWindow) {
        smartMap.infoWindow[i].close();
    }

    // Open new info window
    infoWindow.open(map, marker);

    // Zoom to marker
    var zoomLevel = 6;
    smartMap.zoomOnMarker(mapId, markerName, zoomLevel);

}

When you loop through your entries to generate the results list, you can attach an onclick event which calls your function.
{% for entry in allEntries %}

{{ entry.title }}

{{ entry.myAddressField.distance }} miles away

{% endfor %}

For more information, check out the documentation for manipulating the map in JavaScript...


How can I iterate more than 100 blocks in a matrix field for loop? I am looping through a matrix field and it appears to stop looping when the index reaches 100 but I have more than 100 blocks here. How can I loop through the remaining blocks?

{% for block in entry.myMatrixField %}
    {{ loop.index }}
{% endfor %}

The default limit for fetching elements is 100. This can be overridden as follows:

{% for block in entry.myMatrixField.limit(null) %}

Passing in null will grab all of them, or you can pass in the specific number you want:

{% for block in entry.myMatrixField.limit(400) %}


Dynamic Asset Sub Folder Paths based on section and. if/else or turnery operators How can I create dynamic paths for asset uploads?
Basically I want my structure to be like so;

company-name-slug
  company
    logo-1.jpg
    image-2.jpg
  products
    product-image-1.jpg
  services
    service-image-1.jpeg
    service-image-2.jpeg

I have a field called gallery for the above assets.

Then I have sections for company, products and services.
Each section uses the gallery field. Products and Services uses a related content field for the company (called company).

I want to use the gallery field across all sections, but then set the dynamic paths per service/product and company inline with the above structure.

Here is what I have tried but it just errors out. I have tried various combinations and some work some don't, but I cannot get to desired structure.

{% section == 'Company' ? slug : company.one|kebab %}/{section|kebab}

How can I achieve this or is there a way I can inject some better twig logic into the subfolder field?

So this was a simple fix and not to use {% %} tags but instead to use {{ }} tags. Changing the above logic in the subdirectories filed like so seems to have resolved the issue.

{{ section == 'Company' ? slug : company.one|kebab }}/{section|kebab}


Permission error on session_start() after 3.5 upgrade On my dev box, I have php/nginx running as 'jim'. I've followed the suggestions on permissions in the install docs. (744 since php is running as 'jim')
I'm getting this error...
PHP Warning – yii\base\ErrorException

session_start(): open(/var/lib/php/sessions/sess_a693hln410j5992m23otjnc7nf, O_RDWR) failed: Permission denied (13)

and my folder perms look like this...
-rwxrw-r--   1 jim jim    618 Aug 10 14:21 composer.json
-rwxrw-r--   1 jim jim 216281 Aug 24 11:29 composer.lock
drwxrwxr-x   4 jim jim   4096 Aug 18 11:55 config
-rwxrwxr-x   1 jim jim    655 Jun 23 17:36 craft
-rw-rw-r--   1 jim jim    330 Jun 23 17:36 craft.bat
-rw-rw-r--   1 jim jim   1813 Jul 24 15:54 gruntfile.js
-rw-rw-r--   1 jim jim   1037 Jul  7 18:33 gulpfile.js
-rw-rw-r--   1 jim jim    982 Jul  2 17:19 layout.html
drwxrwxr-x   2 jim jim   4096 Aug 17 15:14 logs
drwxrwxr-x   2 jim jim   4096 Jun 23 17:36 modules
drwxrwxr-x 683 jim jim  24576 Jul 11 15:28 node_modules
-rw-rw-r--   1 jim jim    420 Jul 11 15:28 package.json
-rw-rw-r--   1 jim jim 356363 Jul 11 15:28 package-lock.json
drwxrwxr--   7 jim jim   4096 Jul 16 08:38 storage
drwxrwxr-x  12 jim jim   4096 Aug  6 10:07 templates
drwxrwxr--  56 jim jim   4096 Aug 24 11:29 vendor
drwxrwxr-x   5 jim jim   4096 Jul 20 23:36 web

I've also tried opening up the following files/directories with 777, but still get the error:
.env
composer.json
composer.lock
config/license.key
config/project/*
storage/*
vendor/*
web/cpresources/*

Easy fix. Removed all session data which had www-data:www-data ownership.


GZIP seems to compress only HTML, not CSS or JavaScript I'm not 100% sure this is a Craft specific problem, but I'll try here, as it relates to a Craft installation.

After running a number of tests, it seems that my CSS and JavaScript files are not getting GZIP-ed. I have a .htaccess file in my public folder, and no .htaccess files in the subfolders below. My CSS and JS files are stored in /assets/cssand /assets/js respectively (relative to the publicfolder).

My .htaccess file looks like this. Is there something I'm doing wrong? I thought the settings of the .htacces should work for subfolders when not overridden?

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteOptions InheritDown

    # 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>

<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE application/javascript
  AddOutputFilterByType DEFLATE application/rss+xml
  AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
  AddOutputFilterByType DEFLATE application/x-font
  AddOutputFilterByType DEFLATE application/x-font-opentype
  AddOutputFilterByType DEFLATE application/x-font-otf
  AddOutputFilterByType DEFLATE application/x-font-truetype
  AddOutputFilterByType DEFLATE application/x-font-ttf
  AddOutputFilterByType DEFLATE application/x-javascript
  AddOutputFilterByType DEFLATE application/xhtml+xml
  AddOutputFilterByType DEFLATE application/xml
  AddOutputFilterByType DEFLATE font/opentype
  AddOutputFilterByType DEFLATE font/otf
  AddOutputFilterByType DEFLATE font/ttf
  AddOutputFilterByType DEFLATE image/svg+xml
  AddOutputFilterByType DEFLATE image/x-icon
  AddOutputFilterByType DEFLATE text/css
  AddOutputFilterByType DEFLATE text/html
  AddOutputFilterByType DEFLATE text/javascript
  AddOutputFilterByType DEFLATE text/plain
  AddOutputFilterByType DEFLATE text/xml
</IfModule>

You can use .htaccess config from HTML Boilerplate for better configuration. There are a lot of useful config option there.

I use this config to enable gzip compression in my personal blog, and it's worked perfectly.

<IfModule mod_deflate.c>

    # Force compression for mangled `Accept-Encoding` request headers
    <IfModule mod_setenvif.c>
        <IfModule mod_headers.c>
            SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
            RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
        </IfModule>
    </IfModule>

    # Compress all output labeled with one of the following media types.
    <IfModule mod_filter.c>
        AddOutputFilterByType DEFLATE "application/atom+xml" \
                                      "application/javascript" \
                                      "application/json" \
                                      "application/ld+json" \
                                      "application/manifest+json" \
                                      "application/rdf+xml" \
                                      "application/rss+xml" \
                                      "application/schema+json" \
                                      "application/vnd.geo+json" \
                                      "application/vnd.ms-fontobject" \
                                      "application/x-font-ttf" \
                                      "application/x-javascript" \
                                      "application/x-web-app-manifest+json" \
                                      "application/xhtml+xml" \
                                      "application/xml" \
                                      "font/eot" \
                                      "font/opentype" \
                                      "image/bmp" \
                                      "image/svg+xml" \
                                      "image/vnd.microsoft.icon" \
                                      "image/x-icon" \
                                      "text/cache-manifest" \
                                      "text/css" \
                                      "text/html" \
                                      "text/javascript" \
                                      "text/plain" \
                                      "text/vcard" \
                                      "text/vnd.rim.location.xloc" \
                                      "text/vtt" \
                                      "text/x-component" \
                                      "text/x-cross-domain-policy" \
                                      "text/xml"

    </IfModule>

    <IfModule mod_mime.c>
        AddEncoding gzip              svgz
    </IfModule>

</IfModule>


jQuery Validate with Charge plugin I'm trying to validate my form before the charge.js is triggered.

I've decided to drop submit button in favour of a standard button and then use valid() method to process submit, so this is what I have now:

<form id="charge-form">
<!-- some fields here !-->
<input id="submit" type="button" value="Subscribe">
</form>

<script>
  $("#charge-form").validate();
  $("#charge-form").charge();
  $("#submit").click(function() {
    if ($("#charge-form").valid()) {
        $("#charge-form").submit();
    }
  })
</script>

Validation works, and when testing the conditional statement with console.log it also works properly, but when actually used it gives $form.get(...).submit is not a function in the console in charge.js

Did anyone make jQuery Validate work with Charge?

Silly me, this has nothing to do with charge.js, one simply can't have a button with an id="submit" as weird things will happen - see this thread

<input type="button" id="otherThanSubmit">

this works fine


Validate a lineItem option within a plugin? I have a lineItem option that needs validation. It’s actually an input field that can’t be blank, and different to the lineItem’s note.

The docs for Add to Cart mention using onBeforeAddToCart but it also needs to be validated if a customer decides to edit this field in the cart so perhaps commerce_cart.onBeforeAddToCart is not the right event here.

Can anyone offer an example of how to do this? This needs to be server-side validation, not front-end.

I've achieved something similar but used commerce_lineItems.onBeforeSaveLineItem.

This event is fired every time a line item is created or edited. Fired on /updateCart (product page) or /updateLineItem (cart page).

You might run into problems because the lineItems in the event won't contain a post request unless its the lineItem that triggered the event through a form.

You need to grab the events line item and check it against the lineItemId in the post request before doing any comparisons - unless its a new lineItem.

// Get the line item being saved from the event
$item = $event->params['lineItem'];

// Is this a new line item?
$isNewLineItem = $event->params['isNewLineItem'];

// Get the line item id that triggered the save from the post request
// (this will only exist if we're updated a line item that currently exists)
$lineItemId = craft()->request->getPost( 'lineItemId' );

// If the current line item being saved is new
// OR
// If its an existing line item and matches the one that triggered the event
if ( $isNewLineItem || $item->id == $lineItemId ) {
  //rest of the code
}

I then looked to see if the option was in the post request.

$text = craft()->request->getPost( 'options.Text' );

If it wasn't I added a flash message and stopped the action.

$event->performAction = false;
craft()->userSession->setFlash( "itemError", "You must add some text before adding this product to your basket" );


How to retrieve Site Url and Site Name in Plugin I'm having an exceedingly difficult time trying to retrieve the Site URL and Name in a custom plugin I am developing.

My research has led me to believe this would work:

$envVar = craft()->config->get('environmentVariables');
$siteUrl = $envVar['siteUrl'];
$siteName = $envVar['siteName'];

But in practice this hasn't worked. Does anyone know the correct way?

In Craft 3 you can do this:
use craft\helpers\UrlHelper;
UrlHelper::siteUrl();

Craft::$app->sites->currentSite->name;


Craft installer errors I'm trying to install craft on my local machine (OSX Mavericks). It gets stuck on a screen with "Oops." and a spinning icon.

The requirements checker says all is good. I have InnoDB and MySQL 5.7.3 installed. I get a list of errors in craft.log:

2014/09/22 15:40:54 [warning] [application] Skipping record /Library/WebServer/Documents/lays2/craft/app/records/BaseRecord.php because it’s abstract or an interface.

2014/09/22 15:40:55 [error] [system.db.CDbCommand] CDbCommand::execute() failed: SQLSTATE[42000]: Syntax error or access violation: 1171 All parts of a PRIMARY KEY must be NOT NULL; if you need NULL in a key, use UNIQUE instead. The SQL statement executed was: CREATE TABLE `craft_assetfolders` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY NULL,
`parentId` INT(11) NULL,
`sourceId` INT(11) NULL,
`name` VARCHAR(255) NOT NULL,
`path` VARCHAR(255) NULL,
`dateCreated` datetime NOT NULL,
`dateUpdated` datetime NOT NULL,
`uid` CHAR(36) NOT NULL DEFAULT 0
) ENGINE=InnoDb DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci.

2014/09/22 15:40:55 [error] [exception.CDbException] exception 'CDbException' with message 'CDbCommand failed to execute the SQL statement: SQLSTATE[42000]: Syntax error or access violation: 1171 All parts of a PRIMARY KEY must be NOT NULL; if you need NULL in a key, use UNIQUE instead' in /Library/WebServer/Documents/lays2/craft/app/framework/db/CDbCommand.php:358

There's also a Stack Trace.

Any ideas? Thanks in advance.

If I had to guess, they made a chance in MySQL 5.7 that's breaking Craft and you've found a bug.  We haven't done any 5.7 testing, since it's not officially released, yet, but I'll install it and do some verification and update this answer.

Update:

This was a bug in Craft when using MySQL 5.7 and has been fixed for the next (post 2.2.2588) release.


phpmailer Exception while using Pixel & Tonic contact-form plugin Link to Github repository for plugin: https://github.com/pixelandtonic/ContactForm

Being given an error by the plugin where it is interpreting my Twig variable literally as a string instead of what the variable is representing. I am looking for a way to fix this using the current set-up but having an alternate setup is fine as well. Also for reference, I have followed the guidelines on the README in regards to changing the craft/config/contactform.php file. Much appreciated for the help!

This is my code:

{% macro errorList(errors) %}
{% if errors %}

        {% for error in errors %}

{{ error }}

        {% endfor %}

{% endif %}
{% endmacro %}

{% from _self import errorList %}

<form method="post" action="" accept-charset="UTF-8">
    {{ getCsrfInput() }}
    <input type="hidden" name="action" value="contactForm/sendMessage">

Email to {{default.defaultcontactreason}}

            <input type="hidden" name="toEmail" value="{{ '{{default.defaultContactEmail}}'|hash }}">{{default.defaultContactEmail}}

    {% for category in craft.entries.section('Contacts') %}

Email to {{ category.contactReason }}

            <input type="hidden" name="toEmail" value="{{ '{{category.contactEmail}}'|hash }}">{{category.contactEmail}}

    {% endfor %}

Your Name

    <input id="fromName" type="text" name="fromName" value="{% if message is defined %}{{ message.fromName }}{% endif %}">
    {{ message is defined and message ? errorList(message.getErrors('fromName')) }}

Your Email

    <input id="fromEmail" type="text" name="fromEmail" value="{% if message is defined %}{{ message.fromEmail }}{% endif %}">
    {{ message is defined and message ? errorList(message.getErrors('fromEmail')) }}

Subject

    <input id="subject" type="text" name="subject" value="{% if message is defined %}{{ message.subject }}{% endif %}">
    {{ message is defined and message ? errorList(message.getErrors('subject')) }}

Message

    <textarea rows="10" cols="40" id="message" name="message">{% if message is defined %}{{ message.message }}{% endif %}</textarea>
    {{ message is defined and message ? errorList(message.getErrors('message')) }}

    <input type="submit" value="Send">
    <input type="hidden" name="redirect" value="{{siteUrl}}Contacts">
</form>

Looks like you've got some nested escape tags in Twig, which is a no-no.

value="{{ '{{category.contactEmail}}'|hash }}"

You just need to use:

value="{{ category.contactEmail|hash }}"


SproutForms: "an unknown error occurred" in entries template chart When viewing the charts in the entries template of the SproutForms plugin, I receive an "an unknown error occurred" error message.

In the console, I see this:

Failed to load resource: the server responded with a status of 500 (Internal Server Error): https://domain.com/index.php?p=admin/actions/sproutForms/charts/getEntriesData

Any clue what's going on here?

Update: This issue has been fixed in Sprout Forms v2.3.0, which also added Entry Status workflows and support for front-end Entries, Categories, and Tags relations fields ;-)

--

The issue you’re running into with the Sprout Forms chart is due to your PHP version.  We have it on our list and it should be fixed in the next release.  Until we get that release, the way to fix the issue is to upgrade your PHP version to something higher than PHP 5.4


How do I output the value of a field from a Category selected from a Matrix? I'm new to craft so this is a bit newbie question.

I have a category group with a set of categories, each category has a plain text field associated with it. The category group is then used as a field in a Matrix so the user can select one of the categories in the group. Basically all I want to do is list the plain text field from the selected category onto the page.

I tried working something out from https://craftcms.com/docs/relations (Going through a matrix section) but I just kept breaking everything. Any assistance would be appreciated!

Thanks.

Without knowing what your field handles are, this is the gist of how you’d do it:

{#
   Loop through each block within your Matrix field,
   assigning them to a `block` variable:
#}

{% for block in entry.myMatrixField %}

    {#
       Loop through each category within this Matrix block,
       assigning them to a `category` variable:
    #}

    {% for category in block.myCategoriesField %}

        {#
           Output the plain text field value:
        #}

        <p>{{ category.myPlainTextField }}</p>

    {% endfor %}

{% endfor %}


How can I loop through the values of a drop down within a SuperTable? I a musing a front-end form to create an entry in the CP. In my form I am using a SuperTable that contains two fields/blocks.

Size - [text input]
Measurement - [dropdown]

Here is what my template looks like:

    <input type="hidden" name="fields[lotSize]">
    <input type="hidden" name="fields[lotSize][new1][type]" value="1">

            Lot Size
            <input type="text" class="form-control" name="fields[lotSize][new1][fields][size]">

        Measurement
        <select name="fields[lotSize][new1][fields][measurement]">
            {# Loop through the values instead of hard-coding #}
            <option value="">Select</option>
            <option value="squareFeet">Square Feet</option>
            <option value="acres">Acres</option>
        </select>

I've been reading through Updating a Super Table field from a front end form and have tried this:

{% set fieldHandle = 'lotSize' %}
{% set field = craft.fields.getFieldByHandle(fieldHandle) %}
{% set blocktype = craft.superTable.getSuperTableBlocks(field.id)[0] %}

...But I'm not sure where to go next to get to the measurement field.

I have attached a screenshot of my CP page to help show what I am trying to accomplish. Thank you for any suggestions!

You'll likely want to do something like this:

{% for fieldtype in blocktype.getFieldLayout.fields %}
    {% set field = fieldtype.field %}

    Handle: {{ field.handle }}

    {% if field.type == 'Dropdown' %}
        {% for option in field.settings.options %}
            Label: {{ option.label }}
            Value: {{ option.value }}
        {% endfor %}
    {% endif %}
{% endfor %}

Essentially, this loops through all the sub-fields in your Super Table field, and for each field, you can make any sort of conditional you like in order to handle each fields content.


Pass value in form using the amforms plugin I've created a (apply for a job) form using amforms.
I'm using this form for multiple jobs. Whenever someone replies with this form, I want to pass the job name in the form.

I've tries many thing but can't find a solution.

Anyone?

I presume the title of the entry is the name of the job. So if that's the case, just add a hidden input in the form and add the entry's title to the value.

<input type="hidden" name="fields[jobTitle]" value="{{ entry.title }}">

Then make sure to create a 'jobTitle' text field in the CMS and attach it to that form.