how can I filter to get only root categories in elementapi.php I tried to build JSON-API which returns all categories, whose result will be cascaded like "nav" tag with craft twig templating (see: https://craftcms.com/docs/templating/craft.categories ).

to get all root categories (which has no parent category, and which can have child categories), I've tried to filter giving within "criteria" something like that, but the result was just returned all categories:

'endpoints' => [
    'api/categories' => [
        'elementType' => ElementType::Category,
        'criteria' => [ 'descendantOf' => null ],
        'transformer' => function($entry) {
            return [
                'id' => $entry->id,
                'title' => $entry->title,
                'parent' => ($entry->parent) ? $entry->parent->id : null,
                'children' => ($entry->children) ?
                    children_in_array($entry->children) : null,
            ];
        },
    ]
]

function children_in_array() returns same structure like result of 'transformer' function (id, title, parent, children).

How can I get only root categories in this way?

or is there other solution all cascaded category list in JSON format?

To get all root categories you can use: 'criteria' => ['level' => 1]


Date conversion returning December for every single digit month representation I can't figure out what I'm doing wrong, but trying to convert single digit months to their name representations (ex. '4' to 'April' in English) but am just getting December printed out for every single one. I can't compare to month names because the site is in quite a few languages, so need to actually use the date functionality.

{% set groupedEntries = entriesInYear | group("postDate|date('n')") %}

{% for key, eachMonth in groupedEntries %}
    {% set monthName = date(key) | date('F') %}

        <a href="{{ craft.languageLink.url(craft.locale, urlParam) }}"
            {{ monthName }}, {{ eachMonth|length }}

{% endfor %}

'Key' is the month representation with no leading 0's (4, 3, and 2 for posts that exist in April, March and February).

Getting output as:
December, 4
December, 4
December, 2
(following number is number of posts in that month)

WHAT the heck am I doing wrong?

Here's what's happening... Every time you get "December", it's because the date is being parsed as December 31, 1969 (aka, just before the Unix Epoch). Basically, it's failing to parse the date properly, and thus defaulting back to the Epoch.

And here's why... date(key) is basically saying "Get the date of 4". Which obviously doesn't make any sense. So the "date of 4" is a fail, and you get the Epoch default instead.

So here's what I recommend instead... replace this:

{% set monthName = date(key) | date('F') %}

... with something more like this:

{% switch key %}
    {% case 1 %}
        {% set monthName = 'January'|t %}
    {% case 2 %}
        {% set monthName = 'February'|t %}
    {% case 3 %}
        {% set monthName = 'March'|t %}
    {% case 4 %}
        {% set monthName = 'April'|t %}
    {% case 5 %}
        {% set monthName = 'May'|t %}
    {% case 6 %}
        {% set monthName = 'June'|t %}
    {% case 7 %}
        {% set monthName = 'July'|t %}
    {% case 8 %}
        {% set monthName = 'August'|t %}
    {% case 9 %}
        {% set monthName = 'September'|t %}
    {% case 10 %}
        {% set monthName = 'October'|t %}
    {% case 11 %}
        {% set monthName = 'November'|t %}
    {% case 12 %}
        {% set monthName = 'December'|t %}
{% endswitch %}

That's a big chunk of code, I know. So feel free to offload that to a macro if it's more convenient.

Alternately, you could use a placeholder date, as carlcs suggested in his answer.


Programatically create a Matrix field I'm developing a plugin which requires certain sections and fields to exist so I'm currently creating them in the onAfterInstall() method of the plugin.

I can create individual fields, sections, entry types and even a Matrix field + block type fine. I'm having trouble with creating the Matrix sub-field and attaching that field to the Matrix block type.

I have created the matrix field:

$field = new FieldModel();
$field->groupId      = $group->id;
$field->name         = Craft::t('Field Name');
$field->handle       = 'handleName';
$field->translatable = false;
$field->type         = 'Matrix';
craft()->fields->saveField($fieldContentRSS);

And this is the block type:

$blockType = new MatrixBlockTypeModel();
$blockType->fieldId = $field->id;
$blockType->name = Craft::t('Block Name');
$blockType->handle = 'handleName';
craft()->matrix->saveBlockType($blockType);

I know that I will need to create a field/set of fields for this block type. Is this exactly the same as the new field above? How do I then attach these fields to the block type?

Creating the field/block types manually is only part of the equation - you would also need to create the new content table for your Matrix field.

All you need to do is assign all of your block types and their sub-fields’ settings to $field->settings before calling saveField():

$field = new FieldModel();
$field->groupId      = 1;
$field->name         = Craft::t('Field Name');
$field->handle       = 'handleName';
$field->translatable = false;
$field->type         = 'Matrix';

$field->settings = array(
    'blockTypes' => array(
        'new1' => array(
            'name' => 'My Block Type 1',
            'handle' => 'myBlockType1',
            'fields' => array(
                'new1' => array(
                    'name' => 'My Sub-Field 1',
                    'handle' => 'mySubField1',
                    'required' => true,
                    'translatable' => false,
                    'type' => 'PlainText',
                    'typesettings' => array(
                        'multiline' => false,
                    )
                ),
                'new2' => array(
                    'name' => 'My Sub-Field 2',
                    'handle' => 'mySubField2',
                    'required' => false,
                    'translatable' => false,
                    'type' => 'PlainText',
                    'typesettings' => array(
                        'multiline' => true,
                    )
                ),
            )
        )
    )
);

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


Output children of a structure section in reverse order How do you output the all the children of a structure in a reverse order (assuming the children are limited to max depth).

Using the order parameter, Craft requires that you use a second parameter like "desc" after a primary order parameter (eg, "title"). This would look like:

craft.entries.section('volumes').order('title desc')

But what would be the primary parameter that would respect the natural structure order?

Or is there any other way?

The primary parameter you're looking for is lft:

craft.entries.section('volumes').order('lft desc')


How many simultaneous visitors Craft CMS can handle? I am looking for a CMS as a backbone for front-end work and I like CraftCMS by its interface and structure, so I wonder if CraftCMS is capable for this project. In practice, most of the work will be done on front-end, but next to pageloads, there will be some Ajax requests to the server too and also will users need to log in.

Is Craft CMS (v3) realistically capable of handling around 10.000 logged in visitors simultaneously? I don't know all the details about the project yet, but is there something to say about this so far? Is it critical in CraftCMS? Or should it handle these amounts just fine? As 10.000 simultaneous users on the website looks like a lot to me.

Also, do you guys perhaps know what to look for in hosting specs in order to allow these amounts of simultaneous visitors to all have performant experience (both pageloads and ajax)?

Thanks a lot in advance!

Is CraftCMS (v3) realistically capable of handling around 10.000 logged in visitors simultaneously?

Generally speaking, yes. Depending on the specifics of the site and what the users are doing, you might have to make some environmental accommodations.

As always with stuff like this, so much of it depends on things like the hosting architecture (load balancers, web servers, hardware specs, session/cache storage, caching) as well as Craft's information architecture, template logic, plugins, caching, etc.


Security test generated large compiled_templates directory, site outage We just moved an installation of one of our sites to a new server. Previously, it was on a machine where the versions of Ubuntu / PHP prevented us from upgrading the Craft core version from 2.3.x to 2.6.x.

A few days ago, our client ran one of their security penetration tests that result in a large number of 404 HTTP requests against our site. This test generated enough unique cached templates in /craft/storage/runtime/compiled_templates to fill up the remaining disk space on the server - which appeared to take MySQL service down and serve 500 template errors afterwards.

Since bringing the site back up, we've been trying to identify and resolve the root issue behind the template caching that took the site offline. We've read this thread and are trying to formulate the right questions to prevent this from happening to this site the next time the client runs their tests.

Were there any significant changes in how Craft was handling template caching between versions 2.3 and 2.6 that would've allowed the old site to handle a spike in traffic without this issue?
Is there a configuration setting we missed to either avoid caching 404 pages, or reference the same cached template for all 404 requests?
Are there any special directory or file permission considerations to take into account that would prevent Craft from periodically clearing disk space here? Are there any automated cleanup tasks that should have run before the directory filled up?
Are there any OS, PHP or Apache settings that we should compare between the old server and new server that would help clarify the issue?

I don't have specific answers to your questions, but that's mainly because I feel there are some clarifications and observations that I think might be more helpful.

The thread you linked to is referring to template caching using the Craft {% cache %} tag in a template.  All of its cached data is stored in the database in the craft_templatecache* tables, not on the file system.  See here for an explanation of the different caching methods Craft uses.

The compiled files in craft/storage/runtime/compiled_templates are what happens when Twig needs to render a template in the craft/templates folder. The first time a template is requested, Twig will take that uncompiled template and compile it down to PHP and save it in the compiled_templates folder.  If another request comes in for that same template, it will check the  file's last modified date and if it hasn't changed, it will execute the compiled template directly.

Given that an actual 404 request wouldn't create new files in the compiled_templates folder (other than the 404 template that it might need to render), I'd guess that the assumption that the 404 requests caused the compiled_templates folder to fill up enough to run out of disk space is incorrect.  It could be that enough log files or some other by-product of the testing caused more disk space to be used, but it's hard to tell without looking at the server.

You also mentioned that the database went down.  Given that the {% cache %} tag stores its data in the database, my first hunch would be to look at the strategy for using the template cache tag on your templates.  Here is a good article that weighs the in-and-outs of using it: https://nystudio107.com/blog/the-craft-cache-tag-in-depth

Two other things worth thinking about. A responsible security pen-tester is going to know better than to test on a live site by hammering it to the ground. But it's possible that maybe they were being responsible and the server is under-powered to handle any spike in load.


Getting Checkboxes to work on Frontend Forms I have tried to follow the instructions listed here for checkboxes on frontend forms but have not been successful in implementation.

First, here is my code:

<form method="post" action="" accept-charset="UTF-8" enctype="multipart/form-data">

Push to GistServers for Gist {{ entry.id }}

<input type="hidden" name="action" value="gistClient/pushGistUnits">
<input type="hidden" name="entryId" value="{{ entry.id }}">

Select Gist Categories for Distribution.

{% if entry.gistCategories | length == 0 %}

        {% for option in entry.gistCategories.options %}
        <input type="checkbox" value="{{ option.value }}" name="fields[gistCategories][]"> {{ option.label }}

        {% endfor %}

{% else %}

    {% for checkboxOption in entry.gistCategories %}
        {% set checked = false %}

        {% if checkboxOption.selected %}
            {% set checked = true %}

        {% endif %}

        {% if not checked %}
            <input type="checkbox" value="{{ checkboxOption.value }}" name="fields[gistCategories][]" {% if checked %} checked="checked"{% endif %}>{{ checkboxOption.label }}

        {% endif %}

        <input type="checkbox" value="{{ checkboxOption.value }}" name="fields[gistCategories][]" {% if checked %} checked="checked"{% endif %}>{{ checkboxOption.label }}

    {% endfor %}

{%endif%}

{{ getCsrfInput() }}
{% if entry.socialPush == true %}
    {% set socialPush = "Push to GistServers"%}
    {% set socialPushBtn = "default"%}
{% else %}
    {% set socialPush = "Push to GistServers"%}
    {% set socialPushBtn = "success"%}
{% endif %}

<button class="btn btn-{{socialPushBtn}}  btn-sm btn " style="margin:10px 15px 0 0;" type="submit" name="fields[gistDraft]" value="0">{{ socialPush }}</button>

Now for screen caps showing behavior.

Before form submit

CP View after form submit

Frontend form after submit.

Ideally, After I submit the frontend form my users would be able to see all checkboxes again in case they need to change the selections. I am at a loss and would appreciate some rescue here.

The first loop you're using loops over entry.gistCategories.options, which contains all the options available. However, in the second loop (when entry.gistCategories|length !== 0), you're only looping over the options that have been selected.

Try this:

{% if entry.gistCategories | length == 0 %}

        {% for option in entry.gistCategories.options %}
            {# output checkboxes #}
        {% endfor %}

{% else %}

        {% for checkboxOption in entry.gistCategories.options %}
            {# output checkboxes #}
        {% endfor %}

{% endif %}


Excessive resource usage / virtual memory size Our server is generating lots of emails that follow this template:

subject:

lfd on host.foo.com: Excessive resource usage: foo (24056 (Parent PID:16356))

body:

Time:         Wed Jan 31 11:31:20 2018 -0500
Account:      foo
Resource:     Virtual Memory Size
Exceeded:     556 > 512 (MB)
Executable:   /opt/cpanel/ea-php71/root/usr/bin/php-cgi
Command Line: /opt/cpanel/ea-php71/root/usr/bin/php-cgi /home/foo/public_html/index.php
PID:          24056 (Parent PID:16356)
Killed:       No

Sometimes I can attribute these to image transforms, but other times they appear somewhat randomly. I received 13 in a row earlier today. I've seen this type of email from several servers that run Craft sites. I've researched excessive resource emails in general, but the answer always seems to be "just add it to csf.pignore" - which I don't want to do.

So, I'm wondering if anyone knows what Craft process may be generating this type of email. I don't think that we're doing anything out of the ordinary.

Thanks!

It appears those emails are being generated by something called Config Server Firewall running on your server.  I don't know if your host gives you access to configure settings in it, but it looks like they have allocated you 512M of memory and you're exceeding that.

You can hit that easy enough with image transforms and spikes/surges in traffic can amplify that effect.


Font Color in Rich Text field Is it possible to get the Font Color plugin into Redactor?

I tried adding it to my redactor json file as below but no luck.

{
buttons: ['html','fontcolor','table','formatting','bold','italic','alignment','unorderedlist','horizontalrule','orderedlist','outdent', 'indent','link','image','video'],
plugins: ['fullscreen','video','table','fontcolor'],
toolbarFixedBox: true
}

Font Color Redactor Plugin - http://imperavi.com/redactor/plugins/font-color/

I'm not sure what the correct process is to get it working in my Craft admin.

The plugin doesn't come with Craft. You have to manually install it with a Craft plugin, but luckily this is easy to do:

Set up your new Craft plugin (→ "Plugin Development - Setting Things Up")
Download the Redactor plugin and copy it to craft/plugins/myplugin/resources/
Load the Redactor plugin JS file from the init function:
craft()->templates->includeJsResource('myplugin/redactorplugin.js');


Image transform in inline background css not being generated In my backend I have a radio button field with 2 options for the client:
Normal and cover. When selecting normal, the uploaded image is put into an  tag in the HTML and an image transform is applied. This works well as it should.

When selecting cover however, the uploaded image is added to a background-image inline CSS style. But the applied image transform is not generated for this. When I change the uploaded image to "normal", let it generate a transform and then put it back to "cover" only than it is shown as a background image.

So image transform doesn't seem to trigger in this code:

Does anyone know why this is not working?

Try taking the apostrophes off your transform, e.g.

getUrl(storyMediaTransform)


Multiple entry templates per entry Is there a way to have multiple entry templates per entry?

I'd like to create two different templates that display the same content/data in different ways.

If they can live at different URL's, you could setup multiple routes under Settings->Routes. Give them different URL structures like so:

blog/slug loads mytemplatefolder/blog_template
another-url/slug loads mytemplatefolder/another_template


How can I fix Image Exception error when uploading image via front-end form while Preparse plugin enabled? I'm not sure if the issue is with Craft 3, the Preparse plugin, or me, so I'm posting here first.

I have a front-end form that includes an Assets field used to upload images. The entry type contains Preparse fields.

When the Preparse plugin is enabled and I submit the front-end form with an image, I get this error:

Image Exception – craft\errors\ImageException
The file "assets5bcf19ef8f6bc6.04658934.jpg" does not appear to be an image.

Screenshot with more details: https://cl.ly/edfbc0c07bde

The entry still gets created and the .jpg file is uploaded as expected.

I don't have any issues when creating entries via the CP.

If I disable the Preparse plugin and submit the front-end form, the error does not appear.

If I upload a .pdf file instead of a .jpg while the Preparse plugin is enabled, I don't get an error.

Therefore, it appears to be an issue with the Preparse plugin and image files in Craft 3 front-end forms (tested both .jpg & .png).

How can I fix this?

Fixed in Preparse Plugin v 1.0.3.

View changelog at: https://github.com/aelvan/Preparse-Field-Craft/blob/craft3/CHANGELOG.md#103---2018-10-24


Extend templates from outside templates directory I have a setup where I'm using a component library that I have as an npm package. To use these components I need to extend templates that live outside of the /templates directory. So I need to achieve something like:

{% extends "../../../../node_modules/design-system/page-templates/_template.njk" %}

I will be extended from within a template that is located from within the /templates directory but allows for extends from outside of it.

Any help would be great.

You need to define and register your template roots for this folder:

Event::on(
    View::class,
    View::EVENT_REGISTER_SITE_TEMPLATE_ROOTS,
    function(RegisterTemplateRootsEvent $e) {{
        $e->roots['my-fancy-prefix'] = 'someDir';
    }
);


There are no sites in the config file on nitro add When i try nitro add command to they return "There are no sites in the config file" what should i do?
Unable to locate a webroot, setting to web.
Enter the webroot [web] web
Added tutorial.test to config file
Apply changes from config? [yes] yes
Mounting ~/Nitro/projects/tutorial to nitro-dev
Adding site tutorial.test to nitro-dev
Applied changes from /home/pedro/.nitro/nitro-dev.yaml
[sudo] senha para pedro:
There are no sites in the config file.

It probably because nitro doesn't overwrite your host file. You may need to edit it yourself using nano (assuming you're on linux).
sudo nano /etc/hosts
you will need to provide

the IP address- that you can find using nitro info in the terminal or by opening the nitro-dev shell in multipass
the hostname- example.test or whatever else that may be

There is a github issue raised for it, see https://github.com/craftcms/nitro/issues/213


Installing Craft on Xampp I'm trying to get a dev environment set up and have got stuck.

I use Linux in the office and Windows at home. I simply wanted a basic LAMP stack to run craft on so I could develop locally. Given the two OSs, I figured I'd use Xampp.

I've installed Xampp on my Linux Mint PC. localhost seems to take me to htdocs, which I understand is normal? I've put Craft in htdocs, and then created a folder called public and put the index.php etc. in there.

So we have:

htdocs
 - craft
 - public
   - index.php

However, when I then do localhost/public/admin, I get
Could not find your craft/ folder. Please ensure that $craftPath is set correctly in /opt/lampp/htdocs/public/index.php

My craft path is set to ../craft (i.e. the default)

I've had a google, and there do seem to be similar questions, but mostly on Windows.

Should I move everything up a level? Or am I doing something else wrong?

It might be easier for you to set up a local domain and access it via my-site.dev rather than localhost/public/admin.

Using xampp this is a bit of a manual process. You'll need to go into:
xampp/apache/conf/extra/httpd-vhosts.conf and the following

## my site name Site
<VirtualHost *:80>
    DocumentRoot "D:/xampp/htdocs/my-site"
    ServerName my-site.dev
    ServerAlias www.my-site.dev
    <Directory "d:/xampp/htdocs/my-site">
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

The open your text editor with administrator rights and go to: c:\windows\system32\drivers\etc\hosts and add the following:

127.0.0.1 my-site.dev

For an easier process to set this up use Ampps instead the gui is simpler and everything is automated. Though you may still need to open your hosts file with your text editor if you haven't set up ampps to run with administrator privileges.

I used to use xampps, but now much prefer ampps on windows.


Iterate through all rows of specific page using Freeform? Documentation (http://docs.solspace.com/craft/freeform/v2/template-objects/page.html#usage-in-templates) says you can iterate through all rows on CURRENT page or entire form.

I need all rows/fields at once but separated by page for an accordion.

Or I could actually read all the documentation: Method getRows()

As in {% for row in page.getRows() %}


Modifying Commerce line items after order is complete I am in the process of building a gift card system for a Craft Commerce site. The current process is that the customer will order a gift card and proceed through checkout as with any other item.

The only information passed through the options is the amount, which is used to generate the gift card. The process works perfectly, and the gift card is generated exactly how it is supposed too.

The next step is to modify the line items using the event onBeforeOrderComplete or onOrderComplete. I would like to change the options to include the amount, and the gift card code.

This is the process I have at the moment, which is just one of the many variations that I've attempted. Nothing I do seems to change the options on the order.

craft()->on('commerce_orders.onBeforeOrderComplete', function($event) {
    $order = $event->params['order'];
    $items = $order->lineItems;

    foreach( $items as $key => $item ) {
        $type = $item->getPurchasable()->getProduct()->getType();
        if ($type->handle === 'giftCard') {
            $options = $item->options;
            $giftcard = new GiftCards_GiftCardModel();

            $giftcard->amount = $item->price;
            $giftcard->balance = $item->price;
            $giftcard->isActive = 1;

            craft()->giftCards->saveGiftCard($giftcard);

            $options['code'] = $giftcard->code;
            $items[$key]->options = $options;
        }
    }

    $order->lineItems = $items;
});

My only other solution is to generate the gift card code when the gift card is added to the cart and change the active status when order is complete. This would solve my problem completely, but it runs the risk of having hundreds or even thousands of gift cards generated and never completely activated.

I found a solution (possibly temporary) to my problem. Instead of trying to modify the line items via the order itself, I am modifying them directly.

After changing the line item during the for loop, I pass the $item variable back into this code:

craft()->commerce_lineItems->saveLineItem($item);

I'm not entirely sure what the extra impact that is on the number of queries, but considering that most people will only order a single gift card, maybe two, I would imagine that it's not a terrible way to accomplish this.

I'm still open to ideas of a better way to solve my issue, but for now it seems to do the trick.


Are there any alternatives to the deprecated Export plugin? This thread Export Craft Data leads me to add a new question.

What is a good Craft 3 export plugin?

I know several for imports, for example the FeedMe plugin is doing a great job, but nothing to export data.

What I need:

Export buttons for all views in CP. (Columns can be defined)
related entries/categories can be included in the export
in an extra view you can prepare templates of exports (like in the Wordpress plugin WPAllExport)
It should also be possible to define a path where it exports the data on a regular basis

(And I think you can imagine much more benefits...)

And NO, the ElementAPI Plugin does not fit my needs. It has to be Client-Usable.

We created a lot of web applications where we always implement some kind of export. If there is nothing out there I am really thinking of creating a plugin. Is there anyone else out there willing to support an ideal Export Plugin (and is also willing to pay for a Pro Version )

Assuming you want to export to a CSV, I'd recommend trying the Sprout Reports plugin...

  https://sprout.barrelstrengthdesign.com/craft-plugins/reports


How to integrate custom statuses in a workflow style custom element type? I made a lot of progress on my custom element type from this post and with the help of @selvinortiz:

Best way to implement my own statuses on my custom element type?

I know have custom statuses that look like this:

However, there are a few things I'm stuck on:

How do you assign colors to the statuses? I could target them with CSS but I feel there may be a way with Craft itself.
When listing entries in my templates, the default status is "green" for enabled. So how do I correlate my custom statuses with the enabled/disabled featured thats all ready in place?

I feel like Craft is the perfect tool for developing a workflow style plugin but I am having a few issues with statuses specifically. Does anyone have personal experience with creating a workflow, using native functionality, with Craft?

I looked into this a little bit... It looks like the color of the circles is dependent on one of these CSS classes by default:

.status.live - Green
.status.pending - Orange
.status.expired - Red
.status.disabled - White

I'm assuming (haven't checked this) that the status gets applied to the color dot as a lowercased version of the name. So for example, if you have a status called "Awesome", you would end up with a dot with the class .status.awesome.*

* If I'm mistaken about how this works, anyone is welcome to correct me.

Now that you've got your .status.awesome classes applied to the <span> which produces the color dots, you get to make your own dot! The default versions are pulling from two sprite files... You'll be served up the version which best matches your display:

/app/resources/images/status.png
/app/resources/images/status_2x.png

Since you're not going to be changing anything in the app folder, you'll need to make your own image to represent your dot. One great bonus of this: Your dot doesn't have to be dot shaped! You could just as easily make a star, question mark icon, etc. I'd suggest making both a "regular" and "2x" versions, to stay compliant with the native Craft handling.

Put your new image files into your plugin's resources folder:

/myplugin/resources/images/customstatus.png
/myplugin/resources/images/customstatus_2x.png

Then, you'd reference those in your plugin's CSS:

.status.awesome {
    background: url(/myplugin/resources/images/customstatus.png);
}

The default .status class handles a lot of the generic positioning, so you shouldn't have to override much.

Anyway, most of this is speculative and untested... But let us know if it works out for you!


Internal Server Error: missing method or closure Receiving the standard error:

  Craft\MatrixBlockModel and its behaviors do not have a method or
  closure named "sectionArticles".

The problem is that this error doesn't make sense. Here is why:

I have a newsletter template with the block 'sectionArticles'
It lists entries from 3 different sections
These 3 sections do not have a block 'sectionArticles' nor a reference to it in their templates.
If I click on a link that leads to the url for these entries, I receive the above error
If I copy and paste the url into a new tab everything is fine
This only recently started happening. In other words, old issues of the newsletter are fine

Help?

Here is code for referring template:

{% for block in entry.connectionsContent %}
  {% switch block.type %}
    {% case "connectionsTextOnly" %}

          {% set asset = block.sectionImage.first() %}
          {% if asset %}

          {% else %}

          {% endif %}
              {{ block.sectionText }}

    {% default %}
      {% set entries = block.sectionArticles %}
      {% if entries | length %}

            {% for entry in entries %}
              {% if entry.section.handle == "news" %}
                {% include 'news/_includes/feed' %}
              {% elseif entry.section.handle == "pages" %}
                {% include 'pages/_includes/feed' %}
              {% elseif entry.section.handle == "events" %}
                {% include 'events/_includes/feed' %}
              {% endif %}
            {% endfor %}

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

The feed templates are just links and display fine.

The errors occurs on the events/_entry, news/_entry and pages/_entry templates. There is no references of the block 'sectionArticles' in those templates.

One more thing: the error only happens on scheduled entries, where the Post Date is in the future, after the Post Date has arrived.

Thanks everyone for taking a look. I forgot that I had implemented something on the receiving templates that allowed you to navigate between articles from the newsletter, if the referral url was the newsletter. After I implemented the text only block, I forgot to change this to ignore those blocks.


Is it possible to create a plugin using Python in Craft 2? I've been searching and trying things for a few days now, but I feel like I'm spinning my wheels. I've got a Python script that reads in a .pptx file, and returns a Dictionary of slides. I've also tried returning different things from the Python script, even as simple as a Hello World string.

For simplicity's sake, I just have this code in my onAfterInstall() method:

$output = shell_exec("import_ppt.py 'original.pptx' ");
    var_dump($output);
var_dump($output);

For the filepath, I've also tried ".realpath(dirname(__FILE__))."/ as well, to no avail. I always get a NULL return and a PHP warning about not being able to modify headers.

Then, in my Python file, I have:

if __name__ == '__main__':
import sys
buildSlideshow(sys.argv[1])

buildSlideshow takes one argument, which is the filepath of the powerpoint file, and eventually returns the dictionary of slides and slide content.

I know that the error isn't in my Python code, as if I run it in shell I don't have any problems with it and get the result I want. So, my overall question is this:

Is what I'm trying to do a pipe dream, or am I just missing something major? I can't find any docs about CraftxPython, simply searching the word "Python" on this very site brought up no results, and when I tried looking up how to incorporate Python into a Craft 2 plugin, all I got was information on how to create a plugin for Python.

I think you're going to have a bad time if you attempt to do this. Probably a better way would be to use PHPPresentation to read in the .pptx files.

Integration is certainly possible between server-side languages, but you're going to have to jump through a good deal of hoops that you could more easily just avoid by writing your plugin in PHP.


How can I interact with Users via the ElementAPI? I am attempting to use the ElementAPI to check if a user is logged in or not. I've used the ElementAPI before to check/get entries for a given section, but never for user-based entries.

Here is my elementapi.php file:

<?php
namespace Craft;

return [
    'endpoints' => [
        'user/current.json' => [
            'elementType' => 'User',
            'criteria' => [
                'foo' => 'bar', // Not sure what to do here.
            ],
            'transformer' => function (EntryModel $user) {
                // Not sure about this either...
                if ($user->isCurrent) {
                    return [
                        'status' => true
                    ];
                } else {
                    return [
                        'status' => false
                    ];
                }
            },
        ]
    ]
];

I'm getting to the plugin, but It really is not happy with what I'm giving it:

Argument 1 passed to Craft\ConfigService::Craft\{closure}() must be an instance of Craft\EntryModel, instance of Craft\UserModel given

Pretty sure it has something to do with the criteria?

Change

function (EntryModel $user)

to

function (UserModel $user)

You were passing in a user to a function that’s expecting an EntryModel. That’s the reason for the error you are getting.


Typogrify: hyphenation not kicking in I am stunned by the typogrify extension for craft. https://github.com/nystudio107/craft-typogrify

Alas, the functionalities that are most relevant to me are not kicking in (anymore).
As Andrew says on https://nystudio107.com/docs/typogrify/#troubleshooting

  If it doesn't look like Typogrify is doing anything to the HTML you're
  passing it, it is probably malformed HTML (syntax errors, missing
  closing tags, etc.). Fix your HTML, and Typogrify will prettify it!

Well, in my case it's not, I'm outputting a text-only-field in a completely empty page.

{{ entry.lead|typogrify|smartypants }}

Most things are working: for example (c) is replaced by ©, and I can switch it on or off with "set_smart_marks" => true,

But I can't get the Hyphenation to work:

// enables hyphenation of text
"set_hyphenation" => true,

// defines hyphenation language for text
"set_hyphenation_language" => "de-CH",

At one point, the content was full of &shy;s which seemed to come from Typogrify. Not anymore. Why could that be?

I don't understand where typogrify gets the hyphenation rules from: maybe it requires additional php libraries that are missing?

Also, I wonder how – when it works – to switch the hyphenation language in a multilingual site?

[SOLVED:]

Quotes to guillemets

I wanted to convert all kinds of accidental double quotes into swiss style «Guillemets» (like the french, but there's no space).

I tried:

// curl quotemarks
"set_smart_quotes" => true,

// Primary quotemarks style
// allowed values for $style
"doubleGuillemetsFrench" => "&laquo;&nbsp;foo&nbsp;&raquo;",
"set_smart_quotes_primary" => Quote_Style::DOUBLE_GUILLEMETS_FRENCH,

The reason it wouldn't work were surplus spaces in twig:

{{ entry.lead | typogrify | smartypants }}

instead of

{{ entry.lead|typogrify|smartypants }}

Try adding/changing the hyphenation settings in the config file? e.g.

// establishes minimum length of a word that may be hyphenated
"set_min_length_hyphenation" => 5,

// establishes minimum character requirement before a hyphenation point
"set_min_before_hyphenation" => 3,

// establishes minimum character requirement after a hyphenation point
"set_min_after_hyphenation" => 2,

I ran into a similar problem. There were defaults set, but to get it to work, I had to explicitly add them to my file.


How do I include record relationships in validation? Say I have a record defining a foreign key relationship which is set to required, such as:

public function defineRelations()
{
    return [
        'type' => [
            static::BELONGS_TO,
            'Events_EventTypeRecord',
            'required' => true,
            'onDelete' => static::CASCADE
        ]
    ];
}

If I try to save the record with typeId not set I'll eventually get a database exception but the error won't show up if I call $record->validate().

How do I make a relationship fail validation?

Yii/Active Record won't do this by default.  You'd need to manually add an exists validation rule to the typeId attribute to get it to behave like you're looking for.


Work with data/content from entries I'm usually working on Backends with PHP and ZF/Laminas.

Now I'm building a headless (only Backend) Craft CMS website and have a couple of questions that I didn't find a clear answer on. The Craft CMS project is developed "offline" with Vagrant+Docker and has currently no frontend and won't have it in the near future.

The authors should be able to create an entry (fieldset has only a text) that contains a name. I want to be able to work with the created entry like with a variable/item so I can link other entries and modules to it. Is there a way to do it in the Craft backend itself or in PHP in a controller for example? As I'm working headless, I'm not able to do twig as I don't have the templates or any kind of frontend for now.
The users should be able to upload files and link them to an created item from an author.
What's the best way to fetch these data? I'd like to be able to fetch all (or filter for files or text entries etc.) uploaded files or associated entries to that item.

Is it possible to get the content from specific entries out of my database executing SQL statements in PHP and use the data within a controller?

I'd like to have the newly created entries (by authors) dynamically as items that users can link their uploaded files to.

I'm very thankful for any kind of help!

In Craft almost everything is an element type (assets, categories, entries, global sets, matrix blocks, tags and users). If something is an element type you can attach arbitrary fields to it. Using fields like the Assets field, Entries field, Categories field or Users field you can define relations (link) between these elements.

For fetching elements via an API there are these options:

the built-in GraphQL API
the Element API plugin
creating a plugin or module and define API endpoints freestyle using the element query builders

Other non-API options for querying elements are:

use element queries in Twig and dump the result
use element queries in PHP and dump the result to the browser
use the REPL via the CLI with ./craft shell


How to set up {siteUrl} to work with both http and https I'm looking for a way to set up the general.php file's siteUrl to be able to use both http and https. Only the front-end login would be using the https. This is how I currently have it set up:

'mysite.com' => array(
    'cooldownDuration' => 0,
    'environmentVariables' => array(
        'siteUrl' => '//mysite.com/',
    )
)

The problem with this is when the front-end form is submitted and the user is redirected, the url messes up (i.e.: mysite.com/mysite.com/page-name)

Any suggestions would be great!

One method is using something like the following in your general.php file.  Using this method the config settings will take on the scheme of the request being made.  I've set both the siteUrl and example environmentVariables below:

<?php

// Ensure our urls have the right scheme
define('URI_SCHEME',  ( isset($_SERVER['HTTPS'] ) ) ? "https://" : "http://" );

// The site url
define('SITE_URL',    URI_SCHEME . $_SERVER['SERVER_NAME'] . '/');

// The site basepath
define('BASEPATH',    realpath(CRAFT_BASE_PATH . '/../') . '/');

return array(
    '*' => array(

        'siteUrl' => SITE_URL,

        'environmentVariables' => array(
            'siteUrl'  => SITE_URL,
            'basePath' => BASEPATH
        ),
    ),
);


Event Listener for Publishing Scheduled Posts For performance reasons I'm caching full HTML responses to Redis. This does wonders for response times, but cache invalidation becomes a bit tricky... I'm currently purging the entire cache on 'entries.saveEntry' which will suffice most of the time.

The problem is with scheduled posts. Scheduled posts are not saved when they're published so the cache is not invalidated and the post doesn't show up unless I clear the cache manually. I need to register 2 events listeners to clear the cache: one on entry save and one one on publish. Does this second event exist? If not, is there a way to create one?

There isn't an event that fires when an entry with a future post date goes live, since it's just compared against the existing time and there's no guarantee that any PHP will be executing at that exact time.

You could write a cron job that hits a plugin's controller that checks every minute or so for any entries about to go live.

Or maybe adopt something similar to this for your Redis/full page caching solution.


Sprout Email conflicts with Craft Contact Form I have the latest versions of Craft CMS, Sprout Email and Craft Contact plugins. Sprout behaves fine with some notifications I have set up. However, if I submit a contact form it throws a PHP error - mb_convert_case() expects parameter 1 to be string, array given

If I disable Sprout, then Contact Form works fine.

Looking at the logs, I see that submitting the form triggers a 'When an entry is saved' event and Sprout starts looking at whether it is something it should handle and then chokes when trying to parse it as an entry.

I finally got things to work by disabling the "Enable Sent Email tracking" feature in Sprout Email, but I would prefer not to have to do that.

Has anyone encountered anything like this or have any thoughts on this? Thanks for any input!

This issue has been resolved in Sprout Email 3.

Be sure to read the upgrade notes. This is a major release and some scenarios may require a few manual steps to get updated.


Unable to Update Craft CMS & Plugins When trying to update CraftCMS I'm getting the following errors:

Error: An error occurred

Output: Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

Problem 1
- Installation request for craftcms/cms 3.0.21 -> satisfiable by craftcms/cms[3.0.21].
- craftcms/cms 3.0.21 requires enshrined/svg-sanitize ~0.9.0 -> satisfiable by enshrined/svg-sanitize[0.9.0] but these conflict with your requirements or minimum-stability.
Problem 2
- craftcms/ckeditor 1.0.0-beta.2 requires craftcms/cms ^3.0.0-RC1 -> satisfiable by craftcms/cms[3.0.21].
- craftcms/ckeditor 1.0.0-beta.2 requires craftcms/cms ^3.0.0-RC1 -> satisfiable by craftcms/cms[3.0.21].
- craftcms/cms 3.0.21 requires enshrined/svg-sanitize ~0.9.0 -> satisfiable by enshrined/svg-sanitize[0.9.0] but these conflict with your requirements or minimum-stability.
- Installation request for craftcms/ckeditor 1.0.0-beta.2 -> satisfiable by craftcms/ckeditor[1.0.0-beta.2].

Running update with --no-dev does not mean require-dev is ignored, it just means the packages will not be installed. If dev requirements are blocking the update you have to resolve those problems.

The problem is, the following is all OK:

composer update comes back with "Nothing to Install"

The original composer file that caused the error above looked like this:

{  "name": "craftcms/craft",
"description": "Craft CMS",
"keywords": [
"craft",
"cms",
"craftcms",
"project"
],
"license": "MIT",
"homepage": "https://craftcms.com/",
"type": "project",
"support": {
"email": "support@craftcms.com",
"issues": "https://github.com/craftcms/cms/issues",
"forum": "https://craftcms.stackexchange.com/",
"source": "https://github.com/craftcms/cms",
"docs": "https://craftcms.com/docs",
"rss": "https://craftcms.com/changelog.rss"
},
"require": {
"craftcms/cms": "3.0.13.1",
"vlucas/phpdotenv": "v2.4.0",
"craftcms/ckeditor": "1.0.0-beta.2",
"craftcms/redactor": "2.1.5",
"cebe/markdown": "1.1.2",
"composer/ca-bundle": "1.1.1",
"composer/composer": "1.6.3",
"composer/semver": "1.4.2",
"composer/spdx-licenses": "1.3.0",
"craftcms/oauth2-craftid": "1.0.0.1",
"craftcms/plugin-installer": "1.5.2",
"craftcms/server-check": "1.1.1",
"creocoder/yii2-nested-sets": "0.9.0",
"danielstjules/stringy": "3.1.0",
"doctrine/lexer": "v1.0.1",
"egulias/email-validator": "2.1.4",
"elvanto/litemoji": "1.3.1",
"enshrined/svg-sanitize": "0.8.2",
"ezyang/htmlpurifier": "v4.10.0",
"guzzlehttp/guzzle": "6.3.3",
"guzzlehttp/promises": "v1.3.1",
"guzzlehttp/psr7": "1.4.2",
"justinrainbow/json-schema": "5.2.7",
"league/flysystem": "1.0.44",
"league/oauth2-client": "2.2.1",
"mikehaertl/php-shellcommand": "1.2.5",
"paragonie/random_compat": "v2.0.12",
"pixelandtonic/imagine": "v0.7.1.3",
"psr/http-message": "1.0.1",
"psr/log": "1.0.2",
"seld/cli-prompt": "1.0.3",
"seld/jsonlint": "1.7.1",
"seld/phar-utils": "1.0.1",
"swiftmailer/swiftmailer": "v6.0.2",
"symfony/console": "v3.3.6",
"symfony/debug": "v3.3.6",
"symfony/filesystem": "v3.3.6",
"symfony/finder": "v3.3.6",
"symfony/polyfill-mbstring": "v1.8.0",
"symfony/process": "v3.3.6",
"twig/twig": "v2.4.8",
"yiisoft/yii2": "2.0.15.1",
"yiisoft/yii2-bootstrap": "2.0.8",
"yiisoft/yii2-composer": "2.0.6",
"yiisoft/yii2-debug": "2.0.13",
"yiisoft/yii2-queue": "2.0.2",
"yiisoft/yii2-swiftmailer": "2.1.1",
"zendframework/zend-escaper": "2.6.0",
"zendframework/zend-feed": "2.8.0",
"zendframework/zend-stdlib": "3.2.0",
"solspace/craft3-freeform": "2.2.1"
},
"autoload": {
"psr-4": {
  "modules\\": "modules/"
}
},
"config": {
"optimize-autoloader": true,
"platform": {
"php": "7.0"
}
},
"scripts": {
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@composer dump-autoload -o",
"@php craft setup/welcome"
]
}
}

So I removed "enshrined/svg-sanitize": "0.8.2", from the list in the compser file, and ran the update. The next error was given for Twig. So I deleted ""twig/twig": "v2.4.8" from the file, and ran the update again. This time it was successful, and the composer file now looks like this:

{
"name": "craftcms/craft",
"description": "Craft CMS",
"keywords": [
"craft",
"cms",
"craftcms",
"project"
],
"license": "MIT",
"homepage": "https://craftcms.com/",
"type": "project",
"support": {
"email": "support@craftcms.com",
"issues": "https://github.com/craftcms/cms/issues",
"forum": "https://craftcms.stackexchange.com/",
"source": "https://github.com/craftcms/cms",
"docs": "https://craftcms.com/docs",
"rss": "https://craftcms.com/changelog.rss"
},
"require": {
"craftcms/cms": "3.0.20",
"vlucas/phpdotenv": "^2.4.0",
"craftcms/redactor": "2.1.5"
},
"autoload": {
"psr-4": {
"modules\\": "modules/"
}
},
"config": {
"optimize-autoloader": true,
"platform": {
"php": "7.0"
}
},
"scripts": {
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@composer dump-autoload -o",
"@php craft setup/welcome"
]
}
}

So the update seems to remove a lot of the required references in the composer file. I tried doing this on a backup install first before doing the same on the live install.


Use an entry field's value in body class I have created a plain text field that is assigned to a section and is available in the tabs for entries in that section. I want to use this field's value to modify the CSS on my template. My _entry.html file looks like the following:

{% extends "_layouts/site" %}
{% set title = entry.title %}
{% set modifierClass = entry.shortName %}
{% set bodyClass = "work modifierClass" %}

{% block main %}

{% endblock %}

I have assigned the entry.shortName to the customClass variable, but it is not working correctly. The text "modifierClass" is outputted in the body tag instead of what is entered in the entry.shortName field. If I place the {{ entry.shortName }} within the
 tags, it is outputted correctly there.

Any reason why this is not working? Or am I not understanding how field values can be assigned to variables.

Cheers,

You've assigned the string 'work modifierClass' to the bodyClass variable, rather than adding the value of the modifierClass variable to bodyClass.

You can assign the value of modifierClass to bodyClass like this:

{% set bodyClass = 'work ' ~ modifierClass %}

The ~ (tilde) character is Twig's string concatenation operator.

You could even remove the modifierClass variable altogether and just do this:

{% set bodyClass = 'work ' ~ entry.shortName %}


Load new entry(s) in the same page with ajax as a popup First time I'm going to use Ajax with Craft CMS therefore I'm still confused how it works.

What I need is this, when I click on a specified link  in the front, I need the CMS to load some entry/entries and display the data in a popup on the same page of course.

The CSS for the popup is ready, the HTML too (static for now, not twig template) the backoffice also is ready.  The only thing I need is how to get the entries (basic explanation if possible) with ajax (It seems to be the best solution) and load them into the page then show them in a popup.

Is there any link(s) to help in my task or someone to explain those first steps please ?

First: you need to create a Plugin, I suggest you to use Pluginfactory.io to create your boilerplate and read the docs about plugin development

You'll need an ajax Request that could look like

$('#a-button').click(function(){
    var data = {
        entryIds: [1,2,3,4], // <- insert the id(s) of the entries you want to render
        action: 'pluginName/controllerName/renderTemplate', // <-- route to your controller
        templatePath: 'path/to/template'
    };
    $.ajax({
        type: "post",
        url: '',
        data: data,
        success: function (response) {
            if(response.success === true){
                $('#a-container').html(response.html);
            }else{
                alert(response.message);
            }
        },
        error: function (XMLHttpRequest, textStatus) {
            console.log("Status: " + textStatus);
        }
    });
});

Then you'll insert this function in your controller

/**
 * @throws \Craft\Exception
 */
public function actionRenderTemplate()
{
    $success = false;
    $message = Craft::t('Could not find template path');
    $html = '';

    // check for a template path
    if ($templatePath = craft()->request->getParam('templatePath')) {
        // check for entry ids
        if($entryIds = craft()->request->getParam('ids')){
            // fetch all entries with the ids
            $criteria = craft()->elements->getCriteria(ElementType::Entry);
            $criteria->id = $entryIds;
            $elements = $criteria->find();

            // render the template
            $html = craft()->templates->render($templatePath, ['elements' => $elements]);
            $success = true;
        }else{
            $message = Craft::t('Could not find required entry id parameter');
        }
    }

    // return as json
    $this->returnJson(
        [
            'success' => $success,
            'message' => $message,
            'html'    => $html
        ]
    );
}


Show Facebook Page Feed on Website From my searches it looks like Placid is the way to go for showing Facebook contenton the front-end of my website. What I'm completely confused about is how to get started. Does anyone have a simple step-by-step answer on how I connect Placid to my Facebook page?

First, you would need to create an app for your Facebook page. You are also going to need a Facebook developer account: developers.facebook.com. Once your app is created and you have a Facebook developer account, I would recommend starting with the Facebook open graph explorer: developers.facebook.com/tools/explorer. With the explorer, you can build/debug your URL to add to Placid. The documentation for the Graph API is here: developers.facebook.com/docs/graph-api


How can I display a "pending" entry in my "_entry" template? I have an event site with dates in the future and past.

I know how to display future entries as a listing:

{% set entries = craft.entries.section('mySection').status('pending') %}

But how do you display an entry with status "pending" on the "_entry" template?
In my case nothing displays?

I'm assuming that when you defined your section, you checked the box which says this:

  Entries in this section have their own URLs

... and then filled out the relevant Entry URL Format and Entry Template values. The great thing about this technique is that it automatically populates the entry variable in your target template. Typically, this is the best way to go!

But there are occasions where this isn't the suitable solution. There are certain circumstances in Craft which, by default, can prevent non-active entries from being included. I suspect this is one of those situations.

Here is what I would suggest instead...

Uncheck the box which says "Entries in this section have their own URLs", and save.
Setup a dynamic route. This is basically what the aforementioned checkbox was doing for you.
Declare your route using the same pattern that you had previously setup in your section definition.
Within your template, manually set the entry value, based on the parameters passed through in the URL.

{% set slug = craft.request.getSegment(2) %}
{% set entry = craft.entries.slug(slug).status(null).first %}

Here's where this manual method differs from the automatic method... Specifying null as the status will return that entry regardless of what its status is. Otherwise, only an active entry could be returned.

Because you are now manually setting the entry value, you have enough control to specify that you really do want this entry, despite the fact that it's not currently active.


Next and Previous Entries that match condition? Not sure if what I am looking is possible, but basically I have a section ('portfolio').  At the bottom of each entry I have links to the previous and next entry. Simple.

My trouble is that the body field in my entries is not always populated, and because of this I would like to by-pass these ones in my nav at the bottom of an entry page.

See my code below which is not working, I have a feeling that my logic is not going in the right direction at all with this...

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

{% set prevEntry = entry.getPrev(params) %}
{% set nextEntry = entry.getNext(params) %}

{% if prevEntry and prevEntry.body | length %}
    {% set image = prevEntry.portfolioImages.first() %}
    Previous
{% endif %}

{% if nextEntry and nextEntry.body | length %}
    {% set image = nextEntry.portfolioImages.first() %}
    Next
{% endif %}

You can add the "non-empty body" conditional to your parameters, as follows:

{% set params = craft.entries.section('portfolio').body(':notempty:') %}
{% set previousEntry = entry.getPrev(params) %}
{% set nextEntry = entry.getNext(params) %}
{# …and so forth #}


Call plugin controller from frontend with ajax I want to send an automatic back office email when user click on a button (to request support) on frontend. Then I just display a confirmation message (we ll get back to you shortly).

So I made a plugin controller sending email.
And my idea was to attach an ajax call with a jquery on click stuff to that button.

So I did this.

// SUPPORT ADHERENT button click
$(".call-support a").on("click", function(e, visible) {

    e.preventDefault();

    var data = {
        // ...
    };

    $.ajax({
        method: 'POST',
        url: '/actions/unep/toolBox/requestBrandingHelp',
        data: data,
        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
    })
        .success(function(data) {
            console.log('success', data);
        })
        .error(function(data) {
            console.log('error', data);
        });

});

My controller is called and send an email but I got a 404 error from the ajax call in console:

I checked that ajax call with Craft.postActionRequest here below but it is for back-end scope only.
http://buildwithcraft.com/docs/plugins/controllers#posting-to-controller-actions-with-javaScript
How reference "Craft" js object in jquery scope

I am a bit lost how to do that correctly...

I found the solution by making an application of Front end login form with ajax and Posting to controller actions.

Here is what is really important to understand with Craft controller call:

  Most of the time, you’ll want to access controller actions via HTML forms over POST. To do this, we recommend that you leave your form’s ‘action’ attribute blank, and specify your action via a hidden input named “action” instead:

<form method="post" action="" accept-charset="UTF-8">
    <input type="hidden" name="action" value="cocktailRecipes/ingredients/saveIngredient">

  When you leave your form’s ‘action’ attribute blank, browsers will default to the current request’s URL. Which is great in the event that your controller needs to reload the previous page without a redirect. A common example of this is when the user’s input didn’t validate, and you want to pass the errors back to your template (ideally tucked away within a model).

So my solution here with the correct HTML with the form to submit:

<form id="call-support-form" action="" class="form" method="post" accept-charset="UTF-8">
    <input type="hidden" name="action" value="/unep/toolBox/requestBrandingHelp">
    <input class="button" type="submit" value="Support adhérents">
</form>

And the ajax form submit to call the controller:
(and do whatever you want after)

// member support button click
$("#call-support-form").submit( function(e) {

    e.preventDefault();

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

    $.ajax({
        method: 'POST',
        url: '/',
        data: data,
        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
    })
        .success(function(data) {
            console.log('success', data);
        })
        .error(function(data) {
            console.log('error', data);
        });

});


Including plugin javascript on the client side I've created a simple plugin based on the Craft docs with the following directory structure...

/craft
    /plugins
        /eforms
            /resources
                /js
                    public.js
            /templates
                /public
                    index.html
/public_html

In the index.html template of my plugin I'm using the following line to try to include the public.js file...

{% includeJsResource "eforms/js/public.js" %}

Which attempts to include the following resource in the browser

http://mydomain/eforms/js/public.js

Unfortunately this just gives me a 404. Does anyone have an idea of what I'm doing wrong?

Think you need:

UrlHelper::getResourceUrl('path/to/file.ext')

There is more info over at http://buildwithcraft.com/docs/plugins/resources

Edit

ok, scrap that answer, I didn't read the rest of the help page :)

I think you are nearly there though. I'll have a test on my local machine and get back to you.

Edit 2

I believe I'm running into the same problem you have described as well. I did however get it working by doing this:

<script src="{{ resourceUrl('eforms/js/public.js') }}"></script>


Shouldn't this merge be working? Can anyone help me work out why the following returns the error "The merge filter only works with arrays or hashes."?

{# CREATE ARRAY TO HOLD ALL OF TODAY'S EVENTS #}
{% set todaysEvents = [] %}

{# GET TODAY'S ONE-OFF EVENTS #}
{# RETURNS ENTRIES NICELY IF LOOPED THROUGH #}
{% set todaysOneOffEvents = craft.entries.section('events').eventDate('= '~today | date("Y-m-d")) %}

{# ADD TODAY'S ONE-OFF EVENTS TO TODAY'S EVENTS %}
{# THIS RETURNS MERGE ARRAY ERROR #}
{% set todaysEvents = todaysEvents|merge(todaysOneOffEvents) %}

Try adding find() to your ElementCriteriaModel, I think without that function you're not actually saving your entries as an array in your variable todaysOneOffEvents yet.

Here's what I found in the Docs:

  You don’t actually need to call find() yourself though: It will be called automatically as soon as the ElementCriteriaModel is treated like an array (that is, as soon as you check how many elements there are using the |length filter, or start looping through the elements with a {% for %} loop).

We learn that merging doesn't "treat it like an array", good to know.

Edit: You can't use the length filter to "convert" the content of the variable to an actual array. Removed that part from the answer.


Get entry's from fixed ID array I'm trying to display a list of favorited entries. I have a wishlist with entry id's build with Shortlist. So now I want to display them but it doesn't work. The first part getting the favorited id's works perfect.

Here is my code so far:

        {% set favIds = [] %}

        {# LOOP TRUE FAV IDS AND MAKE ARRAY #}
        {% for list in lists %}
            {% if list.items is empty %}

No wishlist

            {% else %}
                {% for entry in list.items %}
                    {% set favId = entry.id %}
                    {% set favIds = favIds|merge([favId]) %}
                {% endfor %}
            {% endif %}
        {% endfor %}

        {# CONVERT favIds array in comma separated list #}
        {% set favIdString = favIds|join(', ') %}

        {% set wishlist = craft.entries.id(favIdString).fixedOrder('true') %}

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

But nothing shows up. If I output {{ favIdString }} I get a nice list if entry ID's. 9619, 9620, 9621, 9622, 9624, 9625

Turns out... the ID's are wrong. I've listed the shortlist ID's and not the entry ID's. Should use entry.elementId.

Here's the fix:

 {% for entry in list.items %}
      {% set favId = entry.elementId %}
      {% set favIds = favIds|merge([favId]) %}
 {% endfor %}


Prevent Activation Email on creation - Wait for Admin Approval I would like to prevent the 'Activate Your Account' w/link from being sent when users first registers via a front-end public registration.

I need activation to happen manually via an Admin.

I have temporarily blocked this by commenting it out in /craft/app/controllers/UsersController.php
Obviously I do not want to go to production with this, so how can I disable via a plugin?

The code in question appears on line 1049:

//
        if ($verifyNewEmail)
        {
            // Temporarily set the unverified email on the UserModel so the verification email goes to the
            // right place
            $originalEmail = $user->email;
            $user->email = $user->unverifiedEmail;

            if ($isNewUser)
            {
                // Send the activation email
                // $emailSent = craft()->users->sendActivationEmail($user);
                $emailSent = true; // *** NOT TRUE, BUT HACKED ***
            }
            else
            {
                // Send the standard verification email
                $emailSent = craft()->users->sendNewEmailVerifyEmail($user);
            }

            if (!$emailSent)
            {
                craft()->userSession->setError(Craft::t('User saved, but couldn’t send verification email. Check your email settings.'));
            }

            // Put the original email back into place
            $user->email = $originalEmail;
        }

Thanks to @BradBell - I just needed to use the Admin setting.

  Seems like you just want to uncheck "Verify Email Addresses?" under >Settings->Users->Settings


Issue sending email via Mandrill I've set up a site to send emails via Mandrill over SMTP.
However, this does not seem to be sending emails.

If I test the email config it says a message has been sent but the email is not received and there is no record of the email in the Mandrill Outbound messages.

Sending over SSL (which has worked on other Craft sites on same host) on port 465.

Suggestions appreciated as client not receiving messages through the site.

Cole

I'm on the same boat ... Check out http://status.mandrillapp.com . Your issues are, more than likely, due to Mandrill currently being down and having issues (for the past couple days now).


If Conditional for Lightswitch in Matrix Field I have a section that needs to display a certain block type (heroVideo) if a lightswitch (displayHeroVideo) within it is active. Otherwise, it should display a different block type (heroImage).

How can I write a conditional to accommodate this?

Here's what I have already which outputs both blocks if the lightswitch is active. How do I apply the conditional earlier?

{# Start hero section #}
{% for entry in entry.heroFeatured.limit(1) %}
  {% for block in entry.hero %}

  {% if block.type == "heroVideo" and block.displayHeroVideo == "1" %}

Hero Video Markup

  {% else %}

Hero Image Markup

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

You're close! The way you have your conditional set up now will print Hero Image Markup if either of your conditionals fail. By checking if block.displayHeroVideo is 1 on a block type that doesn't have that field, Twig will still return 0. You should only check displayHeroVideo when you know you are inside of a heroVideo block.

{% for entry in entry.heroFeatured.limit(1) %}
    {% for block in entry.hero %}

        {% if block.type == "heroVideo" %}

            {% if block.displayHeroVideo == "1" %}

Hero Video Markup

            {% endif %}

        {% else %}

Hero Image Markup

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


Can I find log activity of who deleted a user and who edited an entry? Is there a 'latest greatest' tool that I can add that has ongoing logging of disable/enable and delete/update activity of users or entries, etc..?

Is there a good way to track this information before I add on a logging tool?  In other words, is this information somewhere in the mysql database anyways?

I know the current dashboard shows information related to entry creation, but, we have some new users that we are training and they have made some mistakes and we need to track those mistakes down.

thanks!

Craft only stores minimum audit information in the database... mainly just when a row was created and last updated.

If you're on Craft 2, there is a deprecated Audit Log plugin which might do what you're looking for.

I don't think the author has intentions of porting it to Craft 3, but there is a commercial plugin called Audit that is in the Craft Plugin Store.


weighted random order I have a field in a channel called "weight" where the user can set a number between 0-1000. On page load I want to generate a random number between 0 and "weight" for each entry, and then sort the entries based on these numbers.

How can I do this with Craft 2/Twig?

Would be a lot cleaner/more efficient to do this from a custom plugin in PHP, but if you want to do it from a template, this should work:

{% set entryArr = {} %}

{# Grab all of the entries in the section #}
{% set entries = craft.entries.section('news').find() %}

{# Loop through them generating a random number between 0 and the weight custom field #}
{% for entry in entries %}
    {% set entryArr = entryArr|merge({(entry.slug): random(range(0, entry.weight))}) %}
{% endfor %}

{# Sort the array by the ascending value maintaining the keys #}
{% set entryArr = entryArr|sort %}

{# print them off #}
<ul>
{% for slug, randomNumber in entryArr %}
    {% set entry = craft.entries.slug(slug).first() %}
    <li>{{ entry.title }} - Max Range: {{ entry.randomNumber }} - Random Number: {{ randomNumber }}
{% endfor %}
</ul>


Possible to get content block from another entry? I guess this isn't possible as it would mean the content is essentially a Global, but I would like to be able use a block from a matrix field from another entry.

At the moment I have a parent page with a block of content, which I would like to replicate on all of it's child pages. I don't want to make the user repeat it on each child page, but I don't want to hardcode it.

You can query for that parent page's entry model with a new ElementCriteriaModel.

{% set mainEntry = craft.entries.id(100).first() %}

{% if mainEntry %}
    {% set matrixField = mainEntry.matrixFieldHandle %}
    {% set firstContentBlock = matrixField.type('content').first() %}

    {% if firstContentBlock %}
        {{ firstContentBlock.myRichTextFieldHandle }}
    {% endif %}
{% endif %}

Instead of using the entry's ID as the link to that entry, you can also use other parameters to query for the entry model. Here's an example using slug and section:

{% set mainEntry = craft.entries.section('news').slug('main-news').first() %}


Entry Form Validation on Front End Form I have a front end form based on the entry form example provided by craft documentation which allows logged in users to submit an entry to a specific section. Form validation is not working in that required fields are not being picked up on submission. So if the field is empty it still submits the form.

I have the user group set up so users are not able to use the CP or submit live entries so the entry is sent through as disabled so that the admin users can monitor entries before enabling them.

Am I correct in thinking that because the entry is being saved as disabled that craft does not validate the post data? If this is correct what is the work around as I do not want users to be able to post live entries.

Cheers

You're correct. Craft will not run validation upon saving disabled elements.

This is not a bug – it's just designed that way (as far as I can tell from looking at the relevant source code in the ElementsService).

As for a workaround – you'll need a plugin.

This is the easiest approach I can think of:

Listen for the entries.onBeforeSaveEntry event
In the event handler, validate the entry model manually, if the entry is disabled
If validation fails, add error messages to the model and set the $event object's performAction attribute to false

This should stop the entry from going through, and should also display any error messages in your form:

craft()->on('entries.beforeSaveEntry',function(){
    $entry = $event->params['entry'];
    if(!$entry->enabled && !craft()->content->validateContent($entry))
    {
        $entry->addErrors($entry->getContent()->getErrors());
        $event->performAction = false;
    }
    return $event;
});

Anyway, since I wanted to test the above before responding here, I wrote the plugin. It seems to do the job, so hopefully it'll help you out!

https://github.com/mmikkel/AlwaysValidate-Craft


Environment Variable siteURL ignored In my general.php file I have a siteUrl environment variable declared:

'ontherocks.dev' => array(
    'devMode' => true,
    'environmentVariables' => array(
        'siteUrl'  => 'http://local.ontherocks.dev/',
    )
),

'dev.livesite.com' => array(

    'environmentVariables' => array(
        'siteUrl'  => 'http://dev.livesite.com/',
    )
)

But when calling it on my page to get page url: siteUrl ~ entry.url
siteUrl is appearing as it is defined in the Craft CMS General Settings SiteUrl.
Is it possible for the environment variable to take precedence?

In your Control Panel, go to Settings > General.

Then set your Site URL to {siteUrl}.

This will parse out the siteUrl environment variable. For more information, see this thread...


Show only children of current page in submenu I have checked the official documentation and also these pages:

How do you only show children of "active" parent in a Structure section's nav?

How to output a structure sub-navigation of current page

I still can't get this to work though. I have tried various code and currently have this (from official docs):

{% set pages = craft.entries.section('pages').level('>1') %}
{% nav entry in pages %}

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

               {% children %}

         {% endifchildren %}

{% endnav %}

This outputs all the children whenever I'm on any top level page. My structure is a little different though, like so (shortened for brevity):

Home
About (structure: 'pages', entry type: 'aboutPage')
  - Aims (structure: 'pages', entry type: 'aboutPage')
  - Governance (structure: 'pages', entry type: 'aboutPage')
Services (structure: 'pages', entry type: 'servicesPage')
  - Residential (structure: 'pages', entry type: 'servicesPage')
  - Homecare (structure: 'pages', entry type: 'servicesPage')
Resources (structure: 'pages', entry type: 'resourcePage')
  - Health (structure: 'pages', entry type: 'resourcePage')
  - External (structure: 'pages', entry type: 'resourcePage')

You can see I have a tree which uses a single 'pages' structure to keep everything obvious in the admin section. I then just create an entry, choose the parent and choose the entry type to add content.

I use a structure 'mainMenu' to add links manually to the main menu using a related entry field. So I have:

Home - About - Services - Resources

As top level pages. When I'm on a top level page, I want to show children of this current page and to hide the unordered list element when there are no children of the current page, and I'm stuck.

Can anyone point me in the right direction? Thanks in advance.

Ran into the same issues you had. Pulled this from a working site I recently built.

Basically you have to get the topmost page. I found entry.getAncestors().level(1).first() works for that no matter what level you're in.

From there, you just get everything that's underneath it. But first check to see if there's actually any children using {% if topLevel.hasDescendants %}

       <! -- local navigation -->

        {% set topLevel = (entry.level == 1) ? entry : entry.getAncestors().level(1).first()  %}

        {# don't show the tree if nothing's under it #}

        {% if topLevel.hasDescendants %}

{{topLevel}}

            {% set subnav =  topLevel.getDescendants()  %}

            {% nav page in subnav  %}
            {% if page.id != entry.id %}
{{ page.getLink() }}
{%else%}
{{page}}
{%endif%}

                {% ifchildren %}

                            {% children %}

                {% endifchildren %}

            {% endnav %}

       {% endif %}


Code shows instead of homepage A website I built frequently throws up the following code instead of the homepage:

<?php

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

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

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

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

require_once $path;

I have followed the Craft CMS install guide to the letter. Here's the output from php.ini:

engine = On
zend.ze1_compatibility_mode = Off
short_open_tag = On
asp_tags = Off
precision    =  12
y2k_compliance = On
output_buffering = Off
zlib.output_compression = Off
implicit_flush = Off
serialize_precision = 100
safe_mode = Off
disable_functions =
realpath_cache_size=256k
expose_php = Off
max_execution_time = 600     ; Maximum execution time of each script, in seconds
max_input_time = 6000   ; Maximum amount of time each script may spend parsing request data
memory_limit = 768M      ; Maximum amount of memory a script may consume (128MB)
error_reporting  =  E_ALL & ~E_NOTICE
display_errors = Off
display_startup_errors = Off
log_errors = On
error_log = /var/sites/t/domain.com/public_html/error_log
log_errors_max_len = 1024
report_memleaks = On
track_errors = Off
variables_order = "EGPCS"
register_globals = Off
register_argc_argv = On
auto_globals_jit = On
upload_max_filesize = 100M
post_max_size = 100M
magic_quotes_runtime = Off
magic_quotes_gpc = Off
magic_quotes_sybase = Off
auto_prepend_file =
auto_append_file =
default_mimetype = "text/html"
extension_dir = "/usr/newage/lib/php/extensions/no-debug-non-zts-20151012"
enable_dl = Off
file_uploads = On
upload_tmp_dir = /tmp
allow_url_fopen = On
allow_url_include = Off
default_socket_timeout = 60
date.timezone = Europe/London
mysql.allow_persistent = On
mysql.max_persistent = -1
mysql.max_links = -1
mysql.default_port =
mysql.connect_timeout = 60
mysqli.max_links = -1
mysqli.default_port = 3306
mysqli.default_socket =
mysqli.default_user =
mysqli.default_pw =
mysqli.reconnect = On
[Session]
session.save_handler = files
session.save_path = /tmp
session.use_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.serialize_handler = php
session.gc_probability = 0
session.gc_divisor     = 100
session.gc_maxlifetime = 14400
session.bug_compat_42 = 1
session.bug_compat_warn = 1
session.referer_check =
session.entropy_length = 0
session.entropy_file =
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.hash_function = 0

#zend_extension="/usr/newage/lib/php/extensions/no-debug-non-zts-20151012/ioncube_loader_lin_5.6.so"
#zend_extension_ts="/usr/newage/lib/php/extensions/no-debug-non-zts-20151012/ioncube_loader_lin_5.6_ts.so"
#zend_extension=/usr/newage/lib/php/extensions/no-debug-non-zts-20151012/ZendGuardLoader.so
always_populate_raw_post_data=-1

The error log set in php.ini is showing up empty.

Via the Craft CPanel, I'm seeing the following recurring errors from the logs tab:

Here's the Server info via the Craft CPanel:

My host has told me that ImageMagick isn't available on the PHP version I'm running (7.1).

For iconv extension, the info bubble is reading:

  You have a buggy version of iconv installed. (See PHP bug #48147 and
  iconv bug #13541

My host has recently fixed load issues on one of their hosting clusters, which I initially thought might be causing the problems, but I'm still getting 503 errors.

This may be unrelated, but the site also jumps from having normal permalinks, like so:

https://www.domain.com/pretty-page-url

To messy permalinks, like this:

https://www.domain.com/index.php/pretty-page-url

If your website is showing the text of your index.php instead of the actual website code, something is misconfigured with your server setup. Anything .php should be passed along to php-fpm or whatever CGI handler you're using.


How do I exclude a Channel, Structure or Singles from search? I'm trying to figure out how to exclude a Channel, Structure or Singles from my search results.

Currently I have the default example from Craft

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

This should work for a single section:

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

to exclude more sections:

{% set entries = craft.entries.section([
    'and', 'not news', 'not blog'
]).search(query).order('score') %}


Eager-Loading Assets in Matrix I've been using this example to eager load images, stored in an Assets field which is located in a Matrix field.

My query looks like this:

{% set entries = craft.entries.section('project')
.with(['projectMatrix.imageBlock:imageFile']) %}

Where projectMatrix is a Matrix field, imageBlock is a Matrix block type and imageFile is an Asset field inside imageBlock.

But how do I reference the that image in my templates?

{% for entry in entries %}

{% set matrixImage = entry.projectMatrix.type('imageBlock')[0].imageFile[0] ?? null %}

...

{% endfor %}

This is always be null, when eager loaded

The reason this doesn't work is because .type('image') won't work with eager loading. Eager loading removes the ability to use ElementCriteriaModel methods.
From the docs:

When the assets aren’t eager-loaded, entry.assetsField gives you an ElementCriteriaModel that is preconfigured to return the related assets once they’re requested (e.g. when first() is called).
However when the assets are eager-loaded, entry.assetsField gets overwritten with an array of the eager-loaded assets. So first(), find(), and other ElementCriteriaModel methods are not available. Instead you must stick to the standard array syntaxes.

As a work around, you could use a for loop to match only Matrix blocks of a particular type instead:
{% for block in entry.projectMatrix if block.type == 'imageBlock' %}
  {% set matrixImage = block.imageFile[0] %}
{% endfor %}

If you only want the first image block type:
{% for block in entry.projectMatrix if block.type == 'imageBlock' %}
  {% if loop.index == 1 %}
    {% set matrixImage = block.imageFile[0] %}
  {% endif %}
{% endfor %}


Replace in the first instance? I am trying to insert a div that'll call an ad between two paragraphs of copy text.

However, I'd like to do it only one instance. The current replace code I'm using is this - which is inserting my test code multiple times.

    {% set str = block.bodyText %}
    {{ str | replace('

', '

') | smartypants }}

Is it possible?

I can't think of a way to do this with Twig's replace filter but it is possible to do it by splitting the text into an array and iterating over it like so:

{% set content %}

Duis mollis, est non commodo luctus.

Nulla vitae elit libero, a pharetra augue.

Donec sed odio dui. Maecenas faucibus mollis interdum.

{% endset %}

{% set inserted %}

Inserted text

{% endset %}

{# Split text into array on closing
 tags #}
{% for paragraph in content | split('
') %}
  {# Add the closing tag back, except for possible empty lines  #}
  {% set paragraph = paragraph | trim | length ? paragraph ~ '
' : '' %}
  {# Render the text as raw html #}
  {{ paragraph | raw }}
  {# Render the inserted paragraph on the first loop #}
  {% if loop.index == 1 %}
    {{ inserted }}
  {% endif %}
{% endfor %}

Edit: Per your question in the comment about the context, this is a good use case for a macro. This code is untested, but you might try something like this.

{% macro insertAfterFirstParagraph(content, insertContent) %}
  {% for paragraph in content | split('
') %}
    {% set paragraph = paragraph | trim | length ? paragraph ~ '
' : '' %}
    {{ paragraph | raw }}
    {% if loop.index == 1 %}
      {{ insertContent }}
    {% endif %}
  {% endfor %}
{% endmacro %}

{% from _self import insertAfterFirstParagraph %}

{% set addThisHtml %}

Add this paragraph

{% endset %}

{% set isAdded = false %}
{% for block in entry.myMatrixField %}
  {% if block.type == 'body' and loop.index > 5 and isAdded == false %}
    {{ insertAfterFirstParagraph(block.bodyField, addThisHtml) }}
    {% set isAdded = true %}
  {% else %}
    {{ block.bodyField }}
  {% endif %}
{% endfor %}

Robin's suggestion to build a custom Twig filter in a plugin (or module) would be the cleanest solution, but the Twig code above should get the job done.

Aside: Craft overrides the default Twig replace filter to use PHP's preg_replace() function but that filter doesn't accept the last two optional arguments, limit and count. If it did, then something like this could have worked:

replace('/<\\/p>\\s+?
/', '

', 1)

Maybe a feature request is in order.


Use cache instead of saving to database With my plugin I am generating and saving a lot of data to a secondary table. Data that can be generated on the fly that is associated with entries. I have noticed a performance hit and was given a suggestion of caching some of that data instead of writing to a database.

Does craft have a built in caching system I can use for accomplishing something like this?

craft()->cache can point to any one of several different caching drivers as defined by the   cacheMethod config setting.

The available methods are all pretty much stock Yii provided caching drivers, with the exception of FileCache, which we've extended a bit.

Note that FileCache is used by default and its values are saved under the craft/storage/runtime/cache folder.


How Can I Output Only the First Word of the Title of an Entry in a Template? Is it possible to output only the first word of the title of an entry in a template? If so, how? Thanks!

Yes, you can do this with Twig alone. Here's how:

{{ entry.title|split(' ')|slice(0, 1)|join }}

This series of Twig filters:

Uses split to turn the title into an array, splitting on spaces.
Passes that array through slice to grab the first item in the array.
Then uses join to turn the array back into a string for output. The array is now just one item (the first word of the title), but join is needed because Twig doesn't want to treat an array as a string.


Associating multiple FreeForm entries with a single Craft entry I have a Freeform which collects information on item(s) to be converted from analog to digital (VHS tape 16mm film, etc). The form requires the user to be logged in.
There may be cases where the user fills out the form more than once, because they have more than one item to convert. I want to do two things:

Save the results of each form submission in a standard Craft entry. I believe I understand how to do this, I just need to hook up all the fields.
Relate one or more form submissions to a single "order", which I believe would be represented by a single Craft entry.

An order entry would have:

User
Date
Relationship to 1 or more form submissions.

What is simplest way to accomplish this? FYI, I do not want to write a custom plug-in, nor write a lot of code.
My first thought was to create an initial order form which collects only the title of the order, and then pass that via a query string or JavaScript into the second form, thus creating a relationship where the first form is the "parent" and submissions of the second form are the children.

I was thinking about this myself, and I found the following 2 articles which I have been going over. It looks like it is quite possible:
http://craftsnippets.com/articles/using-template-hooks-in-craft-cms
https://docs.solspace.com/craft/freeform/v3/overview/relations.html#overview
The 2nd link has a heading for “Relating more than one element” which looks like it would apply in your situation.


Craft 3.6 Upgrade errors - can only install one of yiisoft/yii2 (and other errors) I'm new to Craft so maybe I'm doing something dumb, but I can't get past this error screen when trying to update to 3.6:
Composer output: Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

Problem 1
- Can only install one of: yiisoft/yii2[2.0.38, 2.0.40].
- Can only install one of: yiisoft/yii2[2.0.40, 2.0.38].
- craftcms/cms 3.6.5.1 requires yiisoft/yii2 ~2.0.40.0 -> satisfiable by yiisoft/yii2[2.0.40].
- Installation request for craftcms/cms 3.6.5.1 -> satisfiable by craftcms/cms[3.6.5.1].
- Installation request for yiisoft/yii2 (installed at 2.0.38) -> satisfiable by yiisoft/yii2[2.0.38].

Running update with --no-dev does not mean require-dev is ignored, it just means the packages will not be installed. If dev requirements are blocking the update you have to resolve those problems.

I deleted the composer.lock file based on some threads I found here, and I tried running composer update from the terminal and it did reduce a much longer error message down to this one, but still no joy.
I'm developing locally on MAMP, 3.5.x was running great.
My composer.json:
{
  "require": {
    "craftcms/cms": "3.5.18",
    "craftcms/contact-form": "2.2.7",
    "craftcms/feed-me": "4.3.4",
    "craftcms/mailgun": "1.4.3",
    "craftcms/redactor": "2.8.5",
    "vlucas/phpdotenv": "^3.4.0"
  },
  "require-dev": {
    "yiisoft/yii2-shell": "^2.0.3"
  },
  "autoload": {
    "psr-4": {
      "modules\\": "modules/"
    }
  },
  "config": {
    "sort-packages": true,
    "optimize-autoloader": true,
    "platform": {
      "php": "7.2.5"
    }
  },
  "scripts": {
    "post-root-package-install": [
      "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
    ]
  }
}

I found the fix here
composer install --ignore-platform-reqs


Nesting level too deep - recursive dependency? I've got a page with a couple of levels of loops. It takes a section of speakers, groups them by state, and then loops through the states, and then loops through speakers in that state. It's not too complex so I wouldn't expect to see an error like "nesting too deep".

Here's (a reduction of) the code:

{% set speakersByState = speakers|group(s => s.state.one().slug) %}
{% for state, speakers in speakersByState %}

    {% for speaker in speakers|sort %}

{{ speaker.title }}

    {% endfor %}

{% endfor %}

I figured this out, with help from a GitHub thread or too. It appeared that using the sort filter on an array of objects was problematic. I was able to fix this by sorting the keys in speakers instead of directly sorting speakers.

Working code:

{% for speakerKey in speakers|keys|sort %}
  {% set speaker = speakers[speakerKey] %}

  <li>{{ speaker.title }}</li>
{% endfor %}

I'm not 1000% sure exactly what was breaking, but I think by using |sort on a collection of objects, PHP ended up recursively looping through the speakers array in an attempt to sort it.

Here are some related threads that I pieced together to guess that |sort was the problem:

Nesting level too deep when looping through matrix blocks
https://stackoverflow.com/questions/3834791/fatal-error-nesting-level-too-deep-recursive-dependency
https://github.com/craftcms/cms/issues/5794


Is it possible to set any attributes (such as a class) of the `a` tag when using `getLink()`? This code:

{{ foo.getLink() }}

Outputs this:

NAME_OF_PAGE

What I really want is something like:

NAME_OF_PAGE

Is it possible to set "class" and/or other html attributes when using Craft CMS Entry Property getLink()?

No, getLink outputs a very simple version of the link.

If you want something more complex, you'll need to build it manually...

{{ foo.title }}


How to improve performance of this nested entries/array template? I have an event calendar of sorts for music gigs. The back-end has sections for Artists and Venues, where I enter appropriate info, and another section, Shows, which I choose an artist, a venue, and enter the event date (in a custom field).

The template that pulls everything together grabs all future show dates, groups the dates by the artist, then checks each entry for fields before displaying it in the HTML, like so:

{#-- grab all current shows and order by date --#}
{% set all_shows = craft.entries.section('shows').gig_date('>=' ~ (now.date)).order('gig_date asc') %}

{#-- group shows by artist --#}
{% set artist_shows = all_shows|group('gig_artist.first()') %}

{% for artist, shows in artist_shows %}

    {#-- artist title --#}

{% if shows[0].gig_artist[0].artist_url|length %}{{ artist }}{% else %}{{ artist }}{% endif %}

            {#-- shows list --#}
            {% for show in shows %}

                        {#-- date --#}
                        <time title="{{ show.gig_date.w3c }}">{{ show.gig_date|date('F j') }}</time>

                        {#-- venue name and website--#}
                        {% if show.gig_venue[0].venue_url|length %}{{ show.gig_venue[0].title }}{% else %}{{ show.gig_venue[0].title }}{% endif %}

                        {#-- city --#}
                        {% if show.gig_venue[0].venue_city|length %}, {{ show.gig_venue[0].venue_city }}{% endif %}

                        {#-- state --#}
                        {% if show.gig_venue[0].venue_state|length %} {{ show.gig_venue[0].venue_state }}{% endif %}

                        {#-- notes --#}
                        {% if show.gig_notes|length %}
{{ show.gig_notes }}
{% endif %}

            {% endfor %}

{% endfor %}

This page takes several seconds to render on my site versus the other pages. I've tried this without the |group filtering, and without the date comparison, and it's still equally slow, which leads me to believe it's the pinging the multiple entry fields that's slowing things down.

I have a hunch eager loading will be helpful, but unfortunately I can't wrap my brain around it at this level. Any ideas?

Have you considered to cache the whole output? https://craftcms.com/docs/templating/cache


The smoothest way to store JSON object to an entry? I'm creating a page where I have a bunch of entries I want to populate with jquery drag and drop boxes. It's for the arrangement of songs, just as a tool.

And I want to store the position of these in a JSON object. When I was using Expression Engine I managed to send an SQL command and store the data in the correct fields. Albeit it was kinda wonky.

But now I'm using Craft so I figure there might way better ways of doing stuff like this. Do I use a form? Do I hide that form and send it using AJAX every time I make some changes to the jquery drag and drop boxes?

It's a little tough to say, since you it seems like you haven't actually architected any of this in the Craft back-end yet. I encourage you to create a field (or fields) which would be a good container for this data.

Once you've established what kind of field you're using, you may find that there is a different answer... but based on your current intent to store a simple JSON object, it sounds like you'd be using a simple plain text field.

Assuming you're using a plain text field, this is actually quite simple to accomplish. Use your JavaScript to set the value of a hidden field, before submitting the form:

<input type="hidden" name="fields[songsJson]" value="" />

More info on saving entry data from a front-end form:

  https://craftcms.com/docs/templating/entry-form


Create a variable from content in a matrix field I want to create a variable based on the contents of a matrix block.  This is the code I created:

{% for item in entry.screenshot %} //my matrix field
    {% for asset in item.webpage %} // an asset field in the block
        {% set backgroundUrl = asset.url %} //want to declare a variable using the asset url
   {% endfor %}
{% endfor %}

This throws a "backgroundUrl not defined" error when I try to use the variable.  Obviously my syntax is wrong.  Any advice would be appreciated!

This is a twig thing. Loops in twig are scoped. Variables defined in a loop cannot be used outside of that loop. To fix this, you simply have to declare the variable before the loop:

{% set backgroundUrl = "" %}
{% for item in entry.screenshot %}
    {% for asset in item.webpage %}
        {% set backgroundUrl = asset.url %}
   {% endfor %}
{% endfor %}

If you know that you only have one asset you can shorten it a bit with:

{% set backgroundUrl = "" %}
{% for item in entry.screenshot %}
    {% set backgroundUrl = item.webpage.first().url %}
{% endfor %}


Mail: There was an error testing your email settings I'm trying to use mailgun to send emails. I'm on my local machine and I get the error: "There was an error testing your email settings." The API key matches up correctly and nothing of significance seems to be showing up in my logs. Can someone suggest another way of debugging this? The error message isn't too helpful on it's own. Thanks.

Check your Craft storage/logs folder for the underlying error message.  You can also use these knowledge base articles to help debug what's going on based on what you find:

https://craftcms.com/knowledge-base/troubleshooting-email-errors

https://craftcms.com/knowledge-base/why-doesnt-craft-send-emails


Is it possible to Filter entry types via the URL? I'm wondering if it's possible to dynamically filter a section list by entry type based on a url segment?

I'm hoping to avoid assigning a category to every entry.

Yes, it is possible.

Pass the entry type handle to a segment and access that segment using the craft.request getSegment() method. Use this segment variable with the craft.entries .type() method to fetch only the entries of the given type. The example below assumes your entry type handle is in segment 2.

{% set entries = craft.entries.section('pages').type(craft.request.getSegment(2)) %}

{% for entry in entries %}
    <li>{{ entry.title }}</li>
{% endfor %}


Ordering/sorting products by their variant stock level I'm trying to implement a sort order in my product listings so that all of the out of stock products are last.

I'm unsure how or if this is possible because the stock is set on the variants of a product and I'm listing the products.

The stock level would need to take into account the stock of all the products variants.

I know we have the ability to only fetch products that have stock with the criteria hasVariant: { hasStock: true }, but is there a way I can sort them using the .order() criteria?

Not possible at the moment, Craft would need to add better support for custom element sorting.

Can you please submit the request here so we can track it: https://github.com/craftcms/commerce/issues

This answer will be updated if there is a change.


Why do the plugin resource paths include the localization prefix? I'm using Craft in a multilingual setup with the Smart Map plugin. However, the CSS and JavaScript files are not being linked properly when the site isn't in the main language.

For some reason, the paths to the plugin resources contain the language prefix:

/en/cpresources/smartmap/css/smartmap.css

Is this normal behaviour? How can it be fixed?

Good question... As far as I know, the plugin's resource paths should not include the localization prefix. The resources are being called via PHP in the most direct way possible:

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

I'm not entirely sure, but I suspect this may be a Craft bug. I've reached out to Pixel & Tonic in order to fully diagnose the problem. If the plugin code needs to be corrected, I will implement a fix as soon as we can figure out what's going on.