Sprout Forms: returning error question With Sprout Forms is it possible to return an error message if a form submission is bouncing back because unique values are expected?

For example, if I have a custom HTML form called signup I would expect it to throw back an object called signup but signup is not defined. Also tried form.getErrors() but this also returns empty.

Sample form code:

<form class="form form--signup" method="post">

    {{ getCsrfInput() }}
    {% set form = craft.sproutForms.form('signup') %}

    <input type="hidden" name="action" value="sproutForms/entries/saveEntry">
    <input type="hidden" name="handle" value="{{ form.handle }}">
    <input type="hidden" name="redirect" value="{{ craft.request.url }}#newsletter">

    <input type="email" name="fields[email]" id="ft_email" placeholder="Email address" class="form__input" required>
    <button type="submit" class="button btn btn--box btn--send">Send </button>
</form>

Apologies - resolved. Case sensitivity issue with variable (signUp not signup)


Site moved to new server - Error 500 I inherited a site running craft and I was asked to move it to my server to host it. The other developer zipped the files and made a database dump for me.
Usually, when I move a site, they have Cpanel access, so I just move and it works with a few tweaks, but they didn't have Cpanel and I am in over my head.
I Know I haven't provided a lot to go on, as I don't know what you need to help me. What is a common thing overlooked? I can post error messages if it helps. The main one I get is the following:
[15-Sep-2020 13:22:01 UTC] PHP Warning:  Use of undefined constant _DIR_ - assumed '_DIR_' (this will throw an Error in a future version of PHP) in /home/client/public_html/index.php on line 7

[15-Sep-2020 13:22:01 UTC] PHP Warning:  require_once(./home/client//vendor/autoload.php): failed to open stream: No such file or directory in /home/client/public_html/index.php on line 11

[15-Sep-2020 13:22:01 UTC] PHP Fatal error:  require_once(): Failed opening required './home/client//vendor/autoload.php' (include_path='.:/opt/cpanel/ea-php74/root/usr/share/pear') in /home/client/public_html/index.php on line 11

The main issue is that the require_once CRAFT_VENDOR_PATH.'/autoload.php'; fails.
This is because the DIR constant, used to compute the value of CRAFT_BASE_PATH and CRAFT_VENDOR_PATH is undefined.
Try to define the value of the DIR constant so that CRAFT_VENDOR_PATH points to the vendor directory in your Craft project (it hard to help you further without knowing your directory structure).
Once this is done, as Jamie mentions, you must use composer to install Craft dependencies.
Did you make any changes to the index.php file of is it just like it was in the archive you received from the other dev?


Grouping a large number of entries I have imported data with 18000+ entries. It's a list of product models with brands associated to each. The product model is being used as the title and the brand field is plain text.

There are approximately 140 brands which I need to output as a dropdown.

I can't output this many entries and then try and group (and order them) on the template as it crashes the page.

This is code that would work if it didn't crash the page (and would take minutes to load the page even if it didn't).

{% set allEntries = craft.entries.section('solarWaterHeaterModels').order('brand asc').limit(null).find() %}

{% set allEntriesByBrand = allEntries|group('brand') %}

{% for brand, entriesInBrand in allEntriesByBrand %}

    {% for entry in entriesInBrand %}
        {% if loop.index == 1 %}
            <option value="{{ entry.brand }}">{{ entry.brand }}</option>
        {% endif %}
    {% endfor %}

{% endfor %}

Can anyone offer some guidance on how to approach this please?

Many thanks

First, based on your example code I don't think you actually need to loop on the entries – you could simply group them on the brand name, and then loop on the keys for the grouped array (the keys would be your brand names):

{% set brands = allEntries|group('brand')|keys %}

{% for brand in brands %}
     <option value="{{ brand }}">{{ brand }}</option>
{% endfor %}

So that's a slight optimization, but you'd still be pulling ~18k entries to print ~140 brand names and I'm not sure the above wouldn't still crash your server – so ideally you should probably use a different strategy altogether.

If you're comfortable w/ writing a little PHP, I'd suggest you scaffold a custom plugin – make sure that the Variables component is included, and add something like the below to the variables/YourPluginHandleVariable.php class:

public function getBrands()
{
    $query = craft()->db->createCommand();
    $query->selectDistinct('field_brand');
    $query->from('content');
    return array_filter($query->queryColumn());
}

In your template, you'd use this like so:

{% set brands = craft.yourPluginHandle.getBrands() %}

{% for brand in brands %}
     <option value="{{ brand }}">{{ brand }}</option>
{% endfor %}

Be sure to replace yourPluginHandle and YourPluginHandleVariable with the actual handle for your plugin.

Note that I haven't actually tested the above w/ as many as +18k rows, so even a distinct select query might not be performant enough. Of course, you can always cache the result.


The Definitive Guide to Extending Twig in Craft CMS So Craft's implementation of Twig is already very powerful and suitable to most common tasks. The Craft Docs already provide a great intro into using Twig and the handy extensions provided by Craft:

Craft Templating Overview
Craft Twig Primer
Craft Full Templating Reference

But what about when you need to go further and build in some sweet custom functionality?

This question serves to be a starting point that summarises all the different ways to extend Twig with custom functionality, including:

Filters, functions, objects, macros and statements – when to use which
Creating a custom Twig filter
Accessing variables and functions in a plugin
Creating a custom global function
Creating a custom global object
Creating a custom statement (or "logic tag")
Creating a custom operator
Calling a plugin service class from Twig
Making custom database calls from Twig
Post-processing HTML after Twig has finished rendering
Changing Twig settings

To encourage input, this is a community wiki post. Any user with at least 100 reputation points may contribute.

Functions, filters, objects, macros and statements – when to use which

A function is one of the simplest constructs in Twig – it takes one or more inputs and returns a single output:

{{ round(42.9) }} will output 43

These are best used for simple, commonly used operations that generate or transform data, such as a Lorem-Ipsum generator: {{ loremIpsum(50) }}. But note that functions are often better grouped into an object to prevent name collisions (see below).

A filter is almost identical to a function, except that it offers a different syntax, which can be more readable when chaining several filters together (they read in progressive order):

{{ 1000000 | number }} will output 1,000,000
{{ 1000000 | number(false) }} will output 1000000
{{ 'ABC' | lower | replace('c', 'd') }} will output abd

It also provides an easy way to wrap around a larger block of text:

{% filter upper %}
    This text becomes uppercase
{% endfilter %}

Note that you can also do this with a function, but it requires an additional line:

{% set myText %}
    A quick brown fox
{% endset %}
{{ filterCurseWords(myText) }}

Use a filter when:

It might be necessary to place it in a chain along with other filters
It might be necessary to place around larger blocks of text/content

A global variable is one accessible to all templates in your project automatically:

{{ siteName }}

A global object is also accessible to all templates in your project, but can contain variables, functions or both:

{{ currentUser.friendlyName }}
{{ currentUser.can('accessCp') }}

Objects provide a good way to neatly group variables and functions and prevent collisions.

A Twig statement (sometimes called a "logic tag") is used to designate the flow of logic and may only execute the content inside based on certain circumstances.

{% cache %}
    {% for block in entry.myMatrixField %}

{{ block.text }}

    {% endfor %}
{% endcache %}

Note that caching would not work as a filter, because the content inside a filter is always executed prior to being passed into the filter. By implementing the cache tag as a statement, it is able to only execute the content inside when appropriate.

Finally, it's worth mentioning macros. They assist with reusing snippets of content or HTML in multiple places. Mijingo has written a great tutorial that explains macros in Craft.

{% import "forms.html" as forms %}
{{ forms.input('username') }}

Note, however, that the functionality of macros can sometimes be replicated via a simple include, with less code and more clarity:

{% include 'mySnippet' with { enabled: true } %}

Creating a custom Twig filter

{{ myVariable | myFilter }}

More content to come here. Feel free to contribute some instructions if you're able.

Accessing a plugin's variables and functions

{{ craft.myPlugin.myVariable }}
{{ craft.myPlugin.myFunction() }}

More content to come here. Feel free to contribute some instructions if you're able.

Creating a custom global function

{{ customFunction() }}

More content to come here. Feel free to contribute some instructions if you're able.

Creating a custom global object

{{ browser.version }}
{{ browser.isMobile() }}

More content to come here. Feel free to contribute some instructions if you're able.

Creating a custom statement (logic tag)

{% devOnly %}
    ...output some debugging info here...
{% endDevOnly %}

Refer to http://twig.sensiolabs.org/doc/2.x/advanced.html#tags

More content to come here. Feel free to contribute some instructions if you're able.

Be aware that sometimes the functionality can be achieved by creating a filter instead of a statement:

{% filter uppercase %}
    A quick brown fox
{% endfilter %}

However the benefit of a statement is that the code inside is not run unless the statement permits it, whereas in a filter the code is always run, and then later sent to the filter.

Creating a custom operator

{{ ! true }}

Refer to http://twig.sensiolabs.org/doc/2.x/advanced.html#operators

More content to come here. Feel free to contribute some instructions if you're able.

Calling a plugin service class from Twig

Under normal circumstances, Twig templates only have access to a plugins Variable Classes and not their Service Classes. But using a simple PHP trick, you can pass all calls on transparently:

Twig > Variable Class > Service Class

// craft/plugins/YourPlugin/variables/YourPluginVariable.php
class YourPluginVariable
{
    /**
     * If function is not found in this class, go find it in service class
     */
    function __call($method, $arguments) {
        return call_user_func_array(array(craft()->YourPlugin_YourService, $method), $arguments);
    }
}

Be sure to rename YourPlugin and YourService to reflect the names of your plugin and service class.

Making custom database calls from Twig

{{ craft.myPlugin.fetchUserCount() }}

Firstly this requires a custom plugin.

In Craft, database calls need to be made via a service class, however because you can only access variable classes from Twig, you need to pass one to the other. (See the point above for a clean way to transparently pass calls from a variable class to a service class.)

Twig > Variable Class > Service Class > Database Query

More content to come here. Feel free to contribute some instructions if you're able.

Post-processing HTML after Twig has finished rendering

More content to come here. Feel free to contribute some instructions if you're able.

Changing Twig settings

More content to come here. Feel free to contribute some instructions if you're able.


Pass aspect ratio as variable into imager I use imager to transform images and I want to pass the image ratio as a variable:

{% set customRatio = 1/1 %}

{% set image = craft.assets().one() %}
{% set transformedImage = craft.imager.transformImage(image,
    { width: 1000, ratio: customRatio })
 %}

This does not work. There is something wrong with how it is passed along. If I pass it as a string: {% set customRatio = '1/1' %}. It doesn't work either. (No errors in both cases).

But when I write it directely into the imager markup like this:

{% set image = craft.assets().one() %}
{% set transformedImage = craft.imager.transformImage(image,
    { width: 1000, ratio: 1/1 })
 %}

Then it works. But why?

Your variable assignment is wrong. {% set customRatio == 1/1 %} should be {% set customRatio = 1/1 %}.


Does the cache tag behave differently for Mobile vs Tablet vs Desktop? Are different cache saved for Mobile / Tablet / localisations or do we have to take care of this?

I.e. if i use:

{% if craft.request.isMobileBrowser() %}

will the response be cached for desktop users as well?

Craft makes no distinction whether it's caching for mobile, tablet, desktop, etc., so it'll need to be taken care of on the template end.

You can easily do that with the "using key" parameter of the {% cache %} tag, though.

{% if craft.request.isMobileBrowser %}
    {% set cacheKeyType = 'mobile' %}
{% else %}
    {% set cacheKeyType = 'desktop' %}
{% endif %}

{% cache using key "page-header-" ~ cacheKeyType %}
    ....
{% endcache %}


How do I loop through two sections as one set I'm trying to loop through two separate channels, but combined together. And then just check which channel the entry belongs to in the loop to display it correctly. This is how I had it done in EE, but I can't seem to find a way with Craft.

{exp:channel:entries channel="press|in-the-press" orderby="date" dynamic="no" limit="10"}

According to the Craft docs, the section parameter takes a "section handle, an array of section handles, or a SectionModel object". So this should work:

{% set entries = craft.entries.section(['press', 'in-the-press']).limit(10) %}

{% for entry in entries %}
    {{ entry.title }}
{% endfor %}


Relationship all to all I'm trying to pair all my custom product entries to all my dealers with 2 extra fields per product: price per day and price per week. The condition is that all my products are paired to all my dealers in advance. So when adding a new dealer I would like to show a table or some sort listing with all my products with the 2 fields in different columns.

I've tried to do this with a static table (Super table plug-in) and sort of succeeded:
I made a new field for my dealers with each field named after a product and the field type set to a normal table with 2 columns for my 2 fields. In my templates I would query based on my product name and match the correct row from my Super table field, but it just seems error prone and not managable.

Does anyone have any advice on how to implement this in a correct way?

I'm not sure I completely understand what you're trying to achieve, but maybe the Many to Many Field Type plugin does the trick?


How can I let JS UI building to field type plugin? I want to use like owl carousel JS UI in front.

Here's carousel a link!

It has some option can setting.

I want to create a own fields type in admin, can setting this option and show this UI in front view.

You can quite easily set up asset and text fields to be fed into a owl-carousel template. Or you could create a matrix in which one of the blocks would automatically produce owl-carousel html and again pass asset and text fields in the matrix block to produce the images and captions.

If you want further assistances try to be a little more specific in your question.


Using Amazon S3 with Craft 2.x in Frankfurt region According to this post it's not possible to use Craft 2.x with Amazon S3 within the Frankfurt region. As Craft 3 is still not near release it would be nice to have some sort of a fallback solution. For us that issue is a major drawback ... and I can imagine for other folks from the EU region too.

The AWS Frankfurt region (eu-central-1) does only support the "new" v4 signature. Craft 2 uses the v2 signature of the S3 API and that's not easy to fix.

Ireland (eu-west-1) should be good enough in terms of latency.


Plugin migration - calling services help In my Craft 2 plugin my initial init function looked like:

public function init()
{
    parent::init();

    if(!extension_loaded('imagick')) {
        PdfThumbnailerPlugin::log("imagick library not found - cannot make pdf thumbnails" , LogLevel::Warning);
        return;
    }

    craft()->on('entries.saveEntry', function(Event $event) {
         craft()->pdfThumbnailer_saveEntry->setThumb($event);
    });

    craft()->on('assets.saveAsset', function(Event $event) {
        PdfThumbnailerPlugin::log("on save asset");
        craft()->pdfThumbnailer_saveAsset->checkAsset($event);
    });

}

I cannot understand (due to lack of devchops) or find an example of how to call my functions (which were in service files) in Craft3.

I can see the constants used in the new style 'listener' but have no idea what or where these are referenced in the v3 docs.

    // Register our site routes
    Event::on(
        UrlManager::class,
        UrlManager::EVENT_REGISTER_SITE_URL_RULES,
        function (RegisterUrlRulesEvent $event) {
            $event->rules['siteActionTrigger1'] = 'pdfthumbnailer/save-entry';
            $event->rules['siteActionTrigger2'] = 'pdfthumbnailer/save-asset';
        }
    );

My plugin in craft 2 would create a thumbnail from the first page of a PDF asset.

UPDATE:
SO i eventually made some progress with :

Pdfthumbnailer::$plugin->SaveEntry->setThumb($event);

Except this kept saying it could not find service method:

Getting unknown property: joomkit\pdfthumbnailer\Pdfthumbnailer::SaveEntry

It turns out that the method 'SaveEntry' only was found when named 'saveEntry'. Why would this be the case? (excuse pun)

I can't answer the question fully without seeing your plugin code, but I'd suggest you generate your plugin scaffolding with pluginfactory.io to see how it all fits together.

It's also helpful to look at a existing plugin that works; here's one I wrote that's pretty simple, and should be easy to follow: FastCGI Cache Bust

Roughly, you'd do something like:

PluginClass::getInstance()->serviceName->methodName();

Or if you do it the pluginfactory.io way:

PluginClass::$plugin->serviceName->methodName();


Import Stripe subscriptions into Commerce 3 Is there a straight-forward way to import Stripe subscriptions into Commerce 3? I had hoped FeedMe or similar would do it, but it seems not: https://github.com/craftcms/feed-me/issues/472

Any help/advice greatly appreciated.

Craft are hoping to release this as an update to Commerce in the next month or so!


Can't find S3 bucket using Craft Pro in trial mode I am using the Craft Pro trial version and I want to use S3 for my Assets.  However, I enter my credentials but the refresh button does not show my bucket.  Also, when I try the refresh with wrong credentials it shows the error message but with correct it just doesn't show anything. I tried to connect to by bucket with other tools and was successful so this is why am thinking that is a restriction on the trial version of Pro.

So is it a Craft trial issue? Are you allowed to connect to S3 in trial version of Craft Pro?

The bucket you're trying to list is probably in the Frankfurt S3 region. The 3rd party library used in Craft 2.x for Amazon S3 support does not support Signature Version 4 that Frankfurt region requires, so you won't be able to use buckets in that region, as outlined in this answer

Craft 3.0 will not have this limitation, however.


Homepage template / queries I might be over-engineering this a bit, but I'm looking for a clean way to set up my homepage, for as few database queries and maintaining a DRY setup. The homepage is:

Hero introduction

Fields in a homepage single.

News & Events

Simple blog-like query

And then the two parts I'm confused about. Both of these are pulled from other singles.

About Us summary
Membership info

Is it fine to just query these pages individually? It feels so over the top to do something like

{% set aboutQuery = craft.entries().section('about') %}
{% set aboutPage = aboutQuery.all() %}
{% for page in aboutPage %}

{{ page.title }}

{{ page.summary }}

{% endfor %}

I'm sure this is a fairly common setup, so I just want to know what other people do in cases like this.

Maybe it feels over the top, cause you could simplify your small request to something like this:

{% for page in craft.entries.section('about').all() %}

{{ page.title }}

{{ page.summary }}

{% endfor %}

Or, if you just want to get the title and the summary of that one single - you could archieve this via:

{% set aboutPage = craft.entries.section('about').one() %}

{{ aboutPage.title }}

{{ aboutPage.summary }}


How do I export search results as a csv? I have set up a custom search of entries on a page in my Craft site which includes filters to filter the results.  I would like to be able to export these results (filtered or otherwise) as a CSV through a link on the page:
http://www.joycefdn.org/grants

Is there a way to do this?

You can just make link to a twig template to output a csv quite simply...just like any other template really, except it won't extend you layout etc. and will simply contain something like:

{%for result in results %}
    {{var1}},{{var2}},{{var3}} etc...
{% endfor %}

Depending on what sort of csv you're after and what you're going to do with the data, you may want to consider escaping the data as you output it:

http://twig.sensiolabs.org/doc/filters/escape.html

In terms of setting it up as a  link, your csv template could just accept the same search parameters passed through and essentially repeat the search and output the csv results as above.

I.e. in your original results page you could build the link to the CSV as

Get Results As CSV

And then in the csvmaker

{% set results = craft.entries.search(q).order('score') %}
...etc as above

But a lot depends on how you've built your search in the first place really.

If you want it to trigger an actual file download, then I've found that's pretty easy to do that on the front end with some JS, e.g. I use this:

https://stackoverflow.com/questions/19721439/download-json-object-as-a-file-from-browser/20343999


Option and notes fields after cart at checkout for order, not just line items My client has gift wrapping services but they apply to the entire order, not one single line item.

How would I add notes or custom fields to the entire order, at the shipping stage of checkout? is this possible without a plugin?

I tried to apply notes and giftwrapping options to the first line item by using the commerce/cart/updateLineItem form, on the cart.lineItems.first() but it didn't work. I presume that after the user proceeds to checkout the line Items no longer exist?

First, add a custom field to your orders, let's call it orderNotes.

Then, in any updateCart form, you can use an input with name="fields[orderNotes]" to set the value of that field.

(Line items persist on the cart until the end of checkout.  At that point they become a saved snapshot of those line items on the completed order.)

<form method="POST" >
       {{ getCsrfInput() }}
       <input type="hidden" name="action" value="commerce/cart/updateCart">
       <input type="text" name="fields[orderNotes]">
       ...etc


Uploaded assets using ftp, asset not displaying I uploaded and un-tar'ed a bunch of folders containing images under one of our local asset source folder.  After triggering the "Update Asset Indexes" tool, and waiting for its completion, my asset table is still blank.  Under "Assets", I can see all the new sub-folders but all are empty.  I checked the file and folder permissions on disk, all are ok.

Looking into the database, the "craft_assetindexdata" show all the file path, but the "recordId" column indicate "NULL".  Is there something else I need to trigger for this process to complete?

Using Craft Pro 2.3.2629

Thanks for your help.

Looks like you're getting an nginx gateway timeout error.  Here is some info on how you can increase the time limit.


Develop a plugin for outputting data in a loop I am looking to develop a plugin which out put the data in a loop Or that plugin would populate the array data with template tag. Could anyone please help me or share a doc link.

Thanks,

Please have a look at the "Template Variables" section of the documentation:
http://buildwithcraft.com/docs/plugins/variables

The template variables are the containers of data which you can access from your twig templates using craft.yourPluginName.yourPluginVariableFunctionName

Let's say you want to loop through 3 different items in an array from your Plugin. Your Plugin variables file might look like this:

<?php
namespace Craft;

class PluginNameVariable
{
    public function data()
    {
        return array('one', 'two', 'three');
    }
}

In your template you can now "fetch" this data like this - in a loop:

{% for item in craft.pluginName.data %}
    {{ item }}
{% endfor %}

Please not this code is not tested


Including two category slugs in entries’ URLs I have a section with two Categories fields, and I would like the entries’ URLs to include the slugs of the categories selected in each of those fields.

The Category Groups are:

mySection

Employees
Employers
Executives

myCategory

Vitality
Health
Safety
Career

So an entry that has “Employees” selected in the first Categories field, ad “Health” selected in the second Categories field should end up with the URL:

mywebsite.nl/employees/health/entrypage

How do I do this?

Set your section’s Entry URL Format to this:

{mySection.first.slug}/{myCategory.first.slug}/{slug}

mySection.first and myCategory.first will give you the first-selected category within those respective fields. Adding .slug after that will give you the slug of those categories.

If either of those category groups can have nested categories, you may want to change .first to .last, so the last-selected category’s slug makes it into the URL rather than the first one.

Category URLs

If you would like to make category URLs like this:

mywebsite.nl/employees/health

you will need to create a new Route in Settings → Routes, with the following URL pattern:

and point the route to whatever template you want to load when these URLs are matched.

Then from your template, you can fetch the actual category models like this:

{% set mySection = craft.categories({
    group: 'mySection',
    slug: matches[1]
}).first() %}

{% set myCategory = craft.categories({
    group: 'myCategory',
    slug: matches[2]
}).first() %}

{# Make sure the URL contained valid slugs #}
{% if not mySection or not myCategory) %}
    {% exit 404 %}
{% endif %}

From there you can do whatever you want with them. For example, you can display every entry that is related to both of them:

{% set entries = craft.entries({
    relatedTo: ['and', {targetElement: mySection}, {targetElement: myCategory}]
}) %}

{% for entry in entries %}
    ...
{% endfor %}

You can repeat all of those steps to do a similar thing for URLs that just have one category in them as well (just omit the second route token, and ignore all the myCategory stuff in the example code).


VAT not being removed when adding a number to businessTaxID Folks, just wondering if anyone has further knowledge on Craft Commerce's Tax Rates? I am setting up my first commerce store and the client requires that if the customer is buying from the EU, and has a valid VAT number, they then do not pay the 20% VAT.

I have my Tax Categories, Zones and Rates set up, and have checked the option to 'Don't apply this tax when the shipping address has a valid VAT ID' - however when it comes to the payment screen after putting in a VAT number in the businessTaxId input on the Shipping Address screen, it does not deduct the 20% added VAT. It does pick up the correct Tax Zone as I can see it is EU Tax that has been added, it is just not deducting when I enter a VAT ID.

Just wondering is there something else that I would need to be covering first before this works? Apologies if this is a little too vague.

I am currently running the latest version of Craft & Craft Commerce, and working from the base files that you get when you download.

Edit
I have just noticed this error in the commerce.log file if it helps matters

[Forced] Communication with VAT API failed: MS_UNAVAILABLE

Commerce, by default, uses this library for VAT validation.

That library is just a wrapper for a European SOAP endpoint for these types of things at http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl

The error code MS_UNAVAILABLE that endpoint can return says:

  The Member State service is unavailable, try again later or with another Member State;

So I'm guessing an invalid member state was selected, or they are having some technical difficulties on their end.


Is there any danger to Craft from upgrading from PHP 5.5 to PHP 5.7? As of July 2016, PHP branch 5.5 is unsupported. The PHP version my server currently is running is 5.5.9 which implies that the server will not receive any security updates going forwards.

I'm told that Craft recommends using 5.7. Is there any danger that parts of my website may stop working if the PHP is updated?

Don't worry, you should be fine.

Craft currently supports a minimum of PHP 5.3. Any higher version of PHP is also compatible.

When Craft 3 ships (late 2016 / early 2017), it will require a minimum of PHP 5.6.

Side note... If you're about to upgrade PHP, I highly recommend switching to PHP 7. The performance boost is notable, and should speed up your site by about 50-80%!


Issue upgrading Craft 2 to 3 I'm attempting to upgrade my Craftsite from 2 to 3, which I have done so, however I seem to be getting a few deprecation errors.

The first error is:

  The auto-generated validation key stored at
  /Users/User/My-Site/craft/storage/runtime/validation.key has been
  deprecated. Copy its value to the “securityKey” config setting in
  config/general.php.

To which I assumed I should just add 'securityKey' => 'xxxxxx', but the error hasn't gone.

The second error is:

  The environmentVariables config setting has been renamed to aliases.

Which to be honest im not sure how to fix.

Any suggestions?

Those aren't so much errors as deprecation messages, meaning you should fix them sometime before Craft 4 comes out where they'll be going away and become real errors for you. :)

  To which I assumed I should just add 'securityKey' => 'xxxxxx', but the error hasn't gone.

They won't go away automatically.  Go to yoursite.com/admin/utilities/deprecation-errors, then you can click the "x" for the message on the far right to clear it.  It won't come back again if it has been fixed.

  The environmentVariables config setting has been renamed to aliases.

You'll want to convert your old environmentVariable to use the new aliases syntax.  You can see examples of that here:

https://docs.craftcms.com/v3/configuration.html#aliases


How to override UserController.actionLogin or the login form template in Craft 3? Hi I'm trying to build a custom authentication plugin for an organization, and I'm having a hard time figuring out how to override the craft\controllers\UserController.actionLogin method. I tried hooking into AuthenticateUserEvent however this is fired after craft has already checked to see if a user exists. For our purposes we want to skip that entirely and solely use ldap to authenticate users. Here's ideally what I need to do.

Check if the user with the given creds exists in ldap.
If so, and they don't exist in craft, create a new user with those same creds.
Forward the creds of the new or existing user to craft\controllers\UserController.actionLogin to finish logging them in to the admin panel.

Essentially I need to override that controller action and I can't find in the docs how to go about doing that. It also doesn't seem possible to override the login form template either? I realize if I could override that template then I can just call my own controller action.

Thanks for any help you can give!

Alright so I was actually misunderstanding how modules work with craft and yii. The init function in your module actually fires before crafts core controllers do, so you could use that to do whatever you need to do before the request continues on. I'm coming from WordPress so I thought I had to 'hook' into something. Here's an example of how you would override the login action on a post request. In the real world you would probably want to extract this logic to a Service but for the sake of clarity I'm just putting it in the init function here.

So, I guess the way to override any core controller is to look for that url or action in your modules init function and do whatever you need to do to override it.

namespace ldap;

use Craft;
use craft\elements\User;

class LdapModule extends \yii\base\Module
{
    public function init()
    {
        Craft::setAlias('@ldap', __DIR__);

        if (Craft::$app->getRequest()->getIsConsoleRequest()) {
            $this->controllerNamespace = 'ldap\\console\\controllers';
        } else {
            $this->controllerNamespace = 'ldap\\controllers';
        }

        parent::init();

        $isActionRequest = Craft::$app->getRequest()->getIsActionRequest();
        $isLoginAttempt = Craft::$app->getRequest()->getFullPath() === 'admin/actions/users/login';
        $isPostRequest = Craft::$app->getRequest()->getIsPost();

        if ($isLoginAttempt && $isPostRequest && $isActionRequest) {
            //...Ldap functionality and creating/activating new user if need be goes here. The request
            // will then continue on to crafts core UserController to log them in.

            // As an aside, if you want to create a user programmatically to login
            // here's more or less how to do it.
            // @reference craft\controllers\UsersController.actionSaveUser
            $user = new User();
            $user->email = 'wolf@inyourface.com';
            $user->username = 'wolf';
            $user->firstName = 'Wolf';
            $user->lastName = 'Face';
            $user->pending = true;
            $user->newPassword = 'secret';
            if ($user->validate(null, false)) {
                Craft::$app->getElements()->saveElement($user, false);
                Craft::$app->getUsers()->activateUser($user);
                Craft::$app->getUserPermissions()->saveUserPermissions($user->id, ['accessCp']);
            }
        }
    }
}


Using getCriteria with a custom element type I've setup a custom element type for badges for a system I'm building, but I've run into some trouble trying to query for badges using craft()->elements->getCriteria(ElementType::Badges_Badge);, however I'm getting an error saying 'Undefined class constant 'Badges_Badge', but when I loop through all element types using getAllElementTypes() I see an entry for 'Badges_Badges', and I'm able to add and edit badges in the cms.

Is it impossible to query for custom elements using getCriteria, or am I missing something more fundamental?

Fixed it for now by including a custom enum class in the base plugin file:

abstract class CustomElementType extends BaseEnum
{
    const Badges_Badge = 'Badges_Badge';
}

and then querying for the custom element in the plugin using craft()->elements->getCriteria(CustomElementType::Badges_Badge);


How to programmatically add fields to matrix blocks? I am easily able to add a Matrix. I am also easily able to add a BlockType to that matrix. → I am fine so far.

But I have no clue what I am missing when I try to add fields to my blocks using the following example (excerpt from a custom plugin).

/**
 * Performs any actions that should occur after the plugin is installed.
 */
public function onAfterInstall() {
    //  create new group
    $fieldGroup = new FieldGroupModel();
    $fieldGroup->name = 'Awesome Field Group';
    //  save group
    craft()->fields->saveGroup($fieldGroup);

    //  create matrix field
    $matrixField = new FieldModel();
    $matrixField->handle = 'myMatrixField';
    $matrixField->name = 'Awesome Matrix';
    $matrixField->type = 'Matrix';
    $matrixField->required = true;
    $matrixField->translatable = true;
    $matrixField->groupId = $fieldGroup->id;
    //  save matrix field
    craft()->fields->saveField($matrixField);

    //  create block type
    $blockType = new MatrixBlockTypeModel();
    $blockType->handle = 'myAwesomeBlock';
    $blockType->name = 'Awesome Block';
    $blockType->fieldId = $matrixField->id; //  also craft()->fields->getFieldByHandle('myMatrixField') possible

    //  save it
    if (craft()->matrix->saveBlockType($blockType)) {

        //  UNTIL HERE EVERYTHING WORKS PRETTY FINE.

        //  on saveField() in fields service the given field's context value is ignored because it's overwritten with "craft()->content->fieldContext"
        //  so, after saving the field's context is "global", but we want something like "matrixBlockType:<id>"
        //  --> temporarily change this value to ensure we cann passe the block type id
        $tmp = craft()->content->fieldContext;
        craft()->content->fieldContext = 'matrixBlockType:' . $blockType->id;

        //  create field
        $field = new FieldModel();
        $field->handle = 'myTestField';
        $field->name = 'Awesome Field';
        $field->type = 'PlainText';
        $field->required = true;
        $field->translatable = true;
        //$field->context = 'matrixBlockType:' . $blockType->id;
        //  … last line is commented out because Craft ignores this value --> see implementation of FieldsService::saveField();

        //  save field
        craft()->fields->saveField($field);

        //  FIELD IS ADDED TO DATABASE BUT I CAN'T SEE IT IN MY MATRIX BLOCK

        //  restore original value of "craft()->content->fieldContext"
        craft()->content->fieldContext = $tmp;
    }
}

I hoped this is enough to add fields to block types. But as you can see in the screenshot below my "Awesome Field" is missing. :(

When adding this field manually in Craft's admin panel the field definitions in my database look exactly the same. So, any other important step is missing here. I have no idea which one.

What do I have to do to add fields to matrix blocks?

I hope someone can lead me into the right direction. Thanks in advance. :)

I'm assuming that you're attempting to create the Matrix, with one or more blocks each containing one or more fields, from scratch? I.e. you're not simply trying to populate content into an already defined Matrix?

Going off of that assumption:

PS: Sorry, this code is not based on your code - I simply took working code from one of my other projects.

// Create a field-group to store our Matrix in
$fieldGroup       = new FieldGroupModel();
$fieldGroup->name = 'My Field Group';
craft()->fields->saveGroup($fieldGroup);

// Create the matrix-field itself
$field          = new FieldModel();
$field->groupId = $fieldGroup->getAttribute('id');
$field->name    = 'My Matrix';
$field->handle  = 'myMatrix';
$field->type    = 'Matrix';

// Create a rich-text field which we will need later
$textField = ['name' => 'Text Field',
              'handle'       => 'label',
              'required'     => TRUE,
              'instructions' => '',
              'type'         => 'RichText',
              'typesettings' => ['configFile'            => 'Standard.json',
                                 'cleanupHtml'           => 1,
                                 'purifyHtml'            => 1,
                                 'columnType'            => 'text',
                                 'availableAssetSources' => '',
                                 'availableTransforms'   => '']];

// Define block-types for our Matrix-field
$blockTypes = ['new1' => ['name'   => 'My text field',
                          'handle' => 'myTextField',
                          'fields' => ['new1' => $textField]];

// Assign block-types to the Matrix-field
$field->settings = ['blockTypes' => $blockTypes];

// Finish the creation of the Matrix-field by saving it
craft()->fields->saveField($field)

I've had to adjust the code slightly to not give you the full 125 lines of code I use (mostly due to having a LOT of different block-types with a lot of different fields) - but hopefully you can get the gist of how it's working and solve your issue based on this :)

PPS: It seems like your code should work fine if you only tweak the order in which you do things slightly.

Create Field Group
Create Matrix Field
Define Block Fields
Create Block Types using defined Block Fields
Assign Block Types to Matrix Field
Save Matrix Field


Template backend entry form Can the backend entry form be adjusted by a template. It's not a very compressed view.
See this image

It would look a lot better if I can add some float:left; to parts.
See this image

You can use CP CSS to accomplish that...

  https://github.com/lindseydiloreto/craft-cpcss


Sorting Entries by category, from multiple category groups I'm struggling to figure out how to do this:

We have a bunch of entries in single a channel.
There are two category groups an entry can be assigned to, with multiple categories in each group.

We want to show all entries, but grouped in a nested format as follows:

Loop through Category Group One and get the entries grouped by each category.
Within each Group One category, loop through Category Group Two, to output entries grouped by Category Group Two categories.

I've found Relations hard enough to wrap my head around when I'm passing just a single category, but this has melted my mind completely.

For more specifics:

Category Group One has categories which are days of the week: Mon, Tue, Wed, Thus, Fri, Sat, Sun.
Category Group Two has categories that are activities: Walking, Running, Skiing

The output ought to be grouped something like:

Mon - Walking [entry title, entry title, entry title]
Mon - Running [entry title]
Mon - Skiing  [entry title, entry title]
Tue - Walking [...]
Tue - Running [...]
...

This is the code I've got closest with, but it's outputting duplicate entries within each day group...

{% set days       = craft.categories.group('day') %}
{% set activities = craft.categories.group('activity') %}

{% for day in days %}

        {{ day.title }}
        {% for activity in activities %}
            {{ activity.title }}
            {% for entry in craft.entries.section('attractions').relatedTo(
                'and',
                { targetElement: day },
                { targetElement: activity }
            ) %}
                    {% if loop.first %}
{% endif %}

{{ entry.title }}

                    {% if loop.last %}
{% endif %}
            {% endfor %}
        {% endfor %}

{% endfor %}

Finally figured it out, I had been so close! The following works:

{% set days       = craft.categories.group('day') %}
{% set activities = craft.categories.group('activity') %}

    {% for day in days %}

{{ day.title }}

        {% for activity in activities %}
            {% set entries = craft.entries.section('attractions').relatedTo(
              'and',
              { targetElement: day },
              { targetElement: area }
            ) %}

            {% if entries | length %}

{{ area.title }}

                {% for entry in entries %}

{{ entry.title }} {{ entry.startTime|date('H:i') }}

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


How can I load the templates from a module? I'm creating a module that contains some predefined templates. How can I load them directly out of the vendor folder? I've tried doing

Event::on(View::class, View::EVENT_REGISTER_SITE_TEMPLATE_ROOTS, function(RegisterTemplateRootsEvent $event) {
    if (is_dir($baseDir = $this->getBasePath().DIRECTORY_SEPARATOR.'templates')) {
        $event->roots[$this->id] = $baseDir;
    }
});

That part seems to be working, cause if I dump it, I get:

[
    'my-module' => '/app/modules/mymodule/src/templates'
]

In my module, I have a templates/test.twig

But when I do mysite.com/test, I still get a 404.

I've also tried a different approach, in the routes.php, I put:

'test' => ['template' => '@modules/my-module/test'],

Still nothing.

Is there something I could differently?

Answer from @robin-schambach

It's not possible the way you do it... or the way you are trying to do it
During site requests only templates from your template folder can be loaded
otherwise it would be a high security issue


Outputting siteUrl consumes next closing tag I'm running Craft Pro 2.3.2640.

Here is the code:

<span>{{ siteUrl }}</span>

Here is the output:

//localhost:3001/%3C/span%3E

The opening tag stays intact.

I am also struggling to use this variable with functions like "replace" when I need to parse the referral url.

Try to set the siteUrl in config/general.php like so.

return array(
    '*' => array(
    ),
    'localhost' => array(
        'siteUrl' => 'http://localhost:3001/',
    ),
);

And then apply your replace filter.

<span>{{ siteUrl|replace({'localhost:3001': 'mysite.com'}) }}</span>


Eager Loading Image Transforms In Plugin The craft docs on eager loading show you how to eager load image transforms in twig.

{% set entries = craft.entries({
   with: [
        ['coolImage', { withTransforms: ['transform'] }]
    ]
}) %}

However I can't figure out the syntax for achieving the same functionality within a plugin using the ElementCritereaModel.

I've made various attempts but they've all resulted in HUGE EXPLOSIONS of the php error variety.

$criterea->with = [
    "coolImage" => [
        "withTransforms" => ["transform"]
    ],
    "otherAssetField",
    "someCategoryField"
];

Of course above wouldn't work because you're switching between field slugs being keys/values in the array.

Using a similar syntax to the docs in twig would be:

$criterea->with = [
    "teaserImage",
    ["withTransforms" => ["peopleListing"]],
    "peoplePffice",
    "peopleCategories"
];

But that also results in explosions.

Help!!! (thanks)

I came across this post while searching for the same answer. Figured it out eventually. For future reference, the correct syntax in a (Craft 2) plugin would be:

$criterea->with = [
    ["coolImage", ["withTransforms" => ["transform"]]],
    "otherAssetField",
    "someCategoryField"
];


Show tags in tag group only being used on live entries Looking to loop through tags from entries but limit to only show tags that are being used on entries. Right now this just loops through any and all created tags.

I tried limit to null but have had no luck getting that to work.

{% set categories = craft.categories.group('storiesCategories').find %}
{% set tags = craft.tags.group('storiesTagGroup').find %}
{% set elements = categories|merge(tags) %}

All

    {% for element in elements | supersort('natcasesort') %}

{{ element.title|capitalize }}

    {% endfor %}

Your mention tags, but it seems like you're merging Categories and Tags together and trying to loop through the results.

If you leave Categories out of the equation it's as simple as this.

If you want Categories and Tags, you'd repeat that process twice and merge the results.

Note that using |merge on full-fledged arrays of objects is sketchy, though, since it's difficult for PHP to know how to compare the objects for equality.  You'll be much better off merging on something primitive, like an array of element IDs.

Something like:

{% set categoryIds = craft.categories.group('storiesCategories').ids() %}
{% set tagIds = craft.tags.group('storiesTagGroup').ids() %}
{% set elementIds = categoryIds|merge(tagIds) %}


Overriding a structure section's template for a single structure entry When you create a structure section you set which template that you would like to use. Is there a way to override that for a single entry in that structure? If I have missed it in the docs I apologise but it would appear that setting a route would not work due to the order things are looked up at.

I think my answer here should provide you with exactly what you need, as well as an elegant and reusable way to do it:

How can I route a specific entry in a structure section to its own template?


Commerce 2 Adding tax to custom adjuster I have created a custom adjuster, there is a surcharge per item if a customer has selected rush delivery. But i need to charge tax on that adjuster. Below is code:

public function adjust(Order $order): array
{
    $adjustments = [];

    foreach ($order->getLineItems() as $item) {
        $adjustment = new OrderAdjustment;
        $adjustment->type = 'rush-delivery';
        $adjustment->name = 'Rush Delivery';
        $adjustment->description = 'Rush Delivery';
        $adjustment->sourceSnapshot = ['data' => 'value']; // This can contain information about how the adjustment came to be
        $adjustment->amount = 1;
        $adjustment->setOrder($order);
        $adjustment->setLineItem($item);

        $adjustments[] = $adjustment;
    }

    return $adjustments;
}

But tax is not added to the £1 i am adding here. How can i get tax to be added or calculated as included?

Having slept on it i thought it could be something to do with the order of the adjusters. Maybe Tax was applying to the price before my custom adjuster. So in the event i did the following:

var_dump($event->types)

This told me that my custom adjuster was going to the bottom of this array. To resolve this i used the php function array_unshift to push it to the front of the array

array_unshift($event->types,MyAdjuster::class);

This now gave me the following array:

array(4) {
      [0]=>
      string(18) "modules\MyAdjuster"
      [1]=>
      string(33) "craft\commerce\adjusters\Shipping"
      [2]=>
      string(33) "craft\commerce\adjusters\Discount"
      [3]=>
      string(28) "craft\commerce\adjusters\Tax"
    }

As you can see the adjuster is at the front of the array and now the tax applies to the fee as required.


Import data into Sprout SEO I'm converting a large EE site into Craft with the FeedMe plugin. So far it's working great. However, I've hit a speed bump. I need to import the SEO data attached to each article into Sprout SEO. When attempting to map the meta title, keyword and description data into the Sprout SEO field it only shows one destination field - the Meta:Basic field. Is it possible to import those 3 sets of data into the corresponding fields within Sprout SEO?

The problem you're running into is that FeedMe doesn't know how to import into custom element types; I think a special hook would need to be written.

If you use my SEOmatic plugin it has a FieldType that lets you choose what fields to pull things like the title, description, etc. from which solves this problem.

Check out the section of the wiki docs on SEO Entry Meta to see how that all works.


Access logged-in user info when `baseCpUrl` is different than `siteUrl` Our site's control panel needs to be on a subdomain for security purposes. So our baseCpUrl setting in our general.php file is http://craft-admin.domain.com/ while our siteUrl is set at http://www.domain.com/.

I'm not able to access user information (specifically if a user is logged in and has accessCp permissions) on the main site. Dumping user information on a template is giving me NULL, I assume because there's no connection being made between craft-admin.domain.com/ and www.domain.com/, so pages on www.domain.com can't tell me anything about logged-in users.

I ran into this trying to add in the Admin Bar plugin so logged-in users can have quicker access to the Control Panel edit screen for a particular page if they're viewing it on the public-facing site. However, since there's no user information being passed along, the admin bar will never show up because it assumes I'm just a regular person browsing the site.

Is there something else I need to do in order to access logged-in user information on the front end if the baseCpUrl is different than the siteUrl?

My guess is you probably need to add the root .domain.com to the defaultCookieDomain config setting.


Related Projects (Structure + Channel Matrix) I've looked around a good bit to see if I could solve this problem on my own. I've managed to get close I believe, but I think I don't quite understand Craft's relationships.

Basically, I have a related projects section on my site. I'm allowing the user to select the related projects with an Entries tag within my matrix. I would then like to compare their selected Entries with projects already added to a Structure - then output attributes that exist only in the Structure.

This is as far as I've gotten:

My Structure Content

{% for entry in craft.entries.section('homePageBanners').limit(3) %}
    {% for block in entry.banner.limit(3) %}

        {{ block.client }}
        {{ block.bannerImage }}

    {% endfor %}
{% endfor %}

My Matrix Entries Block:

{% for entry in block.projectsEntry %}
    {{ entry.title }}
{% endfor %}

I'm not sure how to compare them & pull content based on what the user selects. I looked into relatedTo(), but didn't have much luck with that.

If that's not clear, I can try to be more specific -- please go easy on me, I'm pretty new to Craft.

EDIT:

Maybe this will help clarify
    {% for entry in block.projectsEntry %}

 {% for project in craft.entries.section('homePageBanners').limit(3) %}
  {% set relatedProjects = craft.entries.section('homePageBanners').relatedTo(project) %}
   {% for project in relatedProjects %}
    {{ project[0].title }}
   {% endfor %}
  {% endfor %}
 {% endfor %}

I'm not sure I totally understand your issue, but give this a try in your Matrix code:

{% for entry in block.projectsEntry %}
    {{ entry[0].title }}
{% endfor %}

Are you getting any errors in devMode?


Applying coupon codes via URL I was wondering if it was possible to allow a customer to apply a coupon code using a URL or URL params in Commerce 2. I haven’t been able to find any questions on stack exchange or on the web, but the scenario I’m trying to support is:

Customer receives an email with a coupon code (includes a coupon code image that links to the storefront)
Customer clicks a link which takes them to the store and automatically applies the coupon with a toast confirmation (e.g. store.com?coupon=somecouponcode)
Customer adds purchasables to cart and when they go to the cart page, the coupon is already applied to cart lineitems without requiring them to manually input it themselves

The following code can be used in the init method of a custom module.

Event::on(
    View::class,
    View::EVENT_BEFORE_RENDER_PAGE_TEMPLATE,
    function($event) {
        // Check query string for coupon code
        $couponCode = Craft::$app->getRequest()->getQueryParam('coupon', null);

        if ($couponCode) {
            // Check there is a discount that has this coupon code
            $discount = Commerce::getInstance()->getDiscounts()->getDiscountByCode($couponCode);
            if ($discount) {
                $cart = Commerce::getInstance()->getCarts()->getCart();

                $cart->couponCode = $couponCode;
                Craft::$app->getElements()->saveElement($cart, false);
            }
        }

    }
);

Don't forget the following use statements at the top of the file.

use Craft;
use craft\commerce\Plugin as Commerce;
use craft\web\View;
use yii\base\Event;


Dynamically setting a channel's Entry URL Format with Craft tags I have a Structure section and a Channel section.

Entries in the Channel will be listed on one of the Structure Entries, and it's entry page will fit the same URL format.

So for example, the Structure Entry may be:

Title: "Our People"
URL: /about/our-people"

...and the Channel entry may be:

Title: "Jamie"
URL: /about/our-people/{slug}

When I set up the Channel is there any way of dynamically setting it's "Entry URL Format" based on another entry's URL/slug? I can set it to "/about/our-people/{slug}" but if the Structure entry's slug ever changes it'll be wrong.

I've tried adding the following to the Channel's Entry URL Format field and it seems to work (high fives P&T).

{% set parent = craft.entries.section('site').id('32').first() %}{{ parent.uri }}/{slug}

Is there anything I should be worried about using that? Obviously if that parent entry is deleted things will break. Anything else?

I've successfully used this entry url format and it works great:

{{ craft.entries.id(65).first.uri }}/{slug}

I would advise using the entry id over a slug, as it will never change. You also don't need to specify the section if you've included the id.

For a multi-lingual site, you can specify the locale for each entry url format:

{{ craft.entries.id(65).locale('en_us').first.uri }}/{slug}
{{ craft.entries.id(65).locale('de').first.uri }}/{slug}
{{ craft.entries.id(65).locale('fr').first.uri }}/{slug}

As you mention in your comment, you do need to beware of updating the parent entry's slug as uri's are parsed before being stored in the database so it is not truly dynamic. I'm not aware of any workarounds for this that don't involve a plugin.


Solspace Calendar: Export a single event I'm trying to add an export function to my calendar that will export a single event.

When I use the example code, it exports my entire calendar.

I tried passing a single event using this code:

{% set events = craft.calendar.event(craft.request.getSegment(3), ({
    loadOccurrences: false
})) %}

{{ craft.calendar.export(events) }}

and I get this error:

  Argument 1 passed to Calendar\Library\Export\AbstractExportCalendar::__construct() must be an instance of Calendar\Library\Events\EventList, instance of Calendar\Library\Events\Event given, called in /craft/plugins/calendar/variables/CalendarVariable.php on line 128 and defined

Is there a way to export only individual events?

There's a definitely a syntax error in your first line.

({
    loadOccurrences: false
})

should be:

{
    loadOccurrences: false
}

Also, from their docs, the export method only shows one parameter being passed in and you've specified two.


Craft Commerce > 2.2: How can you order line items? As of Commerce 2.2 line items are ordered by date created.

How can you order line items differently?

{% for item in cart.lineItems.orderBy(’sku desc') %} does not work…

I am posting the answer of Craft Commerce Support in case somebody stumbles over the same thing:

It is possible to order them differently if required. The code example below shows how to order them alphabetically by SKU.

{% set lineItems = cart.lineItems|sort((a,  b) => a.sku <=> b.sku)  %}

    {% for item in lineItems %}

{{ item.description }} - [{{ item.sku }}]

    {% endfor %}

Thanks Nathaniel


Saving Custom Field Values to User Profile I have a custom user field 'myuserfield'

How do I save a value to this field via a plugin in Craft3?

Here is my current attempt.

    $myvar = '12345';
    Craft::$app->getUser()->getIdentity()->setFieldValue('myuserfield', $myvar);
    $myid = Craft::$app->getUser()->getIdentity()->getFieldValue('myuserfield');

When I echo $myid it does, in fact, give me the new value ($myvar or 12345) but when I check the control panel the value is not saved.

I used August's answer, but fixed it:

Put this at the top:

use craft\elements\User;

Then the updating code

$myUser = Craft::$app->getUser()->getIdentity();
$myUser->setFieldValue('fieldHand', 'value');

Craft::$app->getElements()->saveElement($myUser, false);


Moving from Cart to Order I am having difficulty moving the user's cart over to being an order. I understand that a cart is essentially an order with isCompleted set to false and no date set but I can't seem to access anything when setting orders = craft.commerce.orders, etc. I can see the cart on the backend along with the guest's email but cannot get orders. I can easily get the current cart and all my products have a price of $0 if that is relevant.

Thanks!

craft.commerce.orders returns an element criteria model that defaults to setting the criteria param isCompleted to true.

You would need to set isCompleted to false on the criteria to override it, in order to get someone else's cart from the front-end.


Check for logged in user with the Element API plugin Working on a SPA with Vue and Craft and looking to check if a user is logged in to run some Vue conditional logic.

I imagine that will then enable me to check if the logged in user owns content to return as well?

Assuming you want to do this from your transformer, then something like this should work:

'transformer' => function($entry) {

    $isLoggedIn = craft()->userSession->isLoggedIn();

    if ($isLoggedIn) {
        // Do your custom logic.
    }

    return array(
        'title' => $entry->title,
        'url' => $entry->url,
        'description' => (string) $entry->description,
        'photos' => $photos
    );
},


How can I create and validate against a url token? I am (attempting) to and for the most part succeeding in sending an email from a plugin.

My plugin has a textarea in the settings that allows the user to customize the message. The message looks like this by default:

{{ forms.textareaField({
    label:        "Guest Email Message"|t,
    id:           'guestEmailMessage',
    name:         'guestEmailMessage',
    instructions: "The email message."|t,
    value:        (settings.emailMessage ? settings.emailMessage : "
Use the link below to complete your request.

Regards,
{siteName}
"|t({ siteName: craft.app.siteName })),
    errors:       settings.getErrors('emailMessage')
}) }}

I would like to create something like this:

"
Use the link below to complete your request.

"

My first problem is, I haven't figured out how to properly escape the anchor parameter. I've tried single quote and a backslash \ (that one).

My second problem is how to generate a random token. I'd like to generate a random string or something. I thought something like getUrlWithToken(), but I'm at the twig level and I'm not sure how that translates.

It would be cool if when I visit the link I am sending I have a way to validate that in my template. Maybe it's a case of if the CSRF token matches? I'm not sure where to start.

Thank you for any suggestions!

My first problem is, I haven't figured out how to properly escape the anchor parameter.

I'm guessing you mean the link is being escaped (since Twig will do that by default) and you don't want it to?  If so, you can use the |raw filter (http://twig.sensiolabs.org/doc/filters/raw.html).

  My second problem is how to generate a random token. I'd like to generate a random string or something.

If you don't care if it's a cryptographically secure string, you can just use StringHelper::randomString() or StringHelper::UUID().  If you want a cryptographically secure random string, then you can use craft()->security->generateRandomString().


Embedding a podcast player onto my Craft site I'm pasting the embed code below into the HTML section but the player is not appearing. I do not have access to templates on my site. Is there a quick fix to get this to work?

I tried adding a plug in but can't work out how I do that.

Not having access to the templates could make this hard to troubleshoot. Are you pasting into the HTML editor of a Redactor field? If so try editing the field's advanced options. Uncheck Remove inline styles, Remove empty tags, and Purify HTML.


Is there a way to add a url(not to the file itself) to assets? I am testing Craft to see if it would be a good fit for sites I build.  At this point, I do feel it is great and might fit most of the work I do.  The only thing I can't figure out is how I could add a url to images to build a logo gallery (ie: list of logos that link to the partners websites).

Is there a way to do this by default?  I can't find any information on it.

You can add any number of fields to your asset sources (just like you can for 'user groups', 'category groups', 'tag groups', or 'entry types'). Under 'settings > assets > sources', click a source (or create new); then click the 'field layout' tab and add your field (field needs to be created first); and save. For a url you would likely just use a textfield.

In your template you would access it with something like this:

{{ entry.myAssetsFieldHandle.first().myLinkUrlFieldHandle }}


Imagemanager plugin doesn't show up in toolbar I have upgraded redactor 2 to redactor 3, since a lot of things had to be changed. Been fixing those and it works well. I have a problem with image manager plugin which doesn't show up in the toolbar.

Needed a help immediately.

Thanks.

The redactor toolbar can be configured in yourprojectfolder\config\redactor\ and you can choose the toolbar type when you configure your Field. By default, there is Standard.json file, where is the image toolbar button. For example, in menu Settings -> Fields create a new Field named Text, set Field Type to Redactor and now you can select in Redactor Config the Standard toolbar. I hope it helps.


Redactor plugin not found: imagePosition Craft 3 I just updated a Craft 2 site to Craft 3, everything pretty much works except for this error:

Redactor plugin not found: imagePosition

Since Redactor is now installed via the plugin store, how do I go about rectifying this issue?

The reason you get the error is probably that you had the Redactor Image Position plugin installed in Craft 2. If the plugin was available for Craft 3, you'd just need to update to it. But since it's not available, you're kinda out of luck.

To remove the error message though, you only need to remove 'imagePosition' from the list of enabled plugins in your redactor config files, they're located at config/redactor and works the same as in Craft 2.


Dreaded GROUP_BY issue on mySQL 5.7+ I'm having that dreaded GROUP_BY issue on a website. I suspect the server auto-updated itself or something as the site was fine before.

Now it's running on mySQL 5.7.10. The site wont load. I get the usual:

Internal Server Error CDbCommand failed to execute the SQL statement: SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #18 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'creighton_mma_craft.structureelements.root' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

I followed the instructions I have used before (adding the settings into my.cnf to return the group by settings to previous behavior).

It works for a few mins, then the whole of mySQL dies. I can no longer access it at all. I can only bring it back up by removing the line and restarting mySQL. I have tried several times and get the same result each time.

WHAT ON EARTH IS HAPPENING??

Looking at other issues, there are a few options to handle the GROUP BY issue on MySQL 5.6 > 5.7

Alter the query by using GROUP_CONCAT
Alter the SQL modes

Changing the SQL modes gives you a timeout, but these modes were given in a configuration file. Have you tried it by using an "extra" query?

I.E. session/global:

set session sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

This resets the SQL_MODE to ignore ONLY_FULL_GROUP_BY for every session, in a different way.

Let me know if this changes anything :)


Yoast-like real-time content analysis Is there an equivalent to Yoast's real-time content analysis for Craft?

I've looked at SEOmatic and Sprout, but neither of them have the handy traffic light system that Yoast has on WP (despite both are looking to be great for everything else SEO related).

I'm trying to get my company to switch from WP to Craft (for the bigger projects at least), but my director considers the traffic light check-list to be an important time saver for non-techies/clients to post quality content.

This feature will clinch the deal! Help me Craft Stack Exchange Kenobi, your my only(ish) hope.

Since Craft is mainly build for developers why don't you create your own plugin? From my experience Craft is a time saver all over the place and when you compare the time you need to build a complex non blog site with Craft and WP - Craft will win for sure unless you are going to build sites for less than 100$ with existing themes without writing a single line of code.

I don't know Yoast and I don't really know other SEO Plugins because we made a private real time analysis tool for our customers but I know even when we consider the time we spend for this plugin, all our sites consume less time and effort with Craft than with WP. With the experience I collected within the last 3 Years I can say it's not worth to use this CMS if you are going to solve every problem with an existing plugin like for WP.

Yii2 + Craft3 have awesome and very powerful tools to extend the system however you like. There are so many great features and opportunities to customize nearly every aspect of the system within a really short amount of time and effort without loosing much performance or risk security issues. Due to it's well considered API you can create complex frontend logic really fast with plugins and Yii modules.

If your director think the initial time loss is not worth it or if your company does not has the developers you need to create such a plugin it's not a good idea to move to Craft in the first place (at least that's my opinion) because as I said there are not that much plugins for Craft as there are for WP since it's so easy to solve problems and the group of customers is usually totally different

Edit:
within a quick search: maybe webtexttool is something you want?https://github.com/iNalgiev/webtexttool


Craft Commerce not sending E-Mails immediately I have an e-mail problem at Craft Commerce.
Emails are not sent at the time of purchase.
The e-mail is only sent when you log in to the backend.

I first thought it was a server queue problem. But the support of our Nginx server could not find any error. I have also already tried out various e-mail sending options.
Strangely enough, contact form e-mails are sent immediately and without delay.

The problem occurred first when updating Craft Commerce.

Thanks to @PhilipBoomy for his answer.  The problem were missing cron jobs.

Additionally I want to add one more solution from the craft support team:

If you don't have the queue set up to run automatically with a cron job or worker, you can also try adding this to your order confirmation template:

{# run queue #}
{% do craft.app.queue.handleResponse %}
{{ craft.app.response.content|raw }}

Which will run the queue over Ajax on that page.


Change matrixblock field value before save element So i have a Matrix with one type of matrixblocks.
These all have a field for a custom id which should be set by the system, if empty, before the entry is saved.
I can access the individual matrixblocks and change the field value in all of them. But i am not sure how to add them back to the matrix so the changes will apply.
example code that is not working:

After a bit of testing, it appears you don't have anything to do to have your values saved, just set them and Craft will take care of the rest.
    Event::on(
        Elements::class,
        Elements::EVENT_BEFORE_SAVE_ELEMENT,
        static function (ElementEvent $event) {
            $element = $event->element;
            if ($element instanceof Entry && $element->getSection()->handle === 'testSection') {
                /** @var MatrixBlock[] $blocks */
                $blocks = $element->getFieldValue('testMatrix')->all();
                foreach ($blocks as $block) {
                    $block->setFieldValue('automaticField', uniqid('some unique value', false));
                }
            }
        }


How do I select a specific product variant by element/field/entry? Excuse my new-ness, but I'm having an issue with product variants.

Scenario

I have a product with multiple variants (up to 30 in fact). Based on the URL, I want to choose a specific variant so that I can display fields from that variant on my product detail page. I also want a 'default variant' if there is no variant specified in the URL.

In my example, the variant should be selected by a custom field in that variant colour whose value match the 4th URL segment.

Code

{# Grab colour segment #}
{% set colourSlug = craft.request.getSegment(4) %}

{# If there is no colour, we grab the first variant colour #}
    {% if not colourSlug %}
        {# Grab first product variant #}
        {% set dressColour = product.defaultVariant %}
    {% else %}
        {# Set dress colour #}
        ??{% set dressColour = product.variants.find(colour.colourSlug) %}??
    {% endif %}

You would currently need to loop over all variants and just grab the ones that match the 'if' condition shown below:

{% set colourSlug = craft.request.getSegment(4) %}

{% if not colourSlug %}
    {# Grab first product variant #}
    {% set dressColour = product.defaultVariant %}
{% else %}
    {# Set dress colour #}
    {% for variant in product.variants %}
    {% if variant.colour == colorSlug %}
       {{variant.sku}}
    {% endif %}
    {% endfor %}
{% endif %}

We will look to enable variants to be an element criteria query. If each variant has their own page, would it make sense they are seperate products?


How can I get the index of an occurrence in a repeating event on the calendar month view? I'm using the calendar demo templates that came with Solspace Calendar (documentation here). I've got a couple repeating events and I want to output the occurrence index (Day 1, Day 2, Day 3, etc.).

Here's the code for the specific day:

{% for entry in day.events %}
  {{ entry.title }}
{% endfor %}

From the docs, I'd think occurrenceCount to work, but it returns 0 for each event vs the index of the occurrence.

If you're referring to the position of the event inside the loop, so you can just use this:

{{ loop.index }}

If you're referring to which occurrence the event is (of the full series of recurrences of that event), then I don't think that is currently possible.


Visitor drop off since moving over to Craft CMS Hi I've been managing my clients Wordpress site for over 7 years now and redesigned it a few times. Recently, I convinced my client to move over to Craft CMS and 4 months ago we went live with a new design. This was my first build in Craft, the development went well having studied some good tutorials. Since then, in the 4 months that the site has been live the visitor sessions in Google Analytics have halved and have stayed at half continuously. They pretty much halved around the day or the week the site went live.

Bounce rate has increased by 10% and the average session duration has increased by 20%, which would suggest that the site is slow to respond?

I have run the site through Google Site Speed and there is some action to take regarding compression etc, minor stuff though.

So my question is:

Does Craft perform more slowly than Wordpress, or probably a better question: does Craft require more server resources than Wordpress?

Server is a dedicated server and has 2gb of RAM for 15 active domains and 256mb of memory is allocated to PHP for this particular domain.

Pictures do seem to render a little more slowly than before especially on a slide show on the home page.

I did have a lot of 404's which I was a bit slow to notice and clear up but have been dealt with in the .htaccess file.

We also moved the website onto SSL for added security so don't know if there is anything that I should look into there.

All meta tags were ported over correctly.

Have I been penalised in some way by Google for the change in website design or structure?

Other than that, I don't know why my site visitors would halve like this.

Any other tips or suggestions would be really helpful thanks.

I wouldn't be overly concerned about bounce rates and such, I'd be more concerned about conversion metrics. The reason is that many things affect bounce rate; if the new site is better designed, people may not need to click on additional pages to find out what they want to know, for instance.

There's nothing inherent with Craft that would result in this type of a falloff. For sure making sure all of the 404 errors get buttoned up would be a good start, and the Retour plugin can assist with that. You could also consider installing the SEOmatic plugin to assist you with modern SEO.

Disclaimer: I'm the author of both of those plugins.


How do I load composer dependencies for a Yii module that's in my site repo? I have a site-specific module in my modules directory that's being loaded in config/app.php. Since it won't be used elsewhere I am not storing the module in an external repository.

When I added a composer.json file to load some dependencies for the module and ran composer update, it created a new vendor directory inside the module directory.

Is there a way I can have a composer.json inside that module directory, but have the dependencies loaded in the main vendor directory?

Or am I doing something totally wrong here?

With a little nudge from Brad, here's the answer:

In order to get the module's composer dependencies taken into account in the parent site's composer dependencies, you need to add the module in the parent's composer.json, both as a require and as a repository with the path type, like so:

{
  ... a bunch of stuff from the default composer.json goes here ...
  "require": {
    "php": ">=7.0.0",
    "craftcms/cms": "3.0.0-RC5",
    "vlucas/phpdotenv": "^2.4.0",
    "roave/security-advisories": "dev-master",
    "modules/modulename": "dev-master" <-- add your module here (package name)
  },
  ... more stuff goes here ...
  "repositories": [
    {
      "type": "path",
      "url": "modules/modulename" <--- and add it here (package path)
    }
  ]
}


Let user add a message when selecting shipping method One of our shipping methods let's the customer have their purchase delivered at home. When the user selects that method, we'd like to include a simple textarea where the user can write when he wants his order delivered.

Is there an easy way to go about this? Basically just attach a "user note" to the cart as a whole, not to any individual lineItem

Thanks!

Create a text field and add it you field layout for Orders in Commerce settings.

Then in any updateCart form you can simply place a value in this by using <input name="fields[fieldHandle]" etc>


Multi-Language Site but the Date should be always in English with {{ block.timeLimit|date('M d Y H:i')}} i can get the real Date & Time in always the real Language from the Site.
If the Page is German output is Dez, in English output is Dec.

How can i set the output of this Date always to en? Whatever language the Site has?

Thanks for every help!

I made a plugin to do this.

https://github.com/IndigoViking/Translitedated

Use it just like the |date filter (new filter is |dated) and pass it the date format and the locale you would like to use. In you case the locale would be 'en'.

Example from your question:

{{ block.timeLimit|dated('M d Y H:i', 'en') }}

This will always output an English date.

If you have any issues with it, just submit an issue via GitHub.

It's available via packagist so you can run

composer require indigoviking/translitedated

And it is in process to be approved on the plugin store (should only be a day or so. If you need more features/requests/or help with it, please let me know!


Start Matrix loop from item that contains todays day I have a Matrix block weeklyMenuItems, each item in the block has a dropdown with days of the week (Monday, Tuesday etc). Each entry will have a Matrix block with 7 items, matching the 7 days of the week.

In the template, I would like to start the loop from todays day but still include previous days in the loop, at the end. So, according to the example, whichever item.dayOfTheWeek matches {{ now|date('l') }}.

For instance, if today's day is Wednesday, the loop will output...

Wednesday
Thursday
Friday
Saturday
Sunday
Monday
Tuesday

Here is part of my code, the entries that are being looped are from an entries field of another channel menuSection but I don't think that matters in this instance.

{% for entry in craft.entries.section('menuSection').find() %}

    {% for menuItem in entry.menuEntries %}

{{ menuItem.title }}

            {# Matrix blocks #}
            {% for item in menuItem.weeklyMenuItems %}

{{ item.dayOfTheWeek }}

{{ item.itemTitle }}

            {% endfor %}

    {% endfor %}

{% endfor %}

Any guidance will be welcomed, let me know if I can clarify anything!

Thanks

Do you really want to start the Matrix loop from the week day offset?  Or do you just want to only start printing when that offset matches.  The former seems like a bit of a micro-optimization.

For the latter, something like this completely untested code should do it:

{% for entry in craft.entries.section('menuSection').find() %}

    {% for menuItem in entry.menuEntries %}

{{ menuItem.title }}

            {% set offset = false %}

            {# Matrix blocks #}
            {% for item in menuItem.weeklyMenuItems %}

                {% if item.dayOfTheWeek == now|date('l') or offset > 0 }}
                    {% set offset = loop.index0 %}

{{ item.dayOfTheWeek }} - Matched

{{ item.itemTitle }} - Matched

                {% endif %}
            {% endfor %}

            {% if offset == false %}
                {% set offset = 0 %}
            {% endif %}

            {# 2nd pass #}
            {% for item in menuItem.weeklyMenuItems|slice(0, offset) %}

{{ item.dayOfTheWeek }} - Matched

{{ item.itemTitle }} - Matched

            {% endfor %}

    {% endfor %}

{% endfor %}


HTML code button missing from Rich Text "standard" view after 2.5 upgrade After recently upgrading to Craft 2.5.x the HTML code view button is now missing from the "standard" Rich Text view, which means I can no longer edit all the custom HTML code I've added to those fields.

Do I have to create a custom Redactor config file to get HTML code view back, or should it still be included in the Standard config?

Thanks to carlcs for pointing this out. If I edit the Standard.json file in craft/config/redactor/ as per these instructions (https://craftcms.com/help/redactor-ii-configs) it's fixed.

I find it odd that Craft 2.5 didn't come with this Redactor config fix included, rather than letting it break and leaving it up to developers to fix it. I can understand if you had custom configs, but the default Simple and Standard configs should come fixed with the install or upgrade, no?


How can I access disabled entries? I'm looking answer because I need access for all user in database access to disable entries

This mean somebody will publish something and administrator will be change status for entires from live to disable and CMS will be send notification to user about that. When you user will be login to account will be see entires live and disable and access to this entries. Right now I can show every entries live and disable but when click link live entire go to template and work fine but when I click link disable entries to to 404 page.

Thanks for help,
SS

You would need to create a custom route in the Control Panel that matches the same basic routing as your entries. Then in the entry template, you need to add some extra code that pulls disabled entries. Something like below.

{% if entry is not defined %}
    {% set entry = craft.entries.section('whatevs').uri(craft.request.url).status(null).first() %}
    {% if entry is null %}{% redirect '404' %}{% endif %}
{% endif %}


How to filter what is showed based on radio button checked I am fairly new to Craft CMS coming from ruby on rails and angularjs.  I am running into an issue with attempting to display images on a home page based on whether or not the radio button titled "featured" ( a field) is selected.

I have searched around but was unable to find something addressing this, or at least in a way I understood to solve the problem.

I have been trying variations of...

{% if thumbnails.featured %}

...hoping it would only display what has "featured" selected but it either breaks and shows nothing or shows all the images.  Based on what I have found I think I have to "set" something but am unable to figure out exactly how that is set up.  This is exactly what I have right now and it is showing all images.

{% for thumbnails in craft.assets.thumbnails %}
    {% if thumbnails.featured %}

                    {{ thumbnails.caption }}

    {% endif %}
{% endfor %}

If anyone could suggest a solution or even point me in the right direction it would be greatly appreciated.

You will want to first create an 'elementCriteriaModel' to retrieve only the 'featured' images from the 'thumbnails' asset group, which will return an array like object (not technically an array) which you can loop through to display.

{% set images = craft.assets.group('thumbnails').featured(1) %}
{% for image in images %}

        {{ image.caption }}

{% endfor %}

Another method that might be easier to manage from a client perspective is to add an assets fieldType to your homepage section (called 'featuredImages' or whatever; limited of course to the 'thumbnails' asset group) which the client can use to add and/or reorder the featured thumbnails to be displayed. In which case the code would look something more like this.

{% if entry.featuredImages|length %}
    {% for image in entry.featuredImages %}

            {{ image.caption }}

    {% endfor %}
{% endif %}


Sorting multi-dimensional grouped arrays My problem is that I don't know/understand how to sort complex arrays.

I have a multi dimensional array of users from an external API. So it's not an array that I fetch from the Craft database. Let's call this array the "Main Array".

The Main Array contains multiple users, every user has multiple fields such as firstname, lastname, department, and so on. So every user in the Main Array is actually another array that we shall call a User Array. So the Main Array consists of multiple User arrays which consists of multiple fields.

First I group the Main array by the department field of a user (using the Twig group filter). So far so good, that way I can list all my users in department blocks.

But within those blocks, I want them to be alphabetically sorted by their lastname. So I need a way to let Craft know to sort my User Arrays by the lastname field of a user within the Main Array.

Seems logical and simple, but I can't figure out how. I tried SuperSort, but the standard asort function won't work. I than tried superSort('SortAs', '{lastnameField}') but that didn't work either.

Not really an answer that fixes the question per sé if anyone else has the same issue, but none the less the answer that worked for me was simple:

Split up your sorting where possible and simplify things!

I wanted my main array to be sorted by condition A, grouped by condition B and than sort the sub arrays alphabeticaly. All done to the same array in a few lines of code so I could use this one array in my template to get all information from it. Bad idea.

So what I did was sort everything by condition A in PhP in my plugin, in my template I than group everything by condition B and only when I needed to iterate over my array to reveal my sub arrays, only then I sort the values alphabetically.

So short answer: keep it simple damnit! :)


Craft 3 multi-lingual multi-sites setup with shared assets I have 2 almost identical websites. Both have almost the same layout but different colors (so different CSS file). They share most of the same templates and assets (images, css, js, videos, etc.).

Site A has two languages NL and FR.
Site B has only one language FR.

Both sites have their own TLD.

How do I set this up in Craft 3? I have tried various ways, but I don't seem to be able to find the right solution.

I was thinking about creating two separate web folders, one for site A and one for site B. With subfolders for nl and fr in the webfolder for site A.
That works, but than I have the problem that I cannot share my assets because they belong to different webfolders.
And if I want to share a product channel for example, when I upload a product image, I want to use that same image in both sites. How will that work?

Also the baseUrl is a mystery to me. If I use @web/nl and @web/fr for site A and @web for site B, the @web gives the correct TLD as output, but the template from site B (which uses @web) are always loaded.

If I try to forgo to separate web folders, it totaly goes wrong...

Can someone please give a working example?

You could create 2 site groups. One group for site A and one group for site B.

Sitegroup A will contain contain 2 sites, the other one only one site.
Your setup will look like this

SiteGroup A
    - Site A - language NL
    - Site A - language Fr
SiteGroup B
    - Site B - language Fr

Let's imagine your Site A - language Fr is your primary site. So it will have the base url /. Your Site A - language NL have the base url /nl.

Your Site B - language Fr will have the url whatever.you.like.fr.
You don't need multiple web folders at all because Craft will route every request to web/index.php and sets the currentSite depending on the url structure.

Now you have multiple ways to setup your asset structure. You can either create multiple Asset Bundles in a plugin and load the assets you need or you can just check in your template

{% if currentSite.id == 1 %}
    load these assets
{% else %}
    load other assets
{% endif %}


Adjusting Max File Size - Stuck at 16M After Adjusting general.php I'm adjusting the maxUploadFileSize in Craft, to 50MB.
In following the post below, I made several adjustments to both: php.ini and craft/config/general.php.
https://stackoverflow.com/questions/3263480/upload-max-size-in-php

First, I adjusted settings in php.ini:

upload_max_filesize
post_max_size

In general.php (craft/config), the following was already set:

  define('URI_SCHEME',  ( isset($_SERVER['HTTPS'] ) ) ? "https://" : "http://" );
  define('SITE_URL',    URI_SCHEME . $_SERVER['SERVER_NAME'] . '/');
  define('BASEPATH',       realpath(CRAFT_BASE_PATH . '/../') . '/');

 return array(

  '*' => array(
        'environmentVariables' => array(
        'omitScriptNameInUrls' => true,
        'siteUrl'  => SITE_URL,
        'basePath' => BASEPATH,
        'maxUploadFileSize' => 62914560,
        ),
  ),
  'dev' => array(
    'devMode' => true,
  )

 );

I know that that is around 62MB, but I keep receiving an error message saying that there is a 16MB limit on files.  All other files great than 2MB and less than 16MB now are upload-able.
Can anyone make a suggestion as to why the standard CraftCMS default of 16MB is now in place?

Thanks for any leads

My guess is that your php upload_max_filesize is set to 16M, you'll need to adjust that.


Group by day does strange exeptions I have a list of forms which I want to sort by day:

{% set groupVerbund = 'datum.day' %}

{% set allSubmissions = craft.amForms.submissions({
   formHandle: 'reservation',
   limit: null}).find()
%}
{% set entriesByDay = allSubmissions | group(groupVerbund) %}

{% for entriesInDay in entriesByDay %}

    {% for entry in entriesInDay %}
      {% if loop.first %}
{{ entry.datum | date('d.m.Y') }}
{% endif %}

{{ entry.datum | date('d. M Y') }} | {{ entry.vorname }} {{ entry.nachname }}

    {% endfor %}

{% endfor %}

This works but there are two entries which just are at the wrong place:

Entries in: 22. Okt. 2016
------------------
22. Okt. 2016 | Name Surname
22. Okt. 2016 | Name Surname
22. Okt. 2016 | Name Surname
22. Okt. 2016 | Name Surname
22. Okt. 2016 | Name Surname
22. Okt. 2016 | Name Surname
22. Okt. 2016 | Name Surname
22. Okt. 2016 | Name Surname
22. Jan. 2017 | Name Surname // This one is wrong
22. Okt. 2016 | Name Surname
22. Okt. 2016 | Name Surname

Entries in: 13. Nov.2016
------------------
13. Nov. 2016 | Name Surname
13. Dez. 2016 | Name Surname // This one is wrong
13. Nov. 2016 | Name Surname

Everything else is at the right place except these two entries. {{ entry.datum}} is a custom date field so it's not possible to add a wrong date format.

How can this be?

When you specifically group on dateField.day (in your case, the |group('datum.day') part), the group filter won't care about the month or year for the date field – only the day. This means that any entry posted on the 22nd of any month in any year will be grouped together, which is probably not what you want.

In this case, the solution is simply to group on the date field without a postfix (which will create an array index for each unique day/date):

{% set groupVerbund = 'datum' %}
{% set entriesByDay = allSubmissions | group(groupVerbund) %}

Additionally, I can't help but notice the
 tag inside your
, which is strictly speaking non-valid HTML. A better solution might be to do something like this (this would also save you a conditional):

{% for day, entries in entriesByDay %}

{{ day|date('d.m.Y') }}

            {% for entry in entries %}
                {{ entry.datum | date('d. M Y') }} | {{ entry.vorname }} {{ entry.nachname }}
            {% endfor %}

{% endfor %}

One final issue is sorting – you'll probably see the dates mixed up, which is just how the |group filter works – it only groups, and cares less about sorting. Basically, the group filter will return an array that looks something like this:

[
    '2016-10-22' => [array of entries],
    '2017-01-22' => [array of entries],
    '2016-11-13' => [array of entries],
]

...which means that if you want the output to be sorted by date, you'll need to sort that array on its keys (i.e. the dates) – something Twig's native sort filter regrettably doesn't do, but which is easily accomplished with the fantastic SuperSort plugin:

{% set entriesByDay = allSubmissions | group(groupVerbund) | supersort('ksort') %}


Does entry ID change with locale? I have a condition that checks entry Id. The condition seems to not work for Japanese locale but works fine on English. I would think that entry ID remains the same irrespective of the locale. Please confirm or correct me if I'm wrong.

Thanks!

The ID won't change in different locales, check this answer for reference: Craft 3 language switcher

You could also test it in your templates e.g. :

{% for locale in craft.app.sites.getAllSites() %}
    {{ craft.entries.siteId(locale.id).one().id }} : {{ craft.entries.siteId(locale.id).one().title }}
{% endfor %}


Dynamic entries limit via dropdown On a entries (listing) page I'm using pagination and a fixed limit of entries set. I want visitors to be able to select (dropdown) the number of entries that should be listed (limit).

I'm not a Java or AJAX expert can someone show me the way?

   <select>
      <option value="12">12</option>
      <option value="20">20</option>
      <option value="50">50</option>
   </select>

{% paginate craft.entries({
    section: 'holidayHomes',
    limit: 12 ,
}) as pageInfo, pageEntries %}

{% for entry in pageEntries %}

          {{ entry.title }}

{{ entry.body | striptags | slice(0,300)~'...' }}

{% endfor %}

Somehow you would just need to communicate to your template that you are changing the default limit.

A fairly simple/standard way is through a query string, and then looking for the value of the variable.

The two things you need to accomplish are

Setting the query string if someone changes the dropdown box
Checking for a value of the query string key in your code.

To set a query string, you could do it a couple of different ways. The easiest way would actually be to submit your form:

<div class="grid-show">
    <form action="" method="get">
        <select name="limit">
            <option value="12">12</option>
            <option value="20">20</option>
            <option value="50">50</option>
        </select>
        <input type="submit" />
    </form>
</div>

The second step involves checking for the value of the query string within your Twig and if it's not set default to 12:

{% paginate craft.entries({
    section: 'holidayHomes',
    limit: craft.request.getParam('limit') ?? 12,
}) as pageInfo, pageEntries %}

If you wanted this to happen via Ajax it would be a bit more involved, but the principle is the same, ie look for a query string variable and use that as your limit.


Incorrect canonical URLs and redirect chains I have installed SEOMatic. However, I am getting incorrect canonical URLs. Here is an example: https://jenoffvanhulle.com/en/
The URL has a trailing slash, the canonical URL not
A second problem is that I'm having redirect chains. e.g. www.jenoffvanhulle.com -> https://www.jenoffvanhulle.com -> https://jenoffvanhulle.com
It's clear that some settings are not right. Can somebody help me solving both issues please?
Below you find a listing of some relevant settings:

htaccess

# Redirect www traffic to non-www
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]

general config

'siteUrl' => [
'nederlands' => 'https://jenoffvanhulle.com/',
'english' => 'https://jenoffvanhulle.com/en/',
],

base URL settings in Craft

SSL certificate settings

Update to the latest SEOmatic; the issue you're describing is a case where SEOmatic operates the same as Craft CMS does in terms of returning a root URL without a trailing slash, but we added a fix to SEOmatic 3.3.18 anyway.


Can't resize image in Rich Text field since 2.5 update after upgrade to 2.5, it seems it's not possible to click on the inserted image and resize it in the Rich Text Field. If you click it now, you directly get a popup to give in the Title, link or select the alignment.
It used to show an 'Edit' overlay & the option to resize it with the mouse.

Any others experiencing this?

It's not Craft that's broken it, but the new version of Redactor that's "superior in every way" acording to them:
https://imperavi.com/blog/redactor-superior-in-every-way/