How to move entries from one channel to another I have a channel that has three different entry types. The client has decided that two of those post types should be in a separate channel. This is an existing site with a few dozen entries currently in the channel, so I'm wondering if there's any easy way of splitting a channel like this that won't require me to manually set up a duplicate of the channel and then manually copy entries across, one by one.

Is there some way of duplicating a channel with all its entries, so I can then just batch delete some entries within each channel? Or is there a way (a plugin, perhaps?) of moving entries of a particular type into a new channel? ...or would it be easier to keep the existing structure and via templates and routing create the appearance of two channels on the front end? (That's the best solution I've been able to come up with so far)

I'd be very grateful for any advice / suggestions!

Currently there isn't any core functionality in Craft for duplicating/moving entries between sections. I think this has been brought up a few times before, but I'd recommend heading over to Craft Feedback and posting up about it there!

Anyways, back to your question. I did post something similar to this at the end of last year. I haven't used this particular code in a long time, and I'm afraid I can't currently test it for you right now, but it might be worth giving a try.

It's also worth noting to take database backups before trying this in-case things start getting scary!


How can I check on the value of a template variable? If I'm used to PHP's var_dump() and print_r() to check the value of a variable, how can I evolve to inspect things in Craft where Twig's dump isn't available?

If you have devMode set to "true" in your config files, you can use "dump" in a twig template like this without any plug in needed:

{{ dump(myArray) }}


Is there a way to output the events that belong in a month after a specific date using the Calendar plugin by Solspace? I would like to get the events with all their occurrences that belong to a specific month but ignore any of those occurrences before a certain date.
From the documentation, the dateRangeStart parameter should the trick but it doesn't work for me. The following query returns all events starting from December 1st.

{% set month = craft.calendar.month({
    dateRangeStart: '2017-12-17',
    calendar: calendarHandle
}) %}

Any help?

The calendar.month function is designed to only display complete months, so as long as you specify a date, it's going to show you events for that whole month (before and after).

What you're looking for is the calendar.events function:
https://solspace.com/craft/calendar/docs/calendar.events/

The code to display events starting from today plus 1 month (+30 days) would look something like this:

{% set events = craft.calendar.events({
   dateRangeStart: 'today',
   dateRangeEnd: '30 days'
}) %}

If you're looking to display events starting today but stop and the END of the current month, your code would look something like this:

{% set events = craft.calendar.events({
   dateRangeStart: 'today',
   dateRangeEnd: 'last day of +0 month'
}) %}


Craft 3 cannot find mysqldump command, console works I want to use Feed Me with Craft to import my old database, but neither Feed Me nor Craft can find mysqldump.

I know this is a known problem, and I have successfully added the path to $PATH and verified that this is set in my .bash_profile.

When I execute mysqldump on the console I get the familiar usage hints. Executing which mysqldump gives me /usr/local/mysql/bin/mysqldump.

Yet when I go to Craft > Database > Backup it fails. In web.log I find:

  2018-07-18 21:01:10 [::1][1][-][error][yii\base\Exception] yii\base\Exception: Could not create backup: The shell command "mysqldump --defaults-extra-file="/Users/xxx/mysite.com/code/craft/storage/runtime/temp/my.cnf"
  [snip]
  _180718_110110_rig2b5xl4z_v3.0.15.sql"" failed with exit code 127: sh: mysqldump: command not found in /Users/xxx/mysite.com/code/craft/vendor/craftcms/cms/src/controllers/UtilitiesController.php:383

Why can I run the command in the terminal but Craft cannot? I've checked the permissions, and they should be ok:

-rwxr-xr-x   1 root  wheel   4062128 29 Sep  2016 mysqldump*

After a lot of digging I found an SO post which recommended updating the environment variable via PHP:

putenv("PATH={$_SERVER["PATH"]}:/usr/local/mysql/bin");

Adding that line into craft/config/general.php before the return statement did the trick for me. Craft does back up and Feed Me runs the feed successfully.

BUT: Is that a good solution?


On multisite setup, currentUser not true in LivePreview On multisite setup, I have problem to get LivePreview working (Craft 3.3.4). I have one domain live, other not, so it displays Maintenance Page. But I need the editors to edit the entries on that domain and check them in LivePreview.

My templates begin like this:

{% if not currentUser %}
  {% include "_main/maintenance_page" %}
{% else %}
  {% include "_main/general_page" %}
{% endif %}

It should show the page when the user is logged in. But this doesn't work in LivePreview. Maintenance page is displayed in LP, what is not what I need to achieve.

I have also tried

{% if craft.app.request.isLivePreview %}

but it returns FALSE for the inactive domain, when tested on LivePreview. So it is not working neither.

Am I missing something? There is no guide in the Docs, afaik.

Thanks

I have found the solution to my problem.

{% if craft.app.request.isPreview %}
    THIS WILL BE SHOWN IN LIVE PREVIEW,
    even if Your domains are
    www.main-cp-domain.com
    www.second-domain.com
{% else %}
   THIS WILL APPEAR TO ANYONE ON FRONTED
{% endif %}

So it does what I need. However, I don't get why craft.app.request.isLivePreview and currentUser are not working in LivePreview, when editing entries for second-domain.com


Plugin Multi-Environment config not working I have set up the plugin's multi-environment configuration as outlined in this answer.

The config.php file for the plugin is as follows:

<?php

return array(
    // All
    '*' => array(
    ),

    // Development
    '.domain.dev' => array(
        'apiKey' => 'APIKEYDEVVALUE'
    ),

    // Staging
    'dev.domain.com' => array(
        'apiKey' => 'APIKEYSTAGINGVALUE'
    ),

    // Production
    'dev.domain.com' => array(
        'apiKey' => 'APIKEYPRODVALUE'
    ),
);

But calling craft()->config->get('apiKey', 'pluginhandle') returns null.

If I var_dump(craft()->config) I can see that the config file for the plugin is loaded by craft.

What am I missing?  Please let me know if I can provide any more useful info.

The issue is that you're putting the multi-environment config code in your plugins/pluginHandle/config.php file, which is just meant to supply default plugin config values.

Users can set custom values in craft/config/pluginHandle.php which is where the multi-environment logic would also go.


License alert message for mysite.com, but not www.mysite.com I have a client website that is reachable at www.mysite.com and mysite.com. Everything on the site functions fine, and the Craft CP can be accessed at either www.mysite.com/admin and mysite.com/admin.

When accessed form mysite.com/admin, the user gets the "The license located at config/license.key belongs to mysite.com. Transfer it to this domain?" message.

This hasn't affected anything yet, but I'm worried that Craft might suspend the license because of the two different domains. It is also worrying the client anytime they login at mysite.com/admin.

Any tips on how to permanently clear the message on both domains, or somehow let the licesne know that it is the same site on both www.mysite.com and mysite.com?

Thanks!

I'm worried that Craft might suspend the license because of the two different domains.

That will never happen, but from what you're describing you shouldn't be getting that alert.

Can you hit up support@buildwithcraft.com with some details about the domain name?

Regardless, you should probably be picking one of those (domain.com or www.domain.com) and forcing the other domain to redirect to it for SEO reasons.  Otherwise, the all-mighty Google will treat them as two different domains.


Dashboard grid layout broken after an auto update gone wrong An auto update went awry. I lost Internet connection towards the end of the update. Each widget now appears on its own row. Everything else looks ok on the front end as well as the admin. When I check for updates, it says I'm up to date. Does anyone have any suggestions as to which files I should update to fix this issue?

Try clearing your browser cache. (Your browser might be holding onto a stylesheet or something from the previous version.)


Correct Limit for Entries with IF statements I have content on my site that can't be shown in some countries and requires a basic level of geo-targeting, based on the users profile and not by any form of IP geo-targeting.

I have set up an address field on the users profile with country and created a matrix block  with a geo-targeting toggle (lightswitch field) for my entries. Then I'm using the below code to:

Show all entries to logged out users (as we do not know their country at this point)
Only show content with no geo-targeting or where the users country matches a country code of geo-targeted content.

{% set category = craft.categories()
        .all()
        %}

{% set params = {
              section:    'articlesWhitepapers',
              typeId:      'not 7',
              relatedTo:    category
            } %}

    {% set user = user is defined ? user : currentUser  %}

    {% set recentPosts = craft.entries(params)
    .with([ ['companyName.companyLogo', { kind: 'image' }, { withTransforms: ['featuredImage'] }], 'companyName',['author.userPicture', { kind: 'image' }, { withTransforms: ['featuredImage'] }]])
    .orderBy('RAND()')
    .limit(2)
    .all()
    %}
    {# Fetch the entries #}
    {% set entries = recentPosts %}

    {% for entry in entries %}
    {% set relatedCompany = entry.companyName? entry.companyName[0] : null %}

        {% if craft.app.user.isGuest %}
        {# Show Everything Regardless #}

        {% include "home/_main-feat" %}

        {% else %}

        {# Check Geo Targeting #}

            {% for block in entry.addArticlePaper %}
            {# get the matrix block by type #}
                {% if block.type == "addArticleOrPaper" %}
                    {% if block.geoTargetContent %}

                        {% for country in block.orAddCustomGeoTargeting %}
                        {% set country = country.value %}

                        {# use the variable to filter the entries #}
                            {% if country == user.location.countryCode  %}

                            {% include "home/_main-feat" %}

                            {% endif %}

                        {% endfor %}

                    {% else %}

                    {% include "home/_main-feat" %}

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

 {% endfor %}

This is working great and the correct content is displayed. The problem is I always want to show two pieces of content and currently it is checking the limited results and returning either 0, 1 or 2 pieces of content as its using the if logic against only two results. How would I restructure the above to continue to allow my geo-targeting to work correctly whilst ensuring there are always two pieces of content shown? I have tried a few different ways but no luck so far!

many thanks in advance!!

You can restructure your code in two different ways here. But firstly let's see what's the issue with your current implementation. Currently you always fetch 2 entries with your entry query (assuming you have at least 2 entries in total). After that you even filter them further according to the user login status and the use country. This way you'll always end up with 2 or less entries remaining. What you want is always exactly 2 entries.

A) Build your query with the user country în mind. You may have a switch statement to build a query with the country filter and one without the country filter. If it's hard to bake the country into the entry query you could B) fetch all entries of that section and then filter them down to the country and count you want to have. (This could have performance caveats depending on how many entries you have. You may want to cache the query results. But watch out when caching user specific queries. You have to use unique caching keys otherwise user A could see the content of user B.)

I can't show you an exact implementation of the query with country because it's not totally clear to me what's going on in your sections and fields. You may explain the articlesWhitepapers section further.


DateTime::__construct(): Failed to parse time string I want to get the lates postDate of a List and format it for the cache tag

{% set latestSubmission = craft.amForms.submissions(
    { formHandle: 'reservation', order: 'dateCreated desc' }).datum('>= '~now).dateCreated().first()
%}

{{ latestSubmission }}

This Returns:

  Do., 07 Sep. 2017 10:32:05

But I want to pass it into the Cache Tag so I want to format it and write:

{{ latestSubmission | date('c') }}

This returns the error:

  DateTime::__construct(): Failed to parse time string (Do., 07 Sep. 2017 10:32:05) at position 0 (D): The timezone could not be found in the database

Why? Why can’t I reformat it when it is already returning a date?

You're getting that error because Do., 07 Sep. 2017 10:32:05 isn't in a valid PHP Date/Time format when you pass it into the |date filter.

Changing it to 07 Sep. 2017 10:32:05 should work.


Recommended way to include API keys in a multi-environment configuration? What is the recommended way to configure public api keys for multi-environment configurations (i.e. local, dev, stage, production)? Is there a way to set these in either the craft/config/general.php or in plugin/config.php files?

Currently I am having to include these in each of my service methods (and something similar again in my javascript files):

private function _saveStripeCustomer($account, $token = NULL)
{
    \Stripe::setApiKey("sk_test_xxxxxxxxxxxxxxxxxx");
    // ...
}

I am generally following the configuration method shown here (both multi-environment and multi-locale). And a plugin config.php as described here.

You can insert whatever settings you need either in your config/general.php file, config/pluginhandle.php, or the plugin/config.php file.

You can have different value for your setting in each of the environments you have defined. If you call your setting myplugin_stripe_key, you'd put something like this in your config file:

return array(
    '*' => array(
      ...
    ),

    'local' => array(
        'myplugin_stripe_key' => 'sk_test_xxxxxxxxxxxxxxxxxx',
        ...
    ),

    'stage' => array(
        'myplugin_stripe_key' => 'sk_stage_xxxxxxxxxxxxxxxxxx',
        ...
    ),

    'prod' => array(
        'myplugin_stripe_key' => 'sk_prod_xxxxxxxxxxxxxxxxxx',
        ...
    )
);

In your plugin:

private function _saveStripeCustomer($account, $token = NULL)
{
  \Stripe::setApiKey(craft()->config->get('myplugin_stripe_key'));
  // ...
}

If you use this several places in your service, I'd fetch all settings in the constructor and save them in an array:

class MypluginService extends BaseApplicationComponent
{
    var $settings = array();

    public function __construct($urlRecord = null)
    {
        $this->settings = $this->_initSettings();
    }

    private function _initSettings()
    {
        $settings = array();
        $settings['myplugin_stripe_key'] = craft()->config->get('myplugin_stripe_key');
        return $settings;
    }
}

Then you can access them later like this:

\Stripe::setApiKey($this->settings['myplugin_stripe_key']);

If you need this key in javascript, you could create a craft variable that gets the config setting and output it to a javascript variable somewhere in your twig templates. You'd basically use the same way to get the config variable inside the craft variable method.


__PHP_Incomplete_Class retrieved from session I am storing a plugin model in session:

$sessionModel = My_Model::populateModel([
    'token' => 'someData'
]);

craft()->httpSession->add('someKey', $sessionModel);

When I retrieve that later:

$sessionModel = craft()->httpSession->get('someKey');

Craft::dd($sessionModel);

I get this:

__PHP_Incomplete_Class#1
(
    [__PHP_Incomplete_Class_Name] => 'Craft\\My_Model'
    [*:classSuffix] => 'Model'
    [*:strictAttributes] => true
    [Craft\BaseModel:_classHandle] => null
    [Craft\BaseModel:_attributeConfigs] => array
    (
        'token' => array
        (
            'type' => 'string'
            'required' => true
        )
    )
    [Craft\BaseModel:_attributes] => array
    (
        'token' => array
        (
            'token' => 'someData'
        )
    )
    [Craft\BaseModel:_extraAttributeNames] => null
    [CModel:_errors] => array()
    [CModel:_validators] => null
    [CModel:_scenario] => ''
    [CComponent:_e] => null
    [CComponent:_m] => null
)

Is there a better way to store a model in session? Should it be serialised and unserialised in some way?

Save yourself the headache and don't store an entire Model in session.  More to the point, don't store any complex objects in session.

It's much better practice to store just the information you need in session to create the model when it's needed (i.e. some unique ID).  You won't run into issues like you're seeing and you won't be using unnecessary server resources serializing and unserializing these complex objects.

You can see the reason you're getting the error on this page.


Why does my entry language selection look different from examples? All the examples look like this:

Mine looks like the image below where you have to select the site from that top left dropdown and then there are some enabled things on the right:

The top screenshot is from Craft 2. The entry language selector (technically, the entry site selector since Craft 3) was redesigned with Craft 3.


If Most Recent Instance of a Block Contains X in Y Field Then Do Z I’m looping through blocks in a matrix field on a page. In multiple different blocks in that loop, all of which could be different block types, I’d like to have an if statement that basically says if the most recent instance of a particular block type (we'll call it "referenceBlockType") contains x in y field, then do z. Note that by most recent instance I mean the closest previous instance of referenceBlockType relative to the position of the block that contains the if statement.

referenceBlockType appears multiple times in the loop and is not necessarily a direct sibling of the block that is referencing it, nor is it always the first or last field in the loop.

How would I do that? Thanks!

My answer is based on the assumption you only have one matrix module you want to compare, otherwise you would have to store your values in an array with the key as block.getType().handle or you would have to create multiple variables.

You want to create a variable that stores the value of your field if the block handle matches. So you check if your handles are equal and compare them

{% set latestBlockValue = null %}
{% for block in entry.matrix %}
    {% if block.getType().handle == 'referenceBlockType' %}
        {% if latestBlockValue is not null and latestBlockValue == x %}
            {# z #}
        {% endif %}
        {% set latestBlockValue = block.y %}
    {% endif %}
{% endfor %}


Dropdown field value getting outputted multiple times I have a dropdown field that has three options. In my template, I want to do one thing if option 1 is selected and do something else if option 2 is selected.

Here is what my code looks like:

{% for option in entry.transparentMenu.options %}
    {% if entry.transparentMenu.value == "menuLight" %}

white

    {% elseif entry.transparentMenu.value == "menuDark" %}

black

    {% endif %}
{% endfor %}

The code seems to work but the output is: black black black; I only want black to display once.

What am I doing wrong?

You don't need the for loop in this case. What's happening is you're looping over each option in your dropdown field, and each time it's checking the value of the dropdown and displaying white or black. Since you have three options, you're going to get the dropdown value displayed three times (which is why you're seeing black black black).

All you need is just the if conditional:

{% if entry.transparentMenu.value == "menuLight" %}

white

{% elseif entry.transparentMenu.value == "menuDark" %}

black

{% endif %}

  Also, fwiw looks like you have a typo in your code  - you use entry.transparentMenu twice and entry.header.transparentMenu once. I'm guessing you want entry.transparentMenu everywhere...

The only time you'd want to use the for loop to get all the dropdown field's options is if you wanted to display those in the template (in a list for example or to create your own dropdown on the frontend):

    {% for option in entry.dropdownFieldHandle.options %}

{{ option }}

    {% endfor %}

But in your case, you just want the current value and not all the options, so just remove the for loop.


Limiting entries object when using as json_encode I'm building a JSON array of several thousand entries using the following entries query:
{% set services = craft.entries.section('services').asArray().all() %}
The problem is there some private info is visible within the JSON and can be viewed in the browser source (not to mention the result is HUGE.
let services = {{ services | json_encode | raw }};
Is there a parameter similar to ids() where I can specify only the title, url, and ID?
If not, what's the best Twig way to reduce this array to what I'm looking for?

As per the docs:

Element queries are specialized query builders under the hood, so they
support most of the same methods provided by craft\db\Query.

...So, in your case you could use select() to only select the fields you want:
{% set services = craft.entries.section('services').asArray().select(['title','id','url']).all() %}


Can't open new single section I created a new Single section and named it "test", added some content and tried to view it on domain.com/test. Unfortunately I get my default server 404 and not the new single section.

I tried to add a new route using "test" => "_layout" but can't see any change.

Do you have any idea why this isn't working?

EDIT:

Here the both screenshots.

http://i.stack.imgur.com/RtgBB.jpg

http://i.stack.imgur.com/JomkJ.jpg

I hope that helps.

You will need to add a template called test.html that extends the "_layout.html" template. The layout template is just a wrapper template, and with the "_" in front of it, it will always be invisible to a browser.

Take a look at the twig references on extending templates. Also look at the templates supplied with the initial install to get a better idea how this works.

Twig Extend

Routes are for more refined routing of templates and you should not need a route for current implementation.

Imagine if "_layout.html" were named "_wrapper.html" and it makes a little more sense.


How do I display entries, grouped by distinct categories where the entries share a relationship to both the category and an entry in another channel I have 2 channels:survivors, survivorContent and a Category:themes. Relationships are as follows:
survivorContent has -> related themes (max 3) AND survivorContent has -> related survivors (max 1)

Themes are always only one level deep.

I have a template that receives survivor.slug as a variable (based on a route). Given the survivor slug, I need to show a list of distinct themes that are indirectly related to this survivor (via the survivorContent->survivor relationship and the survivorContent->themes relationship). Then I need to show the survivorContent entries under each of those filtered themes that are related to both that theme and the given survivor to get output like this:

Survivor.title

Related Theme 1

Related survivorContent1 (related to both the Survivor & Theme 1)

Related survivorContent2 (related to both the Survivor & Theme 1)

Related Theme 2

Related survivorContent3 (related to both the Survivor & Theme 2)

Related survivorContent1 (related to both the Survivor & Theme 2 as well as Theme 1, above)

etc...

I'm struggling to find a way to do this that is remotely efficient. Any ideas?

Set up a criteria model with both of your relatedTo conditions and add the hierarchy to the list of returned entries using Craft's group filter.

{% set relatedEntries = craft.entries({
    section: 'survivorContent',
    relatedTo: [
        'and',
        {targetElement: entry.themesField},
        {targetElement: entry.survivorsField}
    ]
}) %}

{% set relatedEntriesGrouped = relatedEntries|group('themesField.first().title') %}

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

In case you don't have a "max. 1 element" limit set on your relationship fields, you might also want to look into something like the following.

{% for theme in entry.themesField %}

    {% set relatedEntries = craft.entries({
        section: 'survivorContent',
        relatedTo: [
            'and',
            {targetElement: theme},
            {targetElement: entry.survivorsField}
        ]
    }) %}

    {% if relatedEntries|length %}
        {{ theme.title }}
        {% for entries in relatedEntries %}
            {{ entry.title }}
        {% endfor %}
    {% endif %}

{% endfor %}


Is there any way to set a default status for Entries, either globally or per Section? The subject more or less covers it — is there any way to set the default status for Entries, either on a Section by Section basis, or globally?

I have a client that doesn't want to accidentally set something live when they save something without deliberately setting it to published.

At the moment it looks like I have two options:

Create an un-Crafty "Publish" checkbox field that I check for in my templates.
Use User Groups to keep some users from publishing — this is a little overkill for them, though. They don't want to keep these people from publishing, just try to limit people publishing content without meaning to.

Your two options are the only ones thus far. If you would like this feature you can leave a post on the G+ group, or email them at: support@buildwithcraft.com


Hyperlinks in blog are not showing underlined I'm brand new to Craft, having been a Wordpress user. I'm managing a site for a small charity.
Having done some new pages and a blog page without any problem, I did a blog yesterday in which the hyperlinks are live are not visible (ie not showing as underlined). I've tried various different routes for getting the text to use, and tried a new blog, but with no luck.
Can anyone help me? ...in as plain English as possible please, I'm not familiar yet with html or Craft language.
The blog post I've don that is fine is:
https://timetoshineleeds.org/blog/learning-lunches-and-breakfasts-and-teas
\the blog post that won't show the hyperlinks is:
https://timetoshineleeds.org/blog/free-training-opportunity-project-management

Thank you very much
Rob

Hyperlink styles are defined in you stylesheet (CSS).

Applying the underline text-decoration property like so:

text-decoration: underline;


Graphql total results / pageinfo when searching with pagination I'm trying to build something to search my data that is stored in Craft with graphql.
To make pagination work I want to know how many results there are in total.

I'm doing a query like this:

query($search: String, $relatedTo: [Int]) {
  entries(section: "address", search: $search, orderBy: "companyName", relatedTo: $relatedTo, limit: 10, offset: 0) {
    searchScore,
    ... on address_address_Entry {
      sid,
      address_title,
    }
  }
}

Truncated for readability

I set a limit and an offset to see the first 10 results.
But i also need to know the total amount to determine how many pages there are

I've seen that there is a _count field of type Int on the entryInterface which says "Return a number of related elements for a field." But it seems to just give me the field's value itself, if I, for example, add it like this:

query($search: String, $relatedTo: [Int]) {
  entries(section: "address", search: $search, ... same) {
    _count:id,
  }
}

It just adds in the response {"_count": "8154"} (which is the id, so not very usefull)

I've looked at graphql docs:
https://graphql.org/learn/pagination/

But it doesn't work to just add 'pageInfo' or 'totalCount', neither does the cursor stuff.

Any help to get this working is welcome!

Try entryCount. You can also add arguments to this, such as section: entryCount(section:"news"), for example.


Multiple issues with User Registration from frontend I am not able to get User Registration to work properly using a frontend form from the Craft Docs (https://craftcms.com/docs/templating/user-registration-form).

Here are the particulars:

Craft Pro Version = 2.6.2791

Users > Settings has the ‘verify email addresses’ and ‘allow public registration’ boxes checked, and a default User group selected

I specified a redirect in craft > config > general to 'activateAccountSuccessPath' => 'registration-success',

The form submits and the user is created, but no verification email is sent and the user is not assigned to the group I selected in User Settings. If I manually send a verification email, following the link causes the user to be verified, but still not added to any Group. Further, the user is redirected to http://sitename/dashboard, despite having a redirect set in the Config > General file.

I tried this on two different Craft sites, each on different hosts (one of which is Arcustech) and both of which are running the latest Craft release (2.6.2791).

The form submits and the user is created, but no verification email is sent and the user is not assigned to the group I selected in User Settings.

That sounds like there is a validation error is happening in your form on the UserModel.  Perhaps on a required custom field. You didn't share your form, but is it checking for errors?

  If I manually send a verification email, following the link causes the user to be verified, but still not added to any Group.

Make sure you're not running any plugins that might be interfering listening to the onSaveUser event.

  Further, the user is redirected to http://sitename/dashboard, despite having a redirect set in the Config > General file.

That's a bug that's been fixed for the next (post 2.6.2791) release.


Craft Commerce - Create Order from Control Panel We've been looking around to get some info for this feature but didn't find anything yet and wanted to ask here in case we are missing something.

Is there a way to create an order from the Control Panel?

We are working on a project that needs to track orders not done via the website and will need the ability to create manual orders from the CP but this feature doesn't seem to exist in Craft Commerce.

Does anyone know if there is a 3rd party plugin that we might have missed that allows this functionality? Or if this is a feature that might be considered in the future scope of Craft Commerce?

Thanks heaps,
Alby

There is currently no way to do this from the control panel unfortunately.

It's been said a bunch of times it's on the roadmap, and it's an oft requested feature.

I don't think there is a generalised plugin for this yet.  I doubt there will be as it's coming to core.

It's certainly possible to write one, but it would be a fair bit of work.

(You could quickly hack something together in the form of a form that lists all your products and uses MultiAdd to add them to a cart in one go...but you'd still have to go through checkout to complete the order.  https://github.com/engram-design/MultiAdd


I am unable to successfully submit guest entries I am trying to submit a guest entry it keeps returning a fatal error. This is my code

<form method="post" action="" accept-charset="UTF-8">
{{ getCsrfInput() }}
<input type="hidden" name="action" value="guestEntries/saveEntry">
<input type="hidden" name="redirect" value="success">
<input type="hidden" name="profile" value="3">

Title
<input id="title" type="text" name="title">

Body
<textarea id="body" name="fields[body]"></textarea>

<input type="submit" value="Publish">
</form>

As per the documentation, you need to include a hidden sectionId field. This specifies the section to which the entry will be submitted.


Add a form field into the details bar on the entry edit screen and do something with the value I'd like to add a form field into the details bar on the entry edit page, so that when the entry gets submitted, the form field value gets passed into the data payload so that I can pick it up from the EVENT_BEFORE_SAVE event.
However, it does not seem to get passed into the data I can see in that hook. Is there any way to do this? I want to give the user an option to tick a box that on save of the entry, it sends some data off to a third party API.

Just take your value direct from the $_POST array.


How we can set an image as default value in assets field I have a field for upload an image in asset field. Can we set a default image in this field. Means when I create a new entry a default image has been already selected in asset field.

That's not possible, but the way I handle this is to have a Global called "Missing Image Fallback" inside a "Generic" Global field set, and then when I need to reference an image I use the following twig:

{% set image = entry.myImageField.first ?? generic.missingImageFallback.first %}

That will assign the first myImageField asset to 'image' if it's been filled in, but fall back to the generic global field if not.


Looking to export product listings from Salesforce and importing into Craft Commerce? I've been trying to find an approach where one could import product listings from Salesforce directly into one of my product types in Craft Commerce. It seems like my only option at this point is to write a plugin that can accomplish this. I recently found a post that mentioned that I would need to use the Salesforce PHP Toolkit to effectively make REST API calls from my platform.

The only issue is I don't know exactly where to start.  Can anyone provide some suggestions or advice on how to handle this problem?

Generally speaking, it looks like you'd need to create a Craft plugin that imported the Salesforce PHP Tookit library/classes.  From there you'd query your Salesforce web endpoint for the data you're looking for.

Once the data gets back, you'd programatically create the products using Commerce's service layer API.  You can see any example of that Commerce uses itself to populate default content on a fresh installation in the Commerce_InstallSeeder class in commerce/Commerce/Seed.


no element type exists with getCriteria and custom element type I am working on a plugin using the getCriteria function, but for every Element Type I put, I always get an error:

  No element type exists by the type “Comerce_Group”.

$criteria = craft()->elements->getCriteria("Comerce_Group");
$criteria->number = $number;
return $criteria->first();

And here is the Comerce_Group code:

class Comerce_GroupModel extends BaseModel
{
    protected function defineAttributes()
    {
        return array (
            'id' => AttributeType::Number,
            'number' => AttributeType::String,
            'itemTotal' => AttributeType::Number,
        );
    }
}

As Stephen pointed out, you're getting that error because your Commerce_GroupModel class is a Model that extends BaseModel, not an Element Type, which is what ElementsService->getCriteria() is looking for.

Are you sure you actually need a custom element type here?  Depending on what you're going for, Models might be enough.


Is there a way to retrieve the last date of an event using the Solspace calendar plugin? I want to output a list of events some of which are repeating, on a monthly basis. Each event should show up once even if it's scheduled to repeat multiple times in the same month and the information for each event must also include the date of last occurrence if there is one.

To be a little bit more specific I would like to access the value of the field "End repeat" when it's value is set to "On date".

Is this possible?

Do you mean this?

{% set eventOptions = {
    dateRangeStart: targetStartDate,
    dateRangeEnd: targetEndDate,
    limit: 15,
    search: "EndrepeatHandle:On date"
} %}
{% set events = craft.calendar.events(eventOptions) %}


Custom element type defineSearchableAttributes I have a custom element type with 2 custom fields, 'name' and 'email'.
I can't seem to get the index search working for this element type.
I defined defineSearchableAttributes and returned an array with these 2 attributes.
Searching on the title field works though.

<?php
namespace Craft;

class Newsletter_SubscriptionElementType extends BaseElementType {

public function getName() {
    return Craft::t('Subscriptions');
}

public function hasContent() {
    return true;
}

public function hasTitles() {
    return true;
}

public function populateElementModel($row) {
    return Newsletter_SubscriptionModel::populateModel($row);
}

public function defineCriteriaAttributes() {
    return array(
        'name'      => AttributeType::String,
        'email'     => AttributeType::Email
    );
}

public function defineSearchableAttributes() {
    return array('name','email');
}

public function defineTableAttributes() {
    $attributes = array(
        'title'         => Craft::t('Title'),
        'name'          => Craft::t('Name'),
        'email'         => Craft::t('Email'),
        'dateCreated'   => Craft::t('Date Created')
    );

    return $attributes;
}

public function getTableAttributeHtml(BaseElementModel $element, $attribute) {
    return parent::getTableAttributeHtml($element, $attribute);
}

public function getSources($context = null) {
    $sources = array(
        '*' => array(
            'label'    => Craft::t('All subscriptions'),
        )
    );

    return $sources;
}

public function modifyElementsQuery(DbCommand $query, ElementCriteriaModel $criteria) {
    $query
        ->addSelect('newsletter_subscriptions.name, newsletter_subscriptions.email')
        ->join('newsletter_subscriptions newsletter_subscriptions', 'newsletter_subscriptions.id = elements.id');
}
}

Craft will only extract the search keywords for an element during the element saving process.

If you have existing custom elements already saved, then you go in and add the defineSearchableAttributes() to your element type, you'll need to re-save the existing elements in order for their search keywords to be indexed.

Or now that I think about it... the easier way would probably be to just run the "Update Search Indexes" tool in the Control Panel under Settings->Tools. It will do the same thing for you.


Custom login/profile sections? Apologies if this has been asked before, I couldn't find any documentation specifically about it.

I come from a largely WordPress background but am looking into using Craft Pro for a new client that'll need user registration (real estate website), but I don't want said users to be able to get to the actual CMS backend, rather a simple sort of 'my account' page where it saves their listed properties etc.

Are these sorts of things difficult to pull off in Craft? It seems like this aspect of site dev is quite strictly locked down from what I can extrapolate.

Its not at all difficult. Here's the example form from the docs:

https://craftcms.com/docs/templating/user-registration-form

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

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

                {% for error in errors %}

{{ error }}

                {% endfor %}

        {% endif %}
    {% endmacro %}

    {% from _self import errorList %}

Username

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

    {% if account is defined %}
        {{ errorList(account.getErrors('username')) }}
    {% endif %}

Email

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

    {% if account is defined %}
        {{ errorList(account.getErrors('email')) }}
    {% endif %}

Password

    <input id="password" type="password" name="password">

    {% if account is defined %}
        {{ errorList(account.getErrors('password')) }}
    {% endif %}

    <input type="submit" value="Register">
</form>

And you can find a login form here: https://craftcms.com/docs/templating/user-profile-form

And a profile editing template here:
https://craftcms.com/docs/templating/user-profile-form

Also remember that you can use all kinds of custom fields on your users


Problem with entry.hasDescendants() So I have a Structure like that

Item

Subitem | inactive
Subitem | inactive

why is item.hasDescendants() true ?

How would I do something like that the right way:

<li class="{% if nav_item.hasDescendants() %}more{% endif %}">

hasDescendants() is only concerned with whether the entry actually has descendants; not whether they are enabled or not.

To determine in an entry has enabled descendants, you can do this:

{% set hasDescendants = entry.descendants.total() %}

Or in your case:

<li class="{% if nav_item.descendants.total() %}more{% endif %}">

entry.descendants is an alias for EntryModel::getDescendants(), which will return a new ElementCriteriaModel prepped to return descendants of entry. By default it will only return the enabled ones, like all ElementCriteriaModel’s.


Architecting a Solution with many Sites within a Site (Chapters) - How many sections can Craft Handle? I am working on a plan for a site build that includes national content as well as many chapters' content. The latter has a number of requirements that are leading me to using separate sections including a structure for general pages and news, and events channels.

So looking at 3 sections per chapter and starting with around 20 chapters with more to come over time.

I am not worried about the manual setup of these (albeit it's not ideal); however, I am concerned about hitting limits either in the interface and/or performance of Craft that I just may not be as familiar with.

As chapter numbers grow, will this be too many sections for Craft to handle?

As chapter numbers grow, will this be too many sections for Craft to handle?

Probably not.  I suspect as your section list grows to the multi-thousand section range (if it will ever get that large), you'll start to run into MySQL/environmental limitations rather than any Craft ones.  But if  you do run into any UI/architectural limitations, we'd love to hear about them.

In the upcoming Craft 2.3 release, we spent a great deal of time addressing UI scaling issues around Structured Sections and Categories when they start to approach the multi-thousand range, but we've seem installations with several hundred thousands of Channel entries/assets/users running just fine.


ADLDAP plugin in Craft 2.6 - New User Required In Craft Table? I'm pretty new to Craft, and we have been trying to implement a front end LDAP authentication to our website at my organization.  I found the ADLDAP plugin and have been testing it with the website.

Here's the link to the AdldapController.php file that seems to have most of the logic for the plugin:
https://github.com/thepitagroup/adldap_craftcms/blob/master/adldap/controllers/AdldapController.php

I was looking at the code in the AdldapController.php file and was wondering if the check for a matching username in Craft is necessary?

To clarify, my organization only desires to authenticate by Active directory.  It looks like this script is also checking to see if the user exists in the local craft user table (line 62). (Am I correct in understanding that this script will put the username/password combo from active directory verbatim into the MySQL table for future use, or is a new craft-only password generated?) Can this block of code be omitted as an 'option?' Pros/cons?

Thanks for any leads or input.

In order to navigate as a user in craft the user needs a record in the users table. So what the plugin does is the following

Starting an authentication by active directory
If the login credentials are correct it searches if a craft user exists
If there is no craft user connected to the active directory user it creates a new user with the same name/password like he/she has in active directory
If there is a craft user instead of checking the password with the craft user - in case you changed it in active directory - it just overwrites the current craft user password every single time a user tries to login. The password will be crypted only for craft. There are no changes to your active directory

In summary: you don't need to be afraid, there are no changes in active directory but every time a user tries to login his password will be stored into the db again and again.

The Code is not optional, you have to store the active directory user as a craft user in order to change their permissions otherwise they won't be able to login to the backend or make any changes unless you implement your own logic/controllers to manage the content.

Edit
just some more thoughts: If your users won't be able to login to the backend and should be able to make changes only via frontend requests, there is no need to store them as craft users, so you could eventually(!) - depends on the rest of the plugin - remove that block but you won't be able to use crafts build-in functions like detecting which user made certain changes.

You would have to create a custom logic to give them permissions (if needed) and you would have to log user activities by yourself (if needed). So if you want to see who did something you have to include a custom username field for every entry.

Furthermore you can't use the craft->userSession service to get current user information and you have to implement logic that the user is actually logged in by yourself (store some values in the $_SESSION) You can't use crafts currentUser global in twig as well -> you need a custom twig extension or a custom function.

All controller actions must be allowed for everyone so they can't access all the craft default controllers since most of them don't allow anonymous requests.


Target second (or nth) element in a for loop I'm trying to show content for only the second entry in a for loop, but can't find any info on how to do specifically this. I'd like to do something like the below.

{% for relatedImage in entry.relatedImages %}
    {% for images in relatedImage.image %}

             {% if loop.index == 2 %}

Welcome!

{% endif %}

    {% endfor %}
{% endfor %}

Any ideas?

It's not working because you're using loop.index in the context of the inner loop.

Based on your comment, there will only ever be one images selected, so loop.index will never be 2.

If you don't want to move the loop.index check to the outer loop, then a simple counter will work:

{% set counter = 0 %}

{% for relatedImage in entry.relatedImages %}
    {% set counter = counter + 1 %}

    {% for images in relatedImage.image %}

             {% if counter == 2 %}

Welcome!

{% endif %}

    {% endfor %}

{% endfor %}


How to update stock on a product variant? Setting unknown property error I am trying to update stock of product variants using a custom plugin on our Craft 3 eCommerce site (its a sync process with an external database). But I can't figure out how to update stock, I get an unknown property error for the field stock.
use Craft;
use craft\web\Controller;
use craft\helpers\ElementHelper;
use craft\commerce\elements\Product;

$productEntry = Product::find()->hasVariant(['sku' => 'mysku'])->first();
if($productEntry)
{
    if (!$productEntry->hasUnlimitedStock)
    {
        $productEntry->setFieldValue('stock', '10');
        echo Craft::$app->elements->saveElement($productEntry);
    }
}

But I get a "Setting unknown property: craft\behaviors\CustomFieldBehavior::stock" error:-
2021-01-18 11:21:33 [-][1][9319132c27bbf8aa77f29e2606c2b4ea][error][yii\base\UnknownPropertyException] yii\base\UnknownPropertyException: Setting unknown property: craft\behaviors\CustomFieldBehavior::stock in /home/mysite/craftcms/vendor/yiisoft/yii2/base/BaseObject.php:163
Stack trace:
#0 /home/mysite/craftcms/storage/runtime/compiled_classes/CustomFieldBehavior_zmbofhbcdvie.php(895): yii\base\BaseObject->__set('stock', '10')
#1 /home/mysite/craftcms/vendor/craftcms/cms/src/base/Element.php(2672): craft\behaviors\CustomFieldBehavior->__set('stock', '10')
#2 /home/mysite/craftcms/plugins/mysite/src/controllers/SyncController.php(225): craft\base\Element->setFieldValue('stock', '10')
#3 /home/mysite/craftcms/plugins/mysite/src/controllers/SyncController.php(90): mysite\mysite\controllers\SyncController->updateEntries(Array)
#4 [internal function]: mysite\mysite\controllers\SyncController->actionSyncStock()
#5 /home/mysite/craftcms/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array)
#6 /home/mysite/craftcms/vendor/yiisoft/yii2/base/Controller.php(180): yii\base\InlineAction->runWithParams(Array)
#7 /home/mysite/craftcms/vendor/craftcms/cms/src/web/Controller.php(190): yii\base\Controller->runAction('sync-stock', Array)
#8 /home/mysite/craftcms/vendor/yiisoft/yii2/base/Module.php(528): craft\web\Controller->runAction('sync-stock', Array)
#9 /home/mysite/craftcms/vendor/craftcms/cms/src/web/Application.php(274): yii\base\Module->runAction('mysite/sync/sy...', Array)
#10 /home/mysite/craftcms/vendor/craftcms/cms/src/web/Application.php(577): craft\web\Application->runAction('mysite/sync/sy...', Array)
#11 /home/mysite/craftcms/vendor/craftcms/cms/src/web/Application.php(253): craft\web\Application->_processActionRequest(Object(craft\web\Request))
#12 /home/mysite/craftcms/vendor/yiisoft/yii2/base/Application.php(386): craft\web\Application->handleRequest(Object(craft\web\Request))
#13 /home/mysite/public_html/index.php(23): yii\base\Application->run()
#14 {main}
2021-01-18 11:21:32 [-][1][9319132c27bbf8aa77f29e2606c2b4ea][info][application] $_GET = [
    'p' => 'actions/mysite/sync/sync-stock'
]

Have figured it out. Need to:

use craft\commerce\elements\Variant; // not Product
setFieldValue still does not find variable stock with Variant, but set it using $variantEntry->stock = 20;
Need to find() on Variant to return the actual variant, and not
find product with variant as that returns the product

Following works, changed $productEntry to $variantEntry
use Craft;
use craft\web\Controller;
use craft\helpers\ElementHelper;
use craft\commerce\elements\Variant;

$variantEntry = Variant::find()->sku('mysku')->first();
if($variantEntry)
{
    if (!$variantEntry->hasUnlimitedStock)
    {
        $variantEntry->stock = 20;
        echo Craft::$app->elements->saveElement($variantEntry);
    }
}


Craft 2 Commerce 1 cart session expiry Is it possible to change the cookie timeout just for the cart?  E.g. I'd like to clear abandoned carts after X hours and keep all the other sessions untouched (e.g. user sessions etc).

Please advise anyone!

Create a commerce.php config file in your config folder and set the cartCookieDuration to a time interval. The default is 3 months.

<?php
return [
    'cartCookieDuration' => 'P3M',
    'purgeInactiveCarts' => true,
    'purgeInactiveCartsDuration' => 'P3M',
];


A/B testing - how to in Craft? What's your process for A/B testing a Craft entry? I'm curious about how you'd structure alternative content for a page within Craft and what tools you'd use to measure the results.

Any comments appreciated - I know there are lots of different ways you could approach this!

You can set a cookie from your template, which assigns visitors to specific groups:

Craft 2: (Use the LJ Cookies plugin)

{% set testGroup = craft.lj_cookies.get('group') %}

{% if not testGroup %}
    {# New user - assign them to a group at random #}
    {% set testGroup = random(['a', 'b']) %}
    {% set expires = now|date_modify('+30 days').timestamp %}
    {% do craft.lj_cookies.set('group', testGroup, expires) %}
{% endif %}

Craft 3:

{% set testGroup = craft.app.request.cookies.get('group') %}

{% if not testGroup %}
    {# New user - assign them to a group at random #}
    {% set testGroup = random(['a', 'b']) %}
    {% set expires = now|date_modify('+30 days').timestamp %}
    {% do craft.app.response.cookies.add(create({
        class: 'yii\\web\\Cookie',
        name: 'group',
        value: testGroup,
        httpOnly: true
    }) %}
{% endif %}

And then reference that testGroup variable whenever you need to know which group they’re in:

{% switch testGroup %}
    {% case 'a' %}
        ....
    {% case 'b' %}
        ....
{% endswitch %}

Nice thing about this approach is that you can actually have multiple sets of test groups at the same time, using different cookie/variable names. You’re also not limited to two groups per set.


Edit user's first and last name I have added a form to my front-end to edit the user's first and last name. Editing all the other fields is not a problem but when I try to edit the first or last name it doesn't work.

I think I might need to change name="fields[firstName]" to something else, but I don't know to what I should change it to.

<form method="post" id="loginForm" accept-charset="UTF-8" enctype="multipart/form-data">
    {{ getCsrfInput() }}

{{'Profiel bewerken'|upper}}

    <input type="hidden" name="action" value="users/saveUser">
    <input type="hidden" name="redirect" value="profile">
    <input type="hidden" name="userId" value="{{ currentUser.id }}">

    {{"voornaam"|title}}
    <input type="text" id="voornaam" name="fields[firstName]"
    {% if currentUser.firstName %}value="{{ currentUser.firstName }}"{% endif %}>

    {{"achternaam"|title}}
    <input type="text" id="achternaam" name="fields[lastName]"
    {% if currentUser.lastName %}value="{{ currentUser.lastName }}"{% endif %}>

    {{"woonplaats"|title}}
    <input type="text" id="woonplaats" name="fields[woonplaats]"
    {% if currentUser.woonplaats %}value="{{ currentUser.woonplaats }}"{% endif %}>

    {{"postcode"|title}}
    <input type="text" id="postcode" name="fields[postcode]"
    {% if currentUser.postcode %}value="{{ currentUser.postcode }}"{% endif %}>

    {{"adres"|title}}
    <input type="text" id="adres" name="fields[adres]"
    {% if currentUser.adres %}value="{{ currentUser.adres }}"{% endif %}>

    {# Check to see if the user has a photo  #}
    Profielfoto

    {% if currentUser.photoUrl %}

        <input type="file" name="userPhoto" value="Change Photo">
    {% else %}
        {# If no photo exists, give the option to upload a new one #}
        <input type="file" name="userPhoto" value="Upload">
    {% endif %}

    {# <input type="file" name="userPhoto" value="{{ (currentUser.photoUrl ? 'Change Photo' : 'Upload') }}"> #}

<button type="submit">Opslaan</button>

</form>

A User's first and last name fields don't need the fields[] prefix as they aren't custom fields added to the user field group.

So using the following should work:

{{"voornaam"|title}}
<input type="text" id="voornaam" name="firstName"
{% if currentUser.firstName %}value="{{ currentUser.firstName }}"{% endif %}>

{{"achternaam"|title}}
<input type="text" id="achternaam" name="lastName"
{% if currentUser.lastName %}value="{{ currentUser.lastName }}"{% endif %}>


Understanding Eager Loading I am trying to get to grips with Eager Loading. I have the following code:

{% for article in entry.relatedArticles %}

            {% set array = article.title|split(' ', 2) %}

{{ attribute(array, 0) }} {{ attribute(array, 1) }}

Posted on {{ helpers.date_formatted(entry.postDate) }}

Related Article

                        {{ article.title }}

                        <time datetime="{{ entry.postDate|date('Y-m-d H:i:s') }}" class="date">
                            <svg role="img" class="icon // icon-date" title="Date Icon">
                                <use xlink:href="/assets/img/icons.svg#icon-date"></use>
                            </svg>{{ helpers.date_formatted(entry.postDate) }}
                        </time>

Read Article

{% endfor %}

Looking on the console this combined with the other page requests totals 76 requests. I thought I perhaps should add some eager loading 9at least tot he image transform) So I tried the following:

{% for article in entry.relatedArticles.withTransforms('cardImage') %}

            {% set array = article.title|split(' ', 2) %}

{{ attribute(array, 0) }} {{ attribute(array, 1) }}

Posted on {{ helpers.date_formatted(entry.postDate) }}

Related Article

                        {{ article.title }}

                        <time datetime="{{ entry.postDate|date('Y-m-d H:i:s') }}" class="date">
                            <svg role="img" class="icon // icon-date" title="Date Icon">
                                <use xlink:href="/assets/img/icons.svg#icon-date"></use>
                            </svg>{{ helpers.date_formatted(entry.postDate) }}
                        </time>

Read Article

{% endfor %}

However, this also still results in 76 requests.

So my question is this; Have I misunderstood when I need to use Eager Loading? or is my code incorrect and thus eager loading isn't actually taking place?

Thanks.

Your syntax is a bit off.

The withTransforms parameter is an Asset criteria, meaning it is only relevant when you're pulling Assets. Appending it to entry.relatedArticles (an Entries field, returning an ElementCriteriaModel) like you're currently attempting does nothing, but this does:

{% set assets = entry.someAssetsField.find({
    withTransforms: ['someTransform', 'someOtherTransform']
}) %}

This means your current code should probably be refactored to look something like this (simplified):

{% for article in entry.relatedArticles %}
    ...
    {% set bannerImage = article.bannerImage.find({
        withTransforms: ['cardImage']
    })[0] ?? null %}
    {% if bannerImage %}

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

Assuming there's not a ton of relatedArticles entries, and considering the fact that there's only one image per entry, the above might not make a huge impact on your performance. To take things a step further, you might consider eager loading the actual Asset field(s) as well as their transforms. There's a couple of ways to do this – you could use the same approach as above, adding the eager loading criteria to the Entries field relatedArticles:

{% set relatedArticles = entry.relatedArticles.find({
  with: [
      ['bannerImage', {
          withTransforms: ['cardImage']
      }]
  ]
}) %}
{% for article in relatedArticles %}
    ...
    {% set bannerImage = article.bannerImage[0] ?? null %}
    {% if bannerImage %}

    {% endif %}
{% endfor %}

...or you could use a more "traditional" eager loading approach, using craft.entries and the relatedTo parameter:

{% for article in craft.entries({
    relatedTo: {
      sourceElement: entry,
      field: 'relatedArticles'
    },
    with: [
        ['bannerImage', {
            withTransforms: ['cardImage']
        }]
    ]
}) %}
    ...
    {% set bannerImage = article.bannerImage[0] ?? null %}
    {% if bannerImage %}

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

With the above, assuming there's a fair amount of entries involved you'll probably see a decrease in the number of queries executed.

If you want to learn more about eager loading, I recommend taking a look at the official docs on the subject.


How do I create a structure side navigation that will show active parent list-item and active child list-item A bit of a background on the project. I have a features structure section, that has 2 levels: Parent features & Child features.

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

My goal is to get an active class on the parent if the parent page is active or if it's got a child that is active and also get an active class on the child if its active.

The {% children %} tag doesn't allow for custom HTML.

I am looking to get something similar to this left navigation. But instead of anchors, each feature will be its own page.
https://craftcms.com/features/all#section-types

Thanks

After a long search and lots of trial and error, I've found the perfect solution!
This is how I created a dynamic structure navigation : parent/child (2 levels deep) with class="active" on the parent and the child
.

{# Get top-level entries in structure section 'features' #}
{% set parentFeatures = craft.entries.section('features').level(1) %}

{# Loop through top-level entries #}
{% for parentFeature in parentFeatures %}

    {# Check if entry has descendants/children #}
    {% if not parentFeature.hasDescendants %}

        {# List navigation item if entry has NO child entries #}

            {{ parentFeature.title }}

    {% else %}

        {# List navigation item if entry does have child entries #}
        {# Show an active class if it is active or if it contains a child that is active #}

            {{ parentFeature.title }}

                {# Get child entries of current iteration's top-level entry #}
                {% set subPages = parentFeature.getChildren() %}

                {# Loop through those 2nd-level entries #}
                {% for subPage in subPages %}

                    {# This is the place where you'd nest the next menu hierarchy !! #}

                    {# List sub-menu navigation item #}

                        {{ subPage.title }}

                {% endfor %}

    {% endif %}
{% endfor %}

Thanks to Carlcs's old answer about this found here: https://craftcms.stackexchange.com/a/1847/6586


ERROR: relation "assetindexdata_id_seq" already exists on new database I'm using PostgreSQL locally and everything is working as expected. However, when I decided to move/restore the database to the staging environment I am getting this error (even through the tables do not exist).

Has anyone experienced this before?

restore_pg_11.0: [archiver (db)] could not execute query: ERROR:  relation "assetindexdata_id_seq" already exists
    Command was: CREATE SEQUENCE public.assetindexdata_id_seq
    AS integer
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;

Not sure how the database backup was created and what's being used to restore it, but using this would fix the error:

CREATE SEQUENCE IF NOT EXISTS 'public.assetindexdata_id_seq'

Alternatively, if you delete the database to destroy all of the associated metadata, then it shouldn't matter.

https://www.postgresql.org/docs/9.5/sql-createsequence.html


How cumbersome is the content admin with 6 different languages Am considering Craft for multi lingual project that will use 6 languages including Arabic. Just how cumbersome does the admin of content become when localisation and translatable  are required for content types?

I was hoping to find some screen shots and get a basic idea of what it would look like from an administrators point of view.

Have a look at the video about the localization feature on the Craft Feature page, this should give you a really good impression on how it works.

There's one thing though, that I'd really like to see improved: a way to see which content is still the same across all locales and a way to keep content of a field in sync after the first entry save. See this feature request: http://feedback.buildwithcraft.com/forums/285221-feature-requests/suggestions/7187381-better-options-to-sync-content-across-locales.

Altogether I really, really like how localization is done in Craft, it's actually the feature that made me aware of it (I had lots of trouble with Wordpress mulitsite etc.). And I'm also rather sure that we will see some nice improvement to it over time (Craft is still a new CMS).


Displaying products from a category New to Craft Commerce and doing something pretty template intensive.

I am following this https://craftcommerce.com/support/product-taxonomy  and https://craftcommerce.com/support/products-related-to-category

My categories group handle "productCategories"
My categories field handle "whatFinish"
Categories so far are "metallic" and "standard"

This code returns a short list of both categories from the page above

{% nav category in product.productDepartments %}

    {{ category.title }}
    {% ifchildren %}

        {% children %}

    {% endifchildren %}

{% endnav %}

When I use this code with any of a variety of options to replace(category) I get a template error with a variable issue.

{# Fetch all of the products related to this category #}
{% set products = craft.commerce.products.relatedTo(category) %}

{# Output them #}
{% for product in products %}
    {{ product.title }}
{% endfor %}

Examples things I have tried:

          {# Fetch all of the products related to this category #}
{% set products = craft.commerce.products.relatedTo(standard) %}

{# Output them #}
{% for product in products %}
    {{ product.title }}
{% endfor %}

 {# Fetch all of the products related to this category #}
{% set products = craft.commerce.products('whatFinish').relatedTo(standard) %}

{# Output them #}
{% for product in products %}
    {{ product.title }}
{% endfor %}

{# Fetch all of the products related to this category #}
{% set products = craft.commerce.products('standard').relatedTo(whatFinish) %}

{# Output them #}
{% for product in products %}
    {{ product.title }}
{% endfor %}

Before to get all of the products (not desired as I want just the ones form a specific category) my code worked fine:

{% for product in craft.commerce.products.limit(5).find() %}

        {% set image = product.slider.first() %} {% if image %}
         {% endif %}

{% if product.url %}{{ product.link }}{% else %}{{ product.title }}{% endif %}

{% endfor %}

Do I need to bracket the category code with something I am not aware of? Sorry just completely lost here. I was directed to post form the support email.

Steph

{% set products = craft.commerce.products.relatedTo(category) %}

...is the correct code for finding products related to a category IF category is actually a Category Model at this point - e.g. it is the auto populated category variable in a template set to the template for that category group.  I would check, in the catgeory group settings, what you're using for the Category URL formats and the Category Template settings.

It would be also very helpful to know what's the actual error you are getting?


Why are my entries disappearing when {% if category | length %} is added? Editing an index page that displays all entries within a structure.

Everything displays fine.

I add a category to a few entries and add {% if category | length %}and everything disappears as if no entries had a category.

I get no twig errors, so I presume my code is okay.

Here it is, just in case:

          {% set entries = craft.entries.section('fellows').relatedTo(category) %}
      {% if category | length %}
        {% if entries | length %}
          {% for entry in entries %}
            {% for matrixBlock in entry.fellowsEntry %}
              {% if matrixBlock.type == 'entryContent' %}

                        {% for image in matrixBlock.fellowImage %}

                         {% endfor %}

{{ entry.title }}

{{ matrixBlock.organization }}

                        {{ category }}

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

My Category URL Formats was set-up incorrectly. Or rather, I needed to go to {handle}/{slug} to see the proper result.


Can I add a billing address while updating the cart? I'm designing a donation form right now for what will be a Craft Commerce site, and I want to collect the donator's billing name, address, etc in the product form which adds the donation to the cart. Will commerce/cart/updateCart accept billingAddress parameters when posted?

(I would simply test this, but I've not even started the build phase yet, and don't want to include the address fields on the donation form in my design if it won't be possible.)

Yes, you can submit all updates to the cart in the one controller action commerce/cart/update-cart


How to differentiate between positive and negative numbers in search I discovered today that searching a custom field for a number will return results containing either the positive or negative versions of the number, even if I do an exact search. For example: fieldName::"-2" will give me entries where that field contains either "2" or "-2". Same result if I search for fieldName::"2". The field in question is a "number" field.

Is there any workaround for this?

The reason it's happening:

When Craft's SearchService indexes the keywords for a field, they go though a normalization process that specifically removes punctuation and diacritics before being saved to the craft_searchindex table in the database.

In the case of numeric values, that's going to include things like decimals, grouping separators and negation symbols.

A workaround if you're doing this on a front-end search form, is to query the field's value directly, bypassing the SearchService. So...

{% set results = craft.entries.fieldName('-2').find() %}

Which is going to try and do a direct match against that field's actual value in the craft_content table.

There are a few feature requests you might want to add your voice to that would make your situation better as well:

https://github.com/craftcms/cms/issues/1630

https://github.com/craftcms/cms/issues/833


Custom validation for plugin settings As a follow-up to this thread, I would like to know how to create custom validation rules for plugin settings, or at least how to return field errors to the plugin settings view. I currently have:

<?php namespace Craft;

class SamplePlugin extends BasePlugin {

    function getName() { ... }
    function getVersion() { ... }
    function getDeveloper() { ... }
    function getDeveloperUrl() { ... }

    public function getSettingsHtml()
    {
        return craft()->templates->render('sample/settings', [
            'settings' => $this->getSettings()
        ]);
    }

    public function prepSettings($settings)
    {
        // I'm currently doing my 'custom' validation here. But if
        // there's an error, how do I display errors on the settings page?

        return $settings;
    }

    public function rules()
    {
        // Tried this, but since SamplePlugin isn't a Model, it does nothing.
    }

    protected function defineSettings()
    {
        return [
            'mySetting' => [
                AttributeType::String,
                'required' => true,
                // Can custom validation rules be set here?
            ]
        ];
    }

}

The solution provided here actually required some adjustments. Here is what ended up working:

In craft/plugins/sample/SamplePlugin.php:

<?php namespace Craft;

class SamplePlugin extends BasePlugin {

    function getName() { ... }
    function getVersion() { ... }
    function getDeveloper() { ... }
    function getDeveloperUrl() { ... }

    public function getSettingsHtml()
    {
        return craft()->templates->render('sample/settings', [
            'settings' => $this->getSettings()
        ]);
    }

    protected function getSettingsModel()
    {
        return new Sample_SettingsModel();
    }

}

In craft/plugins/sample/models/Sample_SettingsModel.php:

<?php namespace Craft;

class Sample_SettingsModel extends BaseModel {

    protected function defineAttributes()
    {
        return [
            'mySetting' => [
                AttributeType::String,
                'required' => true
            ]
        ];
    }

    public function rules()
    {
        $rules = parent::rules();
        $rules[] = ['mySetting', 'validateMySetting'];

        return $rules;
    }

    public function validateMySetting($attribute)
    {
        $value = $this->$attribute;

        if ( /* validation condition */) {
            $message = Craft::t("Error message");
            $this->addError($attribute, $message);
        }
    }

}


URL routing with types We need to setup following URL:

DOMAIN/{lang}/{family}/offers/{slug}

e.g.:

example.com/en/Larsen/offers/example

What do we need to configure our section URL? Have anyone an idea?

What is the type of field of family ?
You don't have to enter the domain and language. Just start from family and forward. If family is the title field, write it like this:

{title}/offers/{slug}

if the family field is an element type, do it like this:

{familyField.last().uri}/offers/{slug}

or

{familyField.last().slug}/offers/{slug}

or if it is a title

{title}/offers/{slug}


How to allow data attr in tags in Redactor HTML Purifer I am looking to allow data attr in tags with Redactor content.

What should I add to the Default config settings to allow this attr?

See this config setting: http://htmlpurifier.org/live/configdoc/plain.html#HTML.AllowedAttributes

You should be able to use it to allow data attributes.


Is it safe to move Craft Commerce Templates out of Plugin I installed Craft Commerce 2 and the templates are in vendor/craftcms/commerce/templates/shop. Is it safe to move these to my craft templates folder like this?

├── storage
...
│   └── runtime
├── templates
│   └── shop
├── vendor

Or are they where they are for a reason?

I don't really like the idea of drilling down into the vendor plugin directories to make changes, especially if they can be overwritten by composer during an update.

I don't want to introduce future problems.

David

You can copy them into your templates folder if you want to use them as a starting point.

I've added a mention of that into the installation docs here: https://docs.craftcms.com/commerce/v2/installation.html#example-templates


Is it possible to convert plain text array to an unordered list? I have a front end form with checkboxes which submits the data as an array into a plain text field in craft (named logGeneral_logInputIndications).

Here's an example of what the content looks in the plain text field in Craft CP:

["Abdominal Pain","RUQ","Vomiting",""]

Instead of outputting the field content in it's default state into my template, I'd like to convert it to an unordered list.  If I were to code it by hand it would look like this:

Abdominal Pain

RUQ

Vomiting

Any ideas if it's possible to do this?

(Mats answered the above question and his suggestion worked perfectly.)

However, I just realized that I have checkbox choices that contain non-alphanumeric content like Normal CBD (<0.4cm)  Is there a way to pick and choose which non-alphanumeric content I'd like to strip out vs keep?

Here's a new question that builds upon my initial one...

Is it possible to add a conditional to this?  Some of the text is really a child so it should be inset by another unordered list.  What my initial thought was is that perhaps I could add an identifier to the form input text if it's a child like "•" or something else, and then in the template, use that identifier in a conditional to say if you see "•" indent it and then strip the marker "•".

So then my plain text content would be:

["Abdominal Pain","•RUQ","Vomiting",""]

And my template code would look like this:

Abdominal Pain

RUQ

Vomiting

I was able to combine the suggestion Mats gave me with the following to conditionally indent child items.

{% set listItems = entry.logGeneral_logInputIndications|replace('/[^,()<>• a-zA-Z0-9_-]|[, ]$/s','')|split(',') %}

    {% if entry.logGeneral_logInputIndications|length %}
        {% for listItem in listItems %}
            {% if listItem starts with '•' %}

{{ listItem|trim|slice(1) }}

            {% else %}

{{ listItem|trim }}

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

Something like this should work:

{% set listItems = plainTextValue|replace('/[^, a-zA-Z0-9_-]|[, ]$/s','')|split(',') %}

  {% for listItem in listItems %}
    {% if listItem|length %}

{{ listItem|trim }}

    {% endif %}
  {% endfor %}

What the above does is to first use the replace filter to remove any character that isn't alphanumeric (except spaces and commas), before the resulting string (which would look something like 'Abdominal Pain,RUQ,Vomiting') is split on the commas. The resulting array is stored in a variable listItems. Finally, it's just a matter of looping through that array, to create the
 items.

Note that in the above example, plainTextValue is a variable containing the string '["Abdominal Pain","RUQ","Vomiting",""]' – so swap that out with entry.logGeneral_logInputIndications, or whatever fits.

Edit (OP added more info to the original question)

If your "symptoms" are in fact hierarchical, I'd suggest not using a PlainText field at all. You're quickly running into a situation where your back-end solution is way too simple, which will make your front-end solution way too complex.

My definitive recommendation would be to create a Categories group for the symptoms, and swap out the PlainText field for a Categories field.

Note that you can still render the actual symptoms form element on the front end as checkboxes, you'd just pass in an array of category IDs instead of a plain text string (the following example assumes a Categories group with the handle symptoms and a Categories field with the handle selectedSymptoms):

{# Get all available symptoms #}
{% set symptoms = craft.categories.group('symptoms').limit(null) %}

{# Get the symptoms that have been selected for this entry earlier #}
{% set selectedSymptoms = entry.selectedSymptoms.ids() %}

{# Loop through the available symptoms, creating checkboxes #}
{% for symptom in symptoms %}
    <input type="checkbox" name="fields[selectedSymptoms][]" value="{{ symptom.id }}"{% if symptom.id in selectedSymptoms %} checked{% endif %} />{{ symptom.title }}

{% endfor %}

...and to display whatever symptoms are already selected – in nested lists, as per the category hiearchy, you can use the {% nav %} tag:

{% nav symptom in entry.selectedSymptoms %}

        {{ symptom.title }}
        {% ifchildren %}

                {% children %}

        {% endifchildren %}

{% endnav %}


Add page number to Title and meta desc Want to add page number to title and meta description because I have a lot of duplicates. Could you tell me how I can do it?

You'll need to add more details about your current setup for a more specific answer.

In general, adding a number to the Meta Title and Meta Description is probably not a good approach to solve your problem of duplicates. Search engines score your page based on how relevant your content is. Adding a number, unless it has some meaning (perhaps a date for an event, tax form number, or 241543903), is just going to be noise and not help your page rank in any meaningful way.

Consider what other data you have in your posts. Can you add the name of a category some items are in? Can you add the name of a User that posted the content? Often there is a way to take a generic page and add a second dimension of data to make it more meaningful.

Generic Name - Category 1 - Site Name
Generic Name - Category 2 - Site Name

Alternatively, if the pages really are not meaningful, consider pointing search engines to a more meaningful canonical URL. For example, if you have a paginated index page, sometimes all the secondary pages will appear to have the same metadata.

In these cases you can add the canonical meta tag to point back to the primary page as the one that should be recognized by search engines.

https://website.com/section (points to self with metadata)

https://website.com/section/2 (points to main section page with metadata)
<link rel="canonical" href="https://website.com/section" />


How to duplicate entries and loop them without getting a Twig or deprecation error? I'm trying to duplicate entries inside a macro, which will displays duplicated items inside a carousel.

It's not possible to merge Element Queries. Even if it's possible to merge IDs, merging an array of IDs will end up with non-duplicated entries.

This is how I duplicate entries:

{% set entries = entries | merge(entries) %}

After that, this is how I loop, and the resulting issue:

for entry in entries.all()

→ Twig error: Impossible to invoke a method ("all") on an array;

for entry in entries

→ deprecated warning: Looping through element queries directly has been deprecated. Use the all() function to fetch the query results before looping over them;

for entry in entries.all() ?? entries or entry in entries ?? entries.all()

→ same warning as previous point;

Instead of duplicating the entries, you could run your entries loop twice (or as many times as you want) maybe?

{% for i in 0..1 %}
    {% for entry in entries %}
        {{ entry.title }}   <br>
    {% endfor %}
{% endfor %}


Related category on a single page Been trying for days to figure this one out. How do I extract entries from a channel and display only entries related to a category? How do I pull in the related photo? I have this code below but it pulls in all the photos. I don't think I'm doing doing this right.

{% set category = craft.categories.slug('spring-summer').first() %}

{% for post in craft.entries.section('product').relatedTo({targetElement: category}) %}

{{ post.title }}

{{ post.price }}

    {% for product in craft.entries.find() %}
        {% for image in product.photo %}

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

When you set up your category, you check the Categories in this group have their own URLs box, and you give the category a URL (suppose it is category/{slug}), and a template (suppose it is category/_entry). Now in the category/_entry.html template, category will be defined (the way entry is defined on the template for a section entry).

How do I list the entries related to a category? (tucked away in the Get Help section of the Craft website) describes how to fetch and list the entries related to a category:

{# Fetch all of the entries related to this category #}
{% set entries = craft.entries.relatedTo(category) %}

{# Output them #}
{% for entry in entries %}
    {{ entry.title }}
{% endfor %}

If you want to narrow the entries down to a single section, then fetch them like this:

{% set entries = craft.entries.section('mySectionHandle').relatedTo(category) %}


Updating fails (except it does indeed update) Updating Craft (and sometimes plugins like Commerce) through Craft 3 admin gives errors. Usually undefined, but have gotten "Backend fetch failed" most recently. Once I refresh the window, it seems to be updated. Since the prior update pseudo-failure there was a message about maintenance mode and a button to continue (which I'm assuming is a flag set somewhere from the prior update). It's a live site on shared open_basedir hosting and proc_open() disabled—which is accounted for in the general config, disabling backups when updating.

Anybody experience this and/or have a solution? All the folder permissions and so forth look correct.

My guess is that you're bumping into your php.ini file's memory_limit and/or max_execution_time setting.  It just happens to be towards the end of the update process where Craft is (for all practical purposes) updating, and it fails in the "cleaning up" portion of the update process.

Bump those up to something like 256M and 120 (respectively) and see if that helps going forward.

  Since the prior update pseudo-failure there was a message about maintenance mode and a button to continue (which I'm assuming is a flag set somewhere from the prior update).

Yup, it's a flag set that never gets reset if there's a fatal PHP error (live above).  It'll go away after the next successful update.


Why does a Element Criteria Model Query with Strings on a custom element type not filtering? having issues doing the classic element type query, works fine with numerical criteria (id, price etc.) but fails on strings, (code, name etc.). It just returns all elements.

$criteria = craft()->elements->getCriteria('GoWander_Trip');
$criteria->code = $code;
return $criteria->find();

Is there any step im missing in the setup of the element itself (code below)?

public function modifyElementsQuery(DbCommand $query, ElementCriteriaModel $criteria) {

    $query
        ->addSelect('
            trips.code,
            trips.templateId,
            trips.start,
            trips.end,
            trips.assetId,
            trips.price,
            trips.spots,
            trips.spotsAvailable,
            trips.elements,
            trips.shortDescription
        ')
        ->join('gowander_trips trips', 'trips.id = elements.id');

    if ($criteria->templateId) {

        $query->andWhere(DbHelper::parseParam('trips.templateId', $criteria->templateId, $query->params));
    }

}

Found the answer, simple mistake.

if ($criteria->code) {
   $query->andWhere(DbHelper::parseParam('trips.code', $criteria->code, $query->params));
}

was needed along with

public function defineCriteriaAttributes() {

    return array(
        'templateId'    => AttributeType::Mixed,
        'code'          => AttributeType::String,
    );
}

Hopes that helps anyone else who comes across something like this.


Trouble with twig syntax for discount conditions I'm trying to add a condition for a discount. It involves a custom date field. I want to discount anything that falls on Tuesday. I can't seem to get the twig syntax right. I've tried these two:
((cart.eDate|date('D')) == 'Tue')
((cart.eDate|date('D')) in ['Tue'])

I prefer the latter so I could add additional days if needed. Either of these work in templates. Is it because it is a custom field and the CP doesn't recognize it? Is there another approach?

For anyone interested in why this didn't work...It appears that you can't include a filter in the twig statement for discount formula conditions, at least not |date() as I was using. The error message in the CP isn't so great since it is valid twig syntax, but I totally get not using filters in this situation.


Unable to change password I am unable to change my password, as an admin in the CP of Craft.
I tried resetting it but it did not work.

If the email address is not yours, follow these instructions...

If the email address is yours, then your local system probably isn't sending out email. Follow these instructions to manually set the password.


Product category not being added to the order model. Craft Commerce I've created a form in which to specify a category for a product on the product entry page. I can't seem to add the category that the customer selects to the order model. I've checked the orders in the control panel and they do not seem to be storing the category. Does anybody know how to add a selected category to the order model?

<form id="values" method="POST">
     <input type="hidden" name="action" value="commerce/cart/updateCart">
     <input type="hidden" name="redirect" value="cart">
     ...
     <select id="chocOptions" name="chocolateOptions" class="options">
          <option title="selectOption">Select Option</option>
          {% for category in craft.categories.group('chocolate') %}
               <option value="{{ category.title }}">{{ category.title }}</option>
          {% endfor %}
     </select>
     ...
</form>

I never used Craft Commerce but you usually store relations (no matter which) with the id - not the title. So I expect the Commerce plugin will only recognize your category with this html

 <select id="chocOptions" name="fields[chocolateOptions][]" class="options">
      <option title="selectOption">Select Option</option>
      {% for category in craft.categories.group('chocolate') %}
           <option value="{{ category.id }}">{{ category.title }}</option>
      {% endfor %}
 </select>

And you have to name your field correctly like statet here

Edit
The easiest way to get to know how you have to build your html is the following

open the form in your Craft CP
Right click on the field
Click on "inspect" or "inspect element" or something like this
Search for the input or a hidden input. When I inspect a normal relation field it looks like this

    <input type="hidden" name="fields[relation][]" value="13">

        Some Name


Parse error: syntax error, unexpected '[' I am having a syntax error on my craftCMS website. Hoping someone could help me.

  Parse error: syntax error, unexpected '[' in /home16/puresoci/public_html/dev/craft/plugins/charge/ChargePlugin.php on line 14

Here's the line that it is referring to

  craft()->templates->hook('charge.prepCpTemplate', [$this, 'prepCpTemplate']);

Here's the whole function

public function init()
{
    craft()->charge_license->ping();

    if (craft()->request->isCpRequest()) {
        $this->includeCpResources();
        craft()->templates->hook('charge.prepCpTemplate', [$this, 'prepCpTemplate']);
        craft()->templates->hook('charge.prepCpSettingsTemplate', [$this, 'prepCpSettingsTemplate']);
    }
}

But I am a beginner on using PHP and I dont know how should I update this. I am using PHP 5.6 right now.

The Charge plugin requires a minimum of PHP 5.4.

The brackets notation for arrays (which is what Charge uses) was added in 5.4.

  http://php.net/manual/en/language.types.array.php

Contact your hosting provider to find out how to upgrade.


Get last row in table field for loop How can I determine if the row being returned from a table field in a for loop is the last row?

In any for loop you can use the loop variable that twig gives you.

For example:

{% for row in myTable %}
  {% if loop.last %}
    This is the last row
  {% else %}
    This is anything but the last row
  {% endif %}
{% endfor %}

More information on the loop variable can be found in the twig docs.


Where exactly to update the composer.json to install an older version of Craft 3? I'm trying to install a non-current version of Craft 3, and several pointers on using composer to do this say to "update the composer.json" line with the version you want.
Can someone please explain exactly where this file should be, and/or the steps to do this, as I cannot make head-nor-tail of this process.
Where can I download previous versions of Craft?
https://craftcms.com/knowledge-base/downloading-previous-commerce-versions

Make sure you have Composer installed from the command line.
Open your project's composer.json file.
Find the "require" section. Similar to:

"require": {
    "craftcms/cms": "^3.6.4",
    "vlucas/phpdotenv": "^3.4.0"
},

Edit the craftcms/cms line to the exact version you want. For example 3.5.0.

"craftcms/cms": "3.5.0",

Run composer update from the CLI from your project's root and that will pull in a fresh set to Craft 3.5.0 files.


includeCssFile and includeJsFile doesn't output {{ siteUrl }} It seems that when calling a CSS or JS file include, if the path contains {{ siteUrl }} it outputs {{ siteUrl }} in the html that is generated.

Like so;
<link rel="stylesheet" type="text/css" href="{{ siteUrl }}css/styles.css"/>

Which should be (for example);
<link rel="stylesheet" type="text/css" href="http://site.url/dev/css/styles.css"/>

Anything I'm missing here?

When you want to output Twig variables inside another Twig tag, you shouldn't include the braces around the variable.

So this:

{% includeCssFile "{{ siteUrl }}css/modul.min.css" %}
{% includeJsFile "{{ siteUrl }}js/ui.min.js" %}

Should be this:

{% includeCssFile siteUrl ~ "css/modul.min.css" %}
{% includeJsFile siteUrl ~ "js/ui.min.js" %}

These examples use the concatenation operator (~) to join the value held in the siteUrl variable to the string holding the path to the CSS or JS file to be included.


Change HTML and CSS per Matrix row I have a complex html/css structure per 'row' that I would like to use Matrix to populate. Design markup as follows:

Title

Lorem Ipsum...

Title

Lorem Ipsum...

How would I get Matrix to change the markup per 'row'? I looked at switch but that seems to be for types of block content/types.

TIA.

When looping through Matrix rows, you can use {{ loop.index }} or {{ loop.index0 }} to see which row you're at.

With loop.index, you could create html for each row number, or (for instance) create different html for even/uneven:

{% for row in entry.matrixFieldHandle %}
    {% if loop.index is divisible by(2) %}

{{ row.text }}

    {% else %}

{{ row.text }}

    {% endif %}
{% endfor %}


How to check an entry is in a section within a for loop I need to display different information depending on the section the entry comes under when I'm displaying all entries within a loop.
Use case - I have a feed which will pull in all entries such as 'Projects' and 'Events' both are sections set up as channels.
I need to display different information relating to each Entry on the front end as they have different fields.
So I need to check if the entry belongs to 'projects' or 'events' within the loop. I can't seem to achieve it.
Current code:
{% for entry in craft.entries.authorId(authorIds).orderBy('dateCreated desc') %}

      {% if entry in craft.entries.section('projects') %}

      Do something

      {% elseif entry in craft.entries.section('events') %}

      Do something different

      {% endif %}

{% endfor %}

This displays nothing? Any help?
Thanks

Check against entry.section.handle:
{% for entry in craft.entries.authorId(authorIds).orderBy('dateCreated desc').all() %}

      {% if entry.section.handle == 'projects' %}

         Do something

      {% elseif entry.section.handle == 'events' %}

         Do something different

      {% endif %}

{% endfor %}


POST param "code" doesn't exist I'm getting this error on the back-end and have no idea how to solve it. I re-uploaded the APP directory already once to no avail. Any input on how to resolve this would be greatly appreciated.

[error] [exception.Craft\HttpException.400] exception 'Craft\HttpException' with message 'POST param “code” doesn’t exist.' in /path to craft/craft/app/services/HttpRequestService.php:509
Stack trace:
/path to craft/craft/app/controllers/UsersController.php(333): Craft\HttpRequestService->getRequiredPost('code')
/path to craft/craft/app/framework/web/actions/CInlineAction.php(49): Craft\UsersController->actionSetPassword()

We tried a lot of things to fix this but could not as yet. We tried Nginx config chnages, and on a different server htaccess setting changes, having settings in the config like enableCsrfProtection off, usePathInfo' => true etc. The requireElevatedSession works ok for us on change a users password etc so this did not seem to be the problem as some other users have had.

The only way we could get around this for now was by editing the Charge plugin to stop the requireElevatedSession (Asks for a password before doing anything). I hope everything is ok with Joel at SquareBit as his support before on this plugin was excellent, but have had no reply from the last few months.

We changed:
'craft/plugins/charge/controllers/Charge_ChargesController.php'
lines 113 and 175 and Comment out/remove

//$this->requireElevatedSession();

And then in 'craft/plugins/charge/templates/payment/_view.html' removed JS calls

//new Craft.ElevatedSessionForm('.charge-refund-action');
//new Craft.ElevatedSessionForm('.charge-recur-cancel-action');

Hope this helps, or if anyone knows of a better fix?


Pull DateTime field using alternate timezone? I have a question regarding populating models, in that I have a DateTime field in my model that I'm pulling / populating from the database. The DateTime value does not include the timezone it was set to when it was stored, its stored in UTC.

I have the original timezone value (Not the same as the CRAFT timezone but the users timezone that actually created the entry) stored in the model attributes as well.

Is there a way I can extend the model so that when the data is populated I can force the correct timezone on the DateTime fields?

I'm pretty sure that Craft is going to convert them to the timezone craft is set to when it pulls it into the model, but I dont want that in this case. I want it set to the TZ stored in the "timeZone" column/attribute...

Example:

Craft Timezone is America/Chicago

The user's timezone is America/New_York

The user selects a date and time and the controller creates the DateTime object with the user's selection, specifying the timezone America/New_Yrok, then tells the model to save, so it stores it in the database.

The Database DateTime value is now stored in UTC.

When I fetch this data and populate a model with it and reference the DateTime object, its going to be in Amercia/Chicago right? since that's what the craft system is set to, right?

So what is the best way to set up the model so it automatically knows to use $this->getAttribute('timeZone') as the timezone for that field rather than the Craft system setting?

EDIT:

This is what I ended up doing that appears to work. I added this to my model:

public static function populateModel($values) {
    $model = PARENT::populateModel($values);

    /** @var $startTime DateTime */
    $startTime = $model->getAttribute('startTime');
    if($startTime) {
        $startTime->setTimezone($model->timeZone);
        $model->setAttribute('startTime', $startTime);
    }
    /** @var $endTime DateTime|null */
    $endTime = $model->getAttribute('endTime');
    if($endTime) {
        $endTime->setTimezone($model->timeZone);
        $model->setAttribute('endTime', $endTime);
    }

    return $model;
}

100% untested, but something like this should work:

Have your model override BaseModel's populateModel.
Find the DateTime field you're interested in and get its value.
Create a new DateTime object and pass in the value from the timeZone attribute.
Set the new DateTime object back on the original DateTime field.
Call parent::populateModel($values).


Image asset url is not being output After going through the documentation I believe that this is the correct code to output the url for the asset field but its not working and I have no idea why. Please help!

{% nav program in craft.entries.section('program').level(1) %}
  {% set active = entry is defined and program.isAncestorOf(entry) %}

      {% if program.featureImage|length %}

      {% endif %}

{{ program.title }}

{{ program.description }}

{% endnav %}

So after looking through other craft websites to see how they where able to get images to work I discovered what I did wrong when setting up the asset source. The thing is though that the craft documentation is not very helpful in this regard, also there are no errors or helpful output to indicate that my configuration might be the issue.