Show more entries on click So, I'm kinda new to Craft so there might be a easy trick to do this but I can't seem to get it working (even with some heavy googling).

On the homepage I've got three entries (from the Projects page) loaded and I'd like to load +3 more entries everytime a 'load more' button is clicked. I've already figured out the best way to do this is using the {% paginate %} function limited to 3 entries but thats where I'm kinda stuck right now..

Is there a way to change the limit on click or something better?

You will have to accomplish this without pagination. This is a non-javascript way.

{% set page = craft.request.getParam('page') ? craft.request.getParam('page')|number_format : 1 %}
{% set batch = 3 %}
{% set limit = page * batch %}
{% set newPage = page + 1 %}

{% set items = craft.entries.section('projects').limit(limit) %}

{% for item in items %}

{{ item.title }}

    {# other markup for each item #}
{% endfor %}

More

This just increases the limit by the page number and the factor of BATCH while providing the next page number for the button url.


Using Preparse field to display matrix blocks in Control Panel, limitations? I can successfully use the Preparse field type to display matrix fields in the control panel, however, the output is very limited. Even my  tag is stripped out.
Is there any way to do this short of writing a plug-in?
And if not, what is the simplest possible plug-in I could use as a base for this.
{% for thing in entry.myMatrixField%}
  {{ thing.item }} - {{ thing.amount|number_format(2, '.', ',') }}<br>
{% endfor %}

There may be a better answer, but this is what I have come up with. Using Control Panel JS, combined with Preparse field(s), I am adding characters in like this
{% for thing in entry.myMatrixField %}
  {{ thing.item }} - {{ thing.amount|number_format(2, '.', ',') }}^
{% endfor %}

And then using some basic jQuery to replace the ^ character with a line break. It's a bit clumsy, but it works. Now I can get Matrix fields to display in the control panel. Items, Budget line, Prices are all fields within my Matrix block. Just have to get them out separately.


Categories children in Bootstrap navbar I am trying to put my categories and their children into a Bootstrap navbar. If category has Children it should become a dropdown link.

Here is the code:

{% set categories = craft.categories.group('compositions') %}

   {% nav entry in categories %}

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

       {{ entry.title }}

       {% children %}

{% endifchildren %}

    {% endnav %}

It kind of work except that the top categories appear twice:

once with the dropdown and the children (which I want)
and once without the dropdown.

How could I nest those children without repeating them?

I guess it would be easier to use a for-loop instead of that nav-loop in your case. Although it's harder to get multi-level-dropdowns

{% set categories = craft.categories.group('compositions') %}

    {% for entry in categories %}
      {% if not entry.hasDescendants() %}

{{ entry.title }}

      {% else %}

          {{ entry.title }}

            {% for child in entry.getDescendants() %}
              {{ child.title }}
            {% endfor %}

      {% endif %}


Craft Form Event - Target a Single Form I'm newish to Craft CMS.

Im building a plugin for a client, one of their forms needs to post inputted data to an api then return a result to a hidden text area before the email if fired off.

I have built the form and plugin with event, only problem is this event fires with every form i have on the site now. is it possible to target a form handle in the event ?

Currently using

craft()->on('amForms_submissions.onBeforeSendEmail', function (Event $event) {
    $params = $event->params();
}

Thanks in advance

The following code fires the onBeforeEmailSubmission event (link)

// Fire an 'onBeforeEmailSubmission' event
$event = new Event($this, array(
    'email'      => $notificationEmail,
    'submission' => $submission,
));
$this->onBeforeEmailSubmission($event);

So you'll have access to the $submission and to the $email as array keys in your $params variable. In order to get the form you have to do

$submission = $params['submission'];
$form = $submission->getForm();
if($form->handle === 'whatever'){
     // do something
}


Querying by lightswitch field type in template I have a field (mdFeatured) set up as a lightswitch field type. I am trying to retrieve both featured and non-featured entries:

{% set featuredEntries = craft.entries.section('merchantDirectory').mdFeatured(true).relatedTo(category).find() %}
{% set normalEntries = craft.entries.section('merchantDirectory').mdFeatured(false).relatedTo(category).find() %}

The featured entries are being retrieved properly, but the normal entries are returning both featured entries and normal entries mixed together. Any possibly know why this is not working? I tried replacing "true" and "false" with "1" and "0" but that did not seem to work either.

Thanks!

You could try looking for an empty string: mdFeatured('') or prefix 1 or true with not: mdFeatured('not 1').


Craft 3 to webserver (with only access to public_html ) I just wanted to deploy, my site live, but I was running to some issues.
I read that I should put only the web folder to public_html and all the other folders and files above that.

But on my server provider I have only access to the public_html folder itself, and I cannot go above that.

I found this guide: https://craftcms.com/guides/moving-craft-files , but when I apply this, I myself wont have access to the folder, so I cannot open the admin dashboard.

Is there a way to set an exception for myself, or I am doing something completely wrong?

I figured out, I wasnt keeping my web folder in the root, that was the problem.


Using 'replace' with a regex is throwing an error. Any ideas why? I am attempting to strip out <p> tags around <img> tags that are automatically getting generated in a WYSIWYG field.

The error: preg_replace(): Unknown modifier '&gt;'

{{ story.html|raw|replace('/<p>\s*(<a .*>)?\s*(<img .* \/>)\s*(<\/a>)?\s*<\/p>/iU','\1\2\3') }}

Thanks!

I'm not sure what's going on with the story.html part, but you'll need to double escape your regex.

Assuming you have an entry already with a story Rich Text field, it'd look like this:

{{ entry.body|raw|replace("/<p>\\s*(<a .*>)?\\s*(<img .* \\/>)\\s*(<\\/a>)?\\s*<\\/p>/iU", "\1\2\3") }}


passing the search query into html title tag I wish to show the search query inside the page template but my logic seems to be off and just shows {{ query }} as a string.

What's the best way to achieve this?

{% extends "_layout" %}
{% set query = craft.request.getParam('q') %}
{% set title = "Search results for: {{ query }}" %}

You should be able to use:

{% set title = "Search results for: " ~ query %}


Link to an entry to a related section I have a section called reviews and a section called games.
A entry field in games is creating a relationship to reviews.

On my _entry.html entry for reviews, I want to link back to the related game.

My code is below. I understand why it isn't working, but not sure how to fix it.

The template displays the Review entry title, the body some extra fields in reviews.

And then gets to the Game Link, but the link is not to my Games section but to my Reviews section.

In other words, on this review:
http://www.colorcomputergames.com/reviews/1984-01-01/glaxxons

The link at the bottom should be to:
http://www.colorcomputergames.com/games/glaxxons

But instead, goes to:
http://www.colorcomputergames.com/reviews/1984-01-01/glaxxons

{{ entry.title }}

    {% if entry.ReviewsAuthor|length %}
Reviewer: {{ entry.ReviewsAuthor }}
{% endif %}
    {% if entry.ReviewsMedia|length %}
Media: {% for category in entry.ReviewsMedia %}{{ category.title }}{% endfor %}
{% endif %}
    {% if entry.ReviewsDate|length %}
Date: {{ entry.ReviewsDate.format('F Y') }}
{% endif %}
    {% if entry.ReviewsRelatedLink|length %}
Related Link: {{ entry.ReviewsRelatedLink }}
{% endif %}

{{ entry.body }}

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

Game Link:

{{ entry.title }}

As mentioned, in section called Games, I have a field called GamesReview and set it to entries and assign the review entry. Do I need to do the opposite as well t make this work? That is, in my reviews section, create a field called GameReviewed and set it to entries and assign it to Games section.

Thanks

Your code isn't working because you set the related game(s) to a variable entries (i.e. {% set entries = craft.entries...%}), but you're not actually doing anything with that variable. Then you try to render the link to the related game(s), but you're simply re-using the entry variable – which refers to the review entry, not the related game entry.

If you change

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

Game link:

...

to something like

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

Game Link:

        {% for game in relatedGames %}

{{ game.title }}

        {% endfor %}

{% endif %}

...it should work.

Note that in some cases, its a good idea to be as specific as possible when you're dealing with relations. Simply doing relatedTo(entry) will work, but you can also let Craft know where the relation was created (i.e. in which field), and whether the related elements you're looking for is the source or the target elements for the relation. In this case, then Entries field is on the game entry, which means that the review entry is the target element (i.e. the entry that has been selected in an Entries field), and the game entry is the source element (i.e. the entry that actually has the Entries field in its field layout).

Assuming your Entries field on the game entry has a handle relatedReviews, a more specific relatedTo query for your use case could look like this:

{% set relatedGames = craft.entries.section('games').relatedTo({
    field: 'relatedReviews',
    targetElement: entry
}) %}
...

Being specific about relations can be more performant, and helps avoid issues where you might have multiple relations involving the same elements (e.g. if your review and game entries where also related via a different Entries field).

Another detail to note is that whenever you're dealing with the source element (e.g. if this was the template for the game entry, and you wanted to list the related review entries), you rarely need relatedTo – you can just do this (of course, replace relatedReviews with the real handle for your Entries field):

{% set relatedReviews = entry.relatedReviews %}
{% for review in relatedReviews %}
    {{ review.title }}
{% endfor %}


How does craft deal with Plugin databases when updating plugin versions? Quick scenario.

I build a plugin with a database. Few months down the line I want to upgrade this plugin which will alter the plugin DB. If installing an update to a plugin how does craft deal with not over writing the existing database data? I know in EE you set up separate install and update functions but I can't find anything in the documentation in craft regarding this and the plugins I've pulled apart don't seem to include anything to deal with updates?

Any advice or pointers to some good documentation on this would be appreciated.

Cheers

Every time Craft notices that a plugin's version number has changed (I imagine quite near the start of every request,) it checks for any new Database Migrations in that plugin that might need running in order get the database schema caught up to the code. That link, and this one for database queries should be enough to get you started.


User defined order for categories I'd like to set a user defined order for a Categories field. For example, categories are:

Cat A
Cat B
Cat C

I'd like to give the ability for users to drag and drop the order, to say:

Cat B
Cat A
Cat C

What is the best way to handle this?

I ended up finding this code snipped, which worked for me:

https://gist.github.com/zackspear/7cdd656f9bb34e210676


SearchPlus plugin configuration How can you change from instant search and faceting to a search bar with auto-completion? SearchPlus comes with an excellent sample template but this is set to instant search, which means all entries in the index are displayed. I want to have a search-bar only and when typing the search query the relevant entries start to appear (auto-completion).

Also, if there is no excerpt field available in the indexed entries, would it be possible to create one, with Twig split?

{% set paragraphs = entry.body|split('
') %}
{% set firstParagraph = paragraphs|first ~ '
' %}

{{ firstParagraph|raw }}

See this tutorial by Algolia for autocomplete search: https://www.algolia.com/doc/guides/search/auto-complete/

You would use Search Plus only to keep your index in sync with your sections


Loading email templates in a Craft 3 plugin I've been struggling to make this work within a plugin. I have a html file in my templates folder called _email.html. I try to load it in my plugin but then I get an error. This is my code:

Craft::$app->mailer->compose('_email.html', ['body' => $emailBody])
            ->setFrom($fromMail)
            ->setTo($toMail)
            ->setSubject($subject)
            ->send();

The problem is that the Yii mailer is looking in the vendor folder instead of the templates folder.

This is the error I get:

The view file does not exist: /Applications/MAMP/htdocs/project/vendor/craftcms/cms/src/mail/_email

Even when I try going back to the templates folder it doesn't seem to work and I get the following error:

The view file does not exist: /Applications/MAMP/htdocs/project/vendor/craftcms/cms/src/mail/../../../../../../templates/_email

I found out that if I copy and paste the contents of the _email.html file and do the following it does work, but this obviously is a pretty bad workaround

->setHtmlBody("<!DOCTYPE html......")

Any advice?

Thanks!

I think you have to set the template mode to 'SITE', to let Craft know where to look for the template:

$view = \Craft::$app->getView();
if ($view->getTemplateMode() !== $view::TEMPLATE_MODE_SITE) {
    $view->setTemplateMode($view::TEMPLATE_MODE_SITE);
}

Craft::$app->mailer->compose('_email.html', ['body' => $emailBody])
    ->setFrom($fromMail)
    ->setTo($toMail)
    ->setSubject($subject)
    ->send();


Can't see any craft/app folder It looks like the craft/app folder is no longer in the Craft download.

I've been using v.3.0.9 from the site and through composer.

Or am I missing something here?

This is causing a bit of trouble with step 4 in the install process:

  Download the latest version of Craft from craftcms.com, and copy its craft/app/ folder into happylager/craft/.

I'm inferring from that last line that you're trying to install the Happy Lager demo.

However, that demo is currently only compatible with Craft 2.

The app folder was removed in Craft 3. And the demo has not yet been updated for Craft 3.

So if you really want to play with the Happy Lager demo, you'll need to download Craft 2. Or visit demo.craftcms.com, which will spin up a full copy of the demo for you.


Searching on whole title returns no results When a client site is searched by the whole title, the search results return zero.
If I search by a few words in the entry title then the entry is returned in the search results.
If i search with the whole title in quotes, I get the entry in the search results.
I am expecting the entry to be returned when searching on whole title.
So is this a bug to file or mismatched expectation?
Search query :
results?q=Help+for+seafarers+when+they+need+it+most

I don’t think it’s a bug, that’s what the docs describe, although I would tend to make the same assumption that you’ve made about how it should work.
Either way you can search for a contains, or an exact match at the same time:
.search(search_query "OR \"" ~ search_query ~ "\"")


Setting up Craft on Linode Using Ubuntu I'm setting up a Craft site on a Linode server has anyone had any experience with this? I'm struggling with which owner and user to set the var/www/html folder to with chown and what chmod settings to use on the craft folders. Currently Craft does not show the index page and can't find the admin folder which are all where they are supposed to be so it seems to be something to do with apache permissions. Just wondered if anyone could advise what these should be?

I assume you've seen https://www.linode.com/docs/websites/apache/apache-web-server-on-ubuntu-14-04?

Craft really isn't any different than any other PHP application in the way it needs to be setup to execute.  The only extra thing that other apps might not require (because most PHP apps don't auto-update) is that Craft needs to be able to recursively write to its craft/app folder in order for that to work.

There's a handy script here: https://github.com/nystudio107/craft-scripts that can help automate the necessary permissions for your box, but you'll need still need to know what user:group Apache is running as for it to set things up properly.


Can I use a nested uri for a single? I have a single. I want to set the uri to section/single. For example academy/sign-up. I have created a single and have a template file named sign-up.html in the right location (within academy folder). I get a 404 when requesting site.com/academy/sign-up. Removing academy from address works. Can I use the nested uri or do all singles need to sit at the top level?

Create a Single called Sign Up with a URI (section > settings) of academy/sign-up while keeping your current template academy/sign-up.html.


Search for matrix field in a global set I've set up a global set "attachmentGlobals" with a matrix field inside named "globalFiles". This matrix has only one block "files" which has a text field "fileId" and an Asset field "fileAsset".

I would like to retrieve a specific row searching for the "fileId" content.

I've triyed in those ways:

Test 1:

attachmentGlobals.globalFiles.fileId('sitelogo')

Return me an Error saying no method "fileId" is available

Test 2:

attachmentGlobals.globalFiles.find('fileId:sitelogo')

No error, but no results

Test 3:

attachmentGlobals.globalFiles.search('fileId:sitelogo')

No error, but no results

I've search Craft documentation and some examples on Stack Exchange, but nothing seems to help.

In the first place, is this possible? or were am I wrong?

Thank you in advance.

PS: I know this issue could be solved using only assets fields, but I would like to know if is possible to search for matrix fields by filed content.

As far as I know, (currently) the only way to filter matrix blocks is to use the type method to filter by block type or to limit the amount of returned matrix models with limit.

Here's what I'd do:

{% set searchString = 'sitelogo' %}

{# Search for potential matrix blocks #}
{% set foundBlocks = attachmentGlobals.globalFiles.type('files').search(searchString) %}

{# Loop through the result and output the right one #}
{% for foundBlock in foundBlocks %}

    {% if foundBlock.fileId == searchString %}
        <img src="{{ foundBlock.fileAsset.first.url }}" alt="{{ foundBlock.fileAsset.first.title }}">
    {% endif %}

{% endfor %}

You can't use search('fileId:sitelogo'), because that would filter for entries with  fileId:sitelogo and not entries with a matrix block fileId:sitelogo.


How can I filter by Matrix field I have a Matrix field and I want to be able to filter by it.

For example I want to get all entries that has matrixField.field1Type.value = {some value}.

How can I do that?

You can query Matrix blocks like you are used to with all other elements

{% set blocks = element.matrixFieldHandle.type('typeHandle').field('some value').all() %}

Keep in mind your field should be a valid field handle within your block type


Format date without translating text Is there a simple way to opt out of the translation that occurs when you format a date like this:

{{ expiry | date('D, d M Y H:i:s', 'GMT') }}

The problem is that I need this in english to create a valid date for my HTTP headers. But the site is in norwegian so days and months are translated, resulting in an invalid date.

Not currently - we should probably add a new 'translate' argument to that function which would let you opt out of it.

However Craft’s DateTime variables have a rfc1123() function which can be used instead of the Twig |date filter, and its output won’t get automatically translated.

For reference, RFC 1123 defines the date/time specification recommended by RFC 2616 (HTTP 1.1) (which is the same as the one defined by RFC 822, just with 4-digit years).

{{ expiry.rfc1123() }}


Has anyone been able to get auto-complete working with plugins + PHPStorm? It would make my day to be able to have PHPStorm recognize third-party services. Has anyone figured out how to get this working yet?

Absolutely, just add the app directory as a external library.

Double click on the 'external libraries'.
Add the interpreter
Include the path to the 'app' directory


How to call external lib in my plugin? I want to include Parse SDK in my plugin. I created a folder lib and put the SDK in it. and called like that in controller:

namespace Craft;
use Parse\ParseClient;
use Parse\ParseQuery;

    $APPID = 'xx';
    $MASTERKEY = 'xx';
    $RESTKEY = 'xxx';
    $PARSEURL = 'https://api.parse.com/1/';

    $list = new parseQuery('Dance');
    $results = $list->find();

And it says: Fatal error: Class 'Parse\ParseQuery' not found in /vagrant/craft/plugins/xx not found.

Here is the method we are including libraries in our plugin.

namespace Craft
require_once(CRAFT_PLUGINS_PATH.'parse/parsequery/xx.php');


Craft 3 plugin - how to update entry with field of Entries type Using PHP, I want to update a field of Entries type of an existing entry.

Fields of type Text and Number will update with the following code:

$entry = Entry::find()->id($entryId)->one();
$entry->textField = 20; // works
$entry->entriesField = Entry::find()->id($relatedEntryIds)->all(); // doesn't work
Craft::$app->elements->saveElement($entry);

I looked into the source code and it seems to be expecting a craft\elements\db\EntryQuery object but I can't get it to work.

Can anyone please help?

Ok this was easy.  Tried it at first but didn't work and was successful after another go.  All it needed was a array of Entry IDs.

Working code:

$entry = Entry::find()->id($entryId)->one();
$entry->textField = 20; // works
$entry->entriesField = [$relatedEntryId1, $relatedEntryId2]; // works
Craft::$app->elements->saveElement($entry);


What is the best to find a developer to create a Craft plugin? I have the Craft Commerce based webshop and need a developer to create plugin for Klarna Checkout (https://knowledge.klarna.com).

There are a couple of options, as far as I know:

Straight Up Craft community site
Craft Slack has a jobs channel
Work With Craft


Disabling the target="_blank" on admin site title link I'm looking to hook into this somehow to adjust the title home page link in the top left corner of the admin pages to stop opening in a new tab. Anyone have any good solutions for removing the target="_blank"?

Here's a sample of the code in question:

Site Name

You can use the handy Control Panel JS plugin and add some JS that targets the site-name class on the anchor and removes it.  jQuery's removeAttr should do the trick.


Categories Structure for Landing Pages I'm using a category group and routes to serve up entries on landing pages with a URL structure like this.

www.domain.com/properties/retail/freestanding

My code works, but I am wondering if there's a better way to write it (dry it up).

{% set allProperties = craft.entries.section('propertiesSection') %}
{% set cat = craft.request.getSegment(2) %}
{% set subcat = craft.request.lastSegment %}

{% set retail = craft.categories.group('properties').craft.categories.slug('retail-properties') %}

{% if subcat == "freestanding" %}
    {% set entries = allProperties.relatedTo([ {targetElement: freestanding } ]) %}
{% endif %}

{% if subcat == "storefront" %}
    {% set entries = allProperties.relatedTo([ {targetElement: storefront } ]) %}
{% endif %}

.... and so on

{% if entries|length %}
    {{ entry.title }}
{% endif %}

If you category is related to your entry there is no need to fetch the category via url segment. This method is slower and will need more resources since you'll do the work twice for no reason.

entry.relationFieldHandle

will contain an ElementCriteriaModel with a ready to use query to fetch the related elements. So entry.relationFieldHandle.first() will return the category.

If you want to get all entries, that are related to the category of your current entry you should do

{% set categoryIds = entry.fieldHandle.ids() %}
{% set relatedEntries = craft.entries.relatedTo(categoryIds).find() %}

Your code could be

{% set category = entry.fieldHandle.first() %}
{% set relatedEntries = craft.entries.section('propertiesSection').relatedTo(category).find() %}

That's basically it. Note: you don't need to fetch the category to get the related entries, you only need the id. That's why I used .ids() in the first example instead of .first() or .find()


Inserting Multiple Block Types in one div row I have a matrix with a block type call pageRelatedContent. A user can add multiple block to their entry. I am trying to put all the pageRelatedContent blocks in one div row. For this example, I have three pageRelatedContent blocks in this entry. My code is generating three separate rows. Its a coding thing that I am missing. Can someone please assist.

Here is the rendered HTML:

Here is the desired output:

Here is my code. I can see that it is creating a row for every block, but I can't seem to figure out how to insert all the block in one row.

    {% case 'pageRelatedContent' %}
{% set relatedContentBlocks = entry.memberCommunicationsPageContent.type('pageRelatedContent') %}
{% if entry.memberCommunicationsPageContent.type('pageRelatedContent')|length == 1 %}
    {% set colSize = 12 %}
{% elseif entry.memberCommunicationsPageContent.type('pageRelatedContent')|length == 2 %}
    {% set colSize = 6 %}
{% elseif entry.memberCommunicationsPageContent.type('pageRelatedContent')|length == 3 %}
    {% set colSize = 4 %}
{% endif %}

                {% set relatedBlockInfo = relatedContentBlocks|batch(colSize) %}
                {% for blocks in relatedBlockInfo %}

                             {{ block.relatedContentTitle }}

                                        {% for row in block.relatedLinkInformation %}

{{ row.linkTitle }}

                                        {% endfor %}

                {% endfor %}

Here is the matrix information:

It wasn't a CSS issue. Lack of twig knowledge. Here is the final fix.

    {% case 'pageRelatedContent' %}
{% set relatedContentBlocks = entry.memberCommunicationsPageContent.type('pageRelatedContent') %}
{% if entry.memberCommunicationsPageContent.type('pageRelatedContent')|length == 1 %}
    {% set colSize = 12 %}
{% elseif entry.memberCommunicationsPageContent.type('pageRelatedContent')|length == 2 %}
    {% set colSize = 6 %}
{% elseif entry.memberCommunicationsPageContent.type('pageRelatedContent')|length == 3 %}
    {% set colSize = 4 %}
{% endif %}
    {% set isFirst = not block.getPrev() or block.getPrev().type != 'pageRelatedContent' %}
        {% if isFirst %}

        {% endif %}
        {% set relatedBlockInfo = relatedContentBlocks|batch(colSize) %}
        {% for blocks in relatedBlockInfo %}

                     {{ block.relatedContentTitle }}

                                {% for row in block.relatedLinkInformation %}

{{ row.linkTitle }}

                                {% endfor %}

        {% endfor %}
    {% set isLast = not block.getNext() or block.getNext().type !='pageRelatedContent' %}
        {% if isLast %}

        {% endif %}


Iterate through all entries and count a specific value I am having entries in a Craft channel-section. Each entry has the field "type" with one category filled. I need to iterate through the entries and count the amount of each category.

Example:

Entry 1, Category: One
Entry 2, Category: One
Entry 3, Category: Two

Produces something like

One: 2, Two: 1

So I know which category is used how often. In any language I would use a key/value set and just increment the amount each time I find the specific category, but that seems to be impossible with Twig in Craft.

How can I achieve that?

Before we proceed, let me say that whilst the following will work, I personally think this is a poor use of Twig.

It's far better to collate this information in a simple plugin, rather than jumping through such hoops in your templates.

Caveats dispensed with, here you go:

{% set criteria = {
    section: 'exampleSection',
    limit: 20,
    with: ['categoryFieldHandle']
} %}

{% set categories = {} %}
{% set entries = craft.entries(criteria).find() %}

{% for entry in entries %}
    {% set entryCategories = entry.categoryFieldHandle %}
    {% if entryCategories|length %}
        {% for entryCategory in entryCategories %}
            {% set categorySlug = entryCategory.slug %}

            {% if categories[categorySlug] is not defined %}
                {% set categories = categories|merge({
                    (categorySlug): {
                        count: 0,
                        category: entryCategory
                    }
                }) %}
            {% endif %}

            {% set categoryCount = attribute(categories, categorySlug)['count'] + 1 %}

            {% set categories = categories|merge({
                (categorySlug): {
                    count: categoryCount,
                    category: entryCategory
                }
            }) %}
        {% endfor %}
    {% endif %}
{% endfor %}

{% if categories|length %}

Category Counts

        {% for categoryKey, categoryInfo in categories %}

{{ categoryInfo.category.title }}: {{ categoryInfo.count }}

        {% endfor %}

{% endif %}

Note that we're eager loading the categories. Otherwise, we'll end up with N+1 queries.


Get all fields within Matrix for position? Just working with a Matrix field to create a flexible, 2 column layout. The user can choose to add either an Image or Rich Text field, and position them accordingly with the Position Select field.

To illustrate, one layout might be:

| image | image |
|       |       |
| text  | text  |

But another might be:

| image | text  |
|       |       |
| image | text  |

Now my solution is to first loop through the Matrix field for each possible position option and group fields depending on their position into arrays. ie: leftContent[], rightContent[], etc.

Printing them out is then simple:

    {% for row in leftContent %}
        {% if row.type == 'image' %}

        {% else %}
            {{ row.text }}
        {% endif %}
    {% endfor %}

It would certainly make things easier if you could grab fields for x position? I'm aware this is more of a HTML layout issue and should really be left to the template creator to figure out, but just wanted to see if people had come across this.

Hope that makes sense :)

If I'm understanding what you've asked correctly (and there's every chance I'm not – it's been a long day), I've got something similar on one of my sites and I'm using the following code:

{% for faq in entry.faq if faq.column == 'Left' %}

{{ faq.question }}

{{ faq.answer }}

{% endfor %}

then:

{% for faq in entry.faq if faq.column == 'Right' %}

{{ faq.question }}

{{ faq.answer }}

{% endfor %}

In this case 'faq' is the Matrix field and 'faq.column' is the Position Select field.

There are neater ways to do this to avoid the repeated code, but you get the idea.


Show all tags related to a category? Is it possible to show all tags that are related to a category? I can't find anything on it.

Thanks.

Edit:

What I am looking for is this:

I know a category slug or name. I want to get all tags associated with entries in that category.

I can't seem to get this to work using the relatedTo param.

You can use the relatedTo param on craft.tags like you can with any Element inside Craft.

All Elements inside Craft can be related to one another. There is a .relatedTo parameter available on all of the query elements like craft.entries and craft.tags.

You will need to pass a category object into this relatedTo parameter. I have included the group param below but this can be omitted if you want to query all of your tags.

{% set tags = craft.tags.group( 'groupName' ).relatedTo( category ) %}

More info on using Relations in Craft: https://craftcms.com/docs/relations

UPDATE

The relatedTo param takes one of the following:

An AssetFileModel, CategoryModel, EntryModel, UserModel, or TagModel
object
An element’s ID
An array of element objects and/or IDs

To get a CategoryModel using a slug inside your template you can use:

{% set category = craft.categories.slug( 'theslug' ).first() %}

This will set category to a CategoryModel which you can then use inside the .relatedTo param in the above example.

UPDATE 2

If you've set category to have their own URL's then category inside the template you've set to use is a CategoryModel.

You then set entries to all entries related to the category. Finally, use these entries to get all related tags.

{% set entries = craft.entries.relatedTo( category ).find() %}
{% set tags = craft.tags.relatedTo( entries ).find() %}


Add custom fields to variant snapshot How would I add more information (custom fields) to a variant's snapshot?

The custom field I'm adding will change over time, but I need it to stay consistent on invoices etc.

Yes using the onPopulateLineItem event. Something like this should work:

craft()->on('commerce_lineItems.onPopulateLineItem', function($event){

    $purchasable = $event->params['purchasable'];
    $lineItem = $event->params['lineItem'];

    $lineItem->options = array_merge(
      $lineItem->options,
      ['customFieldLabel'=>$purchasable->customField]
    );

});


Categories Related To Matrix Fields Please help me build my sandwich locator maker :)

I have 3 categories, breads, meats, condiments
I have a Section called subShops with a matrix field.
My matrix field is called sandwichBuilder, fields: breads, meats, condiments
This matrix field is my entry I use for building the sandwiches that the suShops offer.

I want to keep my Categories to make it easy for structure and searching.

How can I build my query so that I can find all entries using a category of bread (over 200 sub categories for bread)?  I want the ability to only show those subShops that carry a certain breads based on URL segments (http://example.com/breads/spelt).

Basically, this above url example would list all the subShops that carry spelt bread, so it would display each group including - subShop, bread and typical meats that go best with spelt.

I have tried various ways and many hours trying to figure it out but with unusual results.  My code below is my baseline, but need some help from anyone willing to offer examples.  This is a pet project and I do plan on sharing the code when complete.

{% set entries = craft.entries.relatedTo(sanwiches).all() %}

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

{% for row in entry.matrixA %}
 {% for option in row.matrixB %}
    {{ option }}
    {% endfor %}
 {% endfor %}
{% endfor %}

You have to insert your matrix field into the rated to param like here

{% set entries = craft.entries.section('subShops').relatedTo({
    targetElement: sandwich,
    field: 'sandwichBuilder.breads'
}) %}


Twig combined conditionals to set variable I am trying to check for the existence of a text field and an asset field and set an icon variable depending on the result.
I don't seem to be having much luck with defined, length and empty combinations.

Here's my code so far:

{% if (story.videoStoryUrl is defined) and (not story.storyImage | length) %}
    {% set icon = "video" %}
{% elseif (story.videoStoryUrl is empty) and (not story.storyImage | length) %}
    {% set icon = "text" %}
{% else %}
    {% set icon = "image" %}
{% endif %}

Any help appreciated :)

It's probably better if you set variables to reference, so your if statements make more sense.

{% set asset = story.storyImage.first() %}
{% set videoUrl = story.videoStoryUrl %}
{% set icon = "text" %}

{% if asset | length %}
    {% if videoUrl is empty %}
        {% set icon = "video" %}
     {% else %}
        {% set icon = "image" %}
    {% endif %}
{% endif %}

{{ icon }}


Saving asset title in frontend form I have a frontend form to save an entry which includes a file upload input field:

<input type="file" name="fields[newsFile]">

The upload works fine, but is it also possible to set the title of the asset similar to the backend? Unfortunately, this doesn't work:

<input type="text" name="fields[newsFile][title]" value="Asset Name">

Sorry, but the answer is no; assets will initially just get titles based on their filenames until someone goes into the Control Panel and customizes them.


Merge a multidimensional array I am creating a calendar for displaying films and their screening times.

I already have a quite convoluted mechanism of retrieving data from the "films" channel, where I have a supertable for "filmScreenings", which contain values for "theater" for name of the theater and "starts" which is a datetime for when the screening starts.

I am trying to create a multidimensional array for storing the films and screenings per theater. This is what I would like to accomplish:

screeningsForTheater  = {
  "Theater 1" : [
    { "film" : "Movie 1", "starts" : "09:00" },
    { "film" : "Movie 2", "starts" : "11:30" },
    { "film" : "Movie 3", "starts" : "13:30" }
  ],
  "Theater 2" : [
    { "film" : "Movie 4", "starts" : "09:30" },
    { "film" : "Movie 5", "starts" : "11:00" },
    { "film" : "Movie 6", "starts" : "13:00" },
    { "film" : "Movie 7", "starts" : "21:00" }
  ]
}

From here on I would be able to loop screenings displaying films and their screenings in the correct column:

Theater 1         Theater 2
Movie 1, 09:00    Movie 4, 09:30
Movie 2, 11:30    Movie 5, 11:30
Movie 3, 13:30    Movie 6, 13:00
                  Movie 7, 21:00

Here is the twig-code for trying to create this kind of array:

{% set screeningsForTheater = {} %}

{% for film in films %}
  {% for screening in film.screenings %}

  {% set starts = screening.starts %}
  {% set ends = "calc starts + length in minutes" %}

  {% set screeningsForTheater = screeningsForTheater | merge(
    {
      (screening.theater.label) : [
        { "film" : film.title, "url" : film.url, "starts" : starts, "ends" : ends, "length" : film.length }
      ]
    }
  ) %}

  {% endfor %}
{% endfor %}

What happens is that the values for keys "Theater 1" and "Theater 2" are being replaced as the loop progresses. In the end I have an array that looks like this:

screeningsForTheater = {
  "Theater 1" : [{ "film" : "Movie 3" ... }],
  "Theater 2" : [{ "film" : "Movie 7" ... }]
};

I cant quite understand how to correctly push screenings into screeningsForTheater[theater] - any help you could offer?

Running Craft 2.6 if it has anything to do with Twig syntax.

Ok, I managed to figure it out following directions on this page:
Creating dynamic array and set keys

{% set filmData = { "film" : film.title, "url" : film.url, "starts" : starts, "ends" : ends, "length" : film.length } %}

{% if not attribute(screeningsForTheater, screening.theater.label) is defined %}

    {% set screeningsForTheater = screeningsForTheater | merge({ (screening.theater.label) : [filmData] }) %}

{% else %}

    {% set otherFilms = attribute(screeningsForTheater, screening.theater.label) %}
    {% set otherFilms = otherFilms | merge([filmData]) %}
    {% set screeningsForTheater = screeningsForTheater|merge({ (screening.theater.label) : otherFilms }) %}

{% endif %}

EDIT

However I realized I had to create another level to the array by including the date of the screening. This was the format needed:

screenings = {
  "22.3.2018" : {
    "Theater 1" : {
      "Movie 1" : { ... },
      "Movie 2" : { ... }
    },
    "Theater 2" : {
      "Movie 3" : { ... },
      "Movie 4" : { ... }
    }
  },
  "23.3.2018" : {
    "Theater 1" : {
      "Movie 5" : { ... },
      "Movie 6" : { ... }
    },
    "Theater 2" : {
      "Movie 7" : { ... },
      "Movie 8" : { ... }
    }
  }
}

I spent some time trying to create this kind of array using twig, but couldn't get the merge to work correctly.

I then created a plugin and a templateVariable to do the search and array stuff using PHP, which was a lot more comfortable, and got this working in no time.


299US$ Upgrade for Pro is for 1 site or any domain with my License I'm not sure 299US$ for Upgrading to Pro License is for 1 domain on upgrading or any domain with my account (Craft CMS Member).

It is per domain (excluding sub-domains), i.e. for one domain / website.

domain.com and subdomain.domain.com can both run off of the same license.

More info on how that is all enforced.


Plugin Store: Page not found I'm having a strange problem on a recent craft install. The plugin store doesn't load, and only reports "Page not found".

I've tried another craft install on the same system, and it's working fine.
I tried replacing all core craft files with freshly downloaded 3.0.2 files.
I've cleared caches, ran updates, loosened all permissions to 777 and everything in between.
I've tried two different browsers with cache cleared.
I have only 2 plugins installed: Redactor and Position Fieldtype — but I have those on another install as well and that install is fine.
The logs in /storage/logs don't show any errors. I tail them, and nothing is reported.

Aside from the plugin page, all other craft systems work. Even the backups can run and save locally.

Is there anything else I can try to either diagnose or solve? Feel like I've hit a wall. Any advice is appreciated.

Solved. There is a bug. When the setting:

omitScriptNameInUrls' => false,

is set to "false" in

/config/general.php

The Plugin Store doesn't load. Switching that setting to true will fix it.


Craft 3: Error "variable now does not exist" I upgraded a Craft 2 project to Craft 3 and am working on updating some template quirks. One I am having trouble with involves the following element query:

{% set scriptsAboutToExpire = craft.entries({
    section: 'scripts',
    order: 'expirationDate asc',
    expirationDate: [ 'and', '>=' ~ now, '<=' ~ now|date_modify('+2 weeks') ]
}) %}

This worked great in Craft 2. It grabs all script entries whose expirationDate field is two weeks away from today's date.

However now after upgrading to Craft 3 I am getting the following error when viewing that template:

PHP Recoverable Error – yii\base\ErrorException
Object of class DateTime could not be converted to string

with a highlight on this line:

(isset($context["now"]) || array_key_exists("now", $context) ? $context["now"] : (function () { throw new Twig_Error_Runtime('Variable "now" does not exist.', 10, $this->source); })())), 2 => ("<=" . twig_date_modify_filter($this->env, (isset($context["now"]) || array_key_exists("now", $context) ? $context["now"] : (function () { throw new Twig_Error_Runtime('Variable "now" does not exist.', 10, $this->source); })()), "+2 weeks"))))), "method");

I tried updating all .localeDate() filters to |date('short') but that had no effect.

You need to convert the DateTime object via Filter:
 now|date('U')

or via function
now.format('U')

This will format the date as a UNIX timestamp which is sufficient for querying. MySQL datetime format will work too: date('Y-m-d H:i:s')
More info can be found in the upgrade documentation.


Is it possible to get the md5 hash of Craft's latest version from the download server? It is possible to programmatically download the latest version of craft. But is it also possible to get this file's md5 sum directly from the server?

I'm thinking about something like this:

http://buildwithcraft.com/latest.hash

I am asking this because I'm currently writing a Salt formula to install Craft. I intend to use salt.states.files.managed, which is capable of downloading a file only if it has a different md5 sum than an already downloaded version of the file.

Currently not, but that's not a bad idea and probably worth adding to https://feedback.buildwithcraft.com.

During an auto-update, the file name of the patch file that is downloaded happens to be the MD5 sum of the file so the Craft client can verify the integrity of the downloaded file, but there isn't a mechanism like that in place currently for full Craft downloads.


How do I proceed when I want to show another language when the actual language is deactivated? I have two languages (German and French).
In my sections I have German enabled as default language. French is off by default.

My Problem is:
I always want to show content, even if the other language is disabled and, when an entry is not translated yet, show a note like "Entry not translated yet."

I know about localeEnabled and status and I can query the following way:

{% set entries = craft.entries.section('referenzen').localeEnabled(false).status(null).find() %}

That outputs all of the entries.
But I am running into problems with the "_entry" template.

And I don't really know how to differentiate between entries that have their status turned off vs. entries that only have a language turned off.

Does anybody have a solution to this problem?

Cheers
Stefan

So thanks to Brad I found this solution:

{# Get all entries regardless if the locale is enabled or not #}
{% set allEntries = craft.entries.section('yourSection').status(null).localeEnabled(false).find() %}

{# Set the other locale (could be done differently, but since I have only two, I chose the easy way) #}
{% if craft.locale == 'de' %}{% set otherLocale = 'fr' %}{% else %}{% set otherLocale = 'de' %}{% endif %}

{# Get all entries that are not disabled regardless if the locale is enabled or not #}
{% for entry in allEntries if entry.enabled == 1 %}

    {# if the locale is turned off, search for the entry in the other language #}
    {% if entry.status == 'disabled' and entry.localeEnabled == 0 %}

        {# Get the same entry in the other locale #}
        {% set otherEntry = craft.entries.id(entry.id).locale(otherLocale).first() %}

{{ otherEntry.title }} ({{ otherLocale|upper }})

    {% else %}

{{ entry.title }}

    {% endif %}

{# else (for the loop) all the entries are disabled #}
{% else %}

No results

{% endfor %}

It works great for my case.


What's the best way to clear cached JSON responses from a third-party API? I'm building a plugin to browse store orders via a third-party API. I make various requests to URLs that can include query parameters:

/customers
/orders/e8b48e72-9c7f-4d6f-91aa-2f7238bdf936
/orders?offset=0&limit=250&from=2014-05-26T22%3A58%3A38%2B00%3A00&to=2014-06-26T22%3A58%3A38%2B00%3A00

I've just started using Guzzle and more importantly craft()->fileCache to keep results around for a few minutes and speed up browsing. I use the query URI as the key for the cache:

 craft()->fileCache->set($query, $response->getBody(true), 600); // store result for 10 minutes

A web hook gets hit with every new order that comes in, making it an ideal time to clear out these caches I've set—but I have no idea how.

Is there any way I can tag this plugin's caches or somehow clear out only those I've made, rather than get overzealous with craft()->fileCache->flushValues()?

You can delete a cache as follows:

craft()->fileCache->delete($key);

So instead of caching individual keys, you could perhaps cache an array of keys and delete the entire array when you want to clear out your keys.


Curating the homepage Learning Craft currently. Wondering if there's any plugin that simplifies the curation of the home page by allowing pinning a post, highlighting a post, reordering a post etc (non chronologically)

Here's a reference of a equivalent Wordpress plugin:
https://github.com/10up/curator

THanks

You could create a matrix content field for the homepage with a child entry selection field. You can add as many matrix blocks as you'd like, and select the entries you would like within them.

You can read more about Matrix fields here.

Likewise you can checkout entry field types here.

So your code for index.twig might look like:

{% for block in entry.calloutBlocks %}

    {{block.title}}
    {{block.body}}
    Read more

{% endfor %}


Output season name from entry date I'd like to get an output of Spring 2015 from a post entry that was written in March. Here is a JavaScript solution

http://jsfiddle.net/RtC58/3/

But I'm hoping I can do something in the template instead. Thanks!

{% switch entry.postDate|date('M') %}

    {% case 'Dec' or 'Jan' or 'Feb' %}
        {% set season = 'Winter' %}

    {% case 'Mar' or 'Apr' or 'May' %}
        {% set season = 'Spring' %}

    {% case 'Jun' or 'Jul' or 'Aug' %}
        {% set season = 'Summer' %}

    {% case 'Sep' or 'Oct' or 'Nov' %}
        {% set season = 'Fall' %}

{% endswitch %}

<p>{{ season }} {{ entry.postDate|date('Y') }}</p>


If I try to preview a previous revision of an entry, I get "an unknown error occurred" Craft 3.3.15

Previous version of the entry was saved 1 minute ago, so no changes in settings between the two entries.

Any ideas on how to debug this?

Update - here's the error, which looks very much like what @mtnorthrop is getting:

2019-11-20 10:41:44 [-][1][-][error][TypeError] TypeError: Argument 1 passed to craft\helpers\ElementHelper::isTempSlug() must be of the type string, null given, called in /Users/andrei/Desktop/dev/hl/mailbuilder/vendor/craftcms/cms/src/controllers/EntryRevisionsController.php on line 473 and defined in /Users/andrei/Desktop/dev/hl/mailbuilder/vendor/craftcms/cms/src/helpers/ElementHelper.php:47

This bug was due to an issue with the Stringify library and was fixed in Craft 3.3.16.1, as stated by Brad Bell in his comment on the original question.

Upgrading to Craft 3.3.16.1 fixes this issue.

(I'm posting this as an answer in case anybody else runs into the same issue.)


If multiple entry types? Is it possible to do the following?

{% if entry.type == 'overview' %}

    {{ entry.title }}

{% elseif entry.type == ['availability', 'specifications', 'sitemap', 'location'] %}

    {{ entry.title }}

{% else %}

    {{ entry.title }}

{% endif %}

At the minute it is not returning anything inside the elseif, can anyone spot anything wrong with the logic or is there an alternative method?

You were so close! Instead of asking whether entry.type is equal to the array (which it isn't), you need to find out whether the value of entry.type matches one of the array items.

Here is an updated snippet that should work for you:

{% if entry.type == 'overview' %}
    {{ entry.title }}
{% elseif entry.type.handle in ['availability', 'specifications', 'sitemap', 'location'] %}
    {{ entry.title }}
{% else %}
    {{ entry.title }}
{% endif %}

EDIT:

It's important to recognize that entry.type is actually an object. When checking a value using in, the object's __toString method will not be invoked. Therefore you'll need explicitly specify entry.type.handle when testing whether the type is in an array.


How can I filter Craft Commerce products by the current price Building on from this question How can I filter Craft Commerce products by price

I have a price filter in the store

Using this code works fine for the normal price

{% set queryParams = {
        relatedTo: category,
        defaultPrice: [
            'and',
            '>= ' ~ 0,
            '<= ' ~ 90,
        ]
    }
%}

but defaultPrice does not consider sale prices.

So if a product is normally $99 but it is reduced to $89, it won't be returned

I would have expected defaultPrice to store the current price being charged. So the sale price if it was on sale.

Is it possible to filter by price and include sale prices?

I've spent hours now on something I thought would be simple. It seems the only way to get this information is to get the products and loop through them. Checking for sale prices.

Do I have to create a plugin to make a usable price filter?

https://craftcommerce.com/docs/variant-model#saleprice

The comment on the documentation leads me to believe you can just use salePrice for your filtering as it will be equal to the defaultPrice if there is no sale.

So:

{% set queryParams = {
        relatedTo: category,
        salePrice: [
            'and',
            '>= ' ~ 0,
            '<= ' ~ 90,
        ]
    }
%}


Apply 'random' to an array How do I output one random line of an array?

{% set img = [
  { bildli: 'http://i.giphy.com/I0xDz0htjsiME.gif' },
  { bildli: 'https://i.giphy.com/fA3JALhIi5YVa.gif' }
 ] %}
 {% for item in img %}
   <img src="{{ item.bildli }}" alt="">
 {% endfor %}

I tried {% for item in img.limit(1).order('RAND()') %} like you would on a normal entries.section but that doesn't work on array.

I also tried: {% for item in random(img) %} as statet in the twig doc but that doesn't work eyther. What's the catch here?

Take a look at the shuffle function provided by Craft: https://craftcms.com/docs/templating/functions#shuffle

This will shuffle the complete array and output them all in the new order:

{% set img = [
    { bildli: 'http://i.giphy.com/I0xDz0htjsiME.gif' },
    { bildli: 'https://i.giphy.com/fA3JALhIi5YVa.gif' }
] %}

{% set shuffledImages = shuffle(img) %}

{% for item in shuffledImages %}

{% endfor %}

If you want to just output one random image, then this should work:

{% set img = [
    { bildli: 'http://i.giphy.com/I0xDz0htjsiME.gif' },
    { bildli: 'https://i.giphy.com/fA3JALhIi5YVa.gif' }
] %}

{% set randomImage = shuffle(img) | first %}


Find entries that have a category selected from a category field within a matrix block I've got a Section that uses a Matrix field, that has a block, that has a categories field in it.

I want to find all entries using this Matrix field, who has a categories field and has a certain category selected.

I'm looking at the Relations documentation and trying the following code, but perhaps i'm barking up the wrong tree here?

{% set cat = craft.categories.slug('print') %}
{% set entries = craft.entries.section('projectsEntries').relatedTo({
sourceElement: cat,
field: 'contentBuilder.relatedCategories.content'
}) %}

{% for entry in entries %}

{{ entry.title }}

{% endfor %}

Try using targetElement: cat instead of sourceElement – in my experience the entries are considered the source of the relation in cases like these, not the categories.

Edit: Also, the field parameter of the relatedTo method shouldn't include the Matrix field's block type, only the actual category field – i.e. contentBuilder.content, not contentBuilder.relatedCategories.content.


create a fixed height and width for profile photos Is it possible to do anything with Craft's getPhotoUrl() function to allow images to be processed in a similar way like assets?

For example for our profile photos I'd like them to be returned 45x45 cropped from centre.

Currently if a user were to upload a landscape photo they would see something like 45x25 because the height isn't being maintained.

Thoughts?

Kind of.  They currently aren't technically true "Assets" like in the rest of Craft.

The most you can do is pass in a size to the method getPhotoUrl(45) and you'll get a 45 x 45 square result back.  I believe it will crop from the center only.

We have plans for Craft 3 so they'll be treated like 1st class Assets and you'll be able to perform transforms on them like any other Asset.


Craft 3 404 and 503 pages in devMode Is there any way to get Craft 3 to display 404.html and 503.html for the 404 and 503 pages while in devMode, as it did in Craft 2, rather than returning the entire Yii 2 error stack?

Sometimes, we have to bring a site temporarily offline (by way of toggle in the general settings tab) to add features, and we have to put it into dev mode for debug. We want the site to show the branded 503 page to the public instead of the stack page.

Just posting this here since I saw an official answer in Github:

  This changed in Beta 7:

  UserException reports are now styled like other exceptions when Dev
  Mode is enabled, with the full stack trace shown.

  You can see your 404 template by requesting it directly, e.g. http://mysite.dev/404

https://github.com/craftcms/cms/issues/1613#issuecomment-293366095


404 error page not loading I found this question "404 Page Not Showing" asked 3 years ago that the person who asked figured it out but didn't really expand on how they did.

I have basically the same issue, craft doesn't load the 404 error ever, it simply loads the template with nothing.
https://footwearoutfitters.net/123

I haven't edited any .htaccess files

Routes is left unmodified, both in the CP and the file itself.

I'm wondering if I setup my entries incorrectly for the URI, anyone have ideas or think of somewhere else I could give info on to help this along?

Here is my .htaccess folder in the public

<IfModule mod_rewrite.c>
  RewriteEngine On

  # Send would-be 404 requests to Craft
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
  RewriteRule (.+) index.php?p=$1 [QSA,L]
</IfModule>

So my issue was very simple to solve once I paid better attention. The 404 was loading perfectly fine the whole time, my problem was that in my 404 file I had it as {% block content %} and not {% block main %} as I had specified in my layout.


Custom Validation Message for numeric I want to Number validation for my site, but not able to show custom validation message to user.

       'CVV' => [
            'label'    =>  'CVV Number',
            'type' => 'numerical',
            'numberPattern'=> '^[0-9]{3,3}$',
            'min'   =>  100,
            'minLength'   =>  3,
            'max'   =>  999,
            'maxLength'   =>  3,
            'required' => true,
            'integerOnly'   =>  true,
            'tooSmall'  =>  'CVV Number is too small (minimum is 3 characters).',
            'message'  =>  'CVV Number is too small (minimum is 3 characters).',
            'tooShort'  =>  'CVV Number is too small (minimum is 3 characters).',
            'tooBig'  =>    'CVV Number is too long (maximum is 3 characters).',
            'tooLong'  =>    'CVV Number is too long (maximum is 3 characters).',
        ],

I tried to set

AttributeType::Number

Also. But it didn't work.
The issue:
in the case of numbers like less than 3 characters, I am getting error message:

CVV Number is too small (minimum is 100).

Please Can anyone help me to get this expected message.
Thank You.

Removed above code and added the custom validation function for CVV Validation

public function validateCVV($attribute) {
    $value = $this->$attribute;
    if(!preg_match('/^[0-9]{3}$/', $value)) {
        $message = Craft::t("Oops!  Try again with a valid CVV security code on the back of your card.");
        $this->addError($attribute, $message);
    }
}

$rules[] = ['CVC', 'validateCVV'];

Thank You.


How to change the Slug in case of copied entries? I have a channel, where entries do NOT have their own URLs. But a slug is created automatically every time I save an entry. And I have auto-generated titles.

Often I save an existing entry as a new entry and just change something which changes then my auto-generated titles also. But the slug does not change (only a number is added).

Now my problem: The search function also searches the slug what then results in wrong search results.

My question: The only solution I've found is to manually delete the existing slug and to save the entry again. Is the a better solution for my problem?

Thank you very much for your help!

Seems like a good case for a simple plugin that listened to the onBeforeSaveEntry event.

That plugin could verify the entry is in the section you're looking for, compare the existing slug against any saved in the database and do whatever you want to do from there (set it null, etc.).


Contact Form Extensions - Checkbox Templating Cannot for the life of me get checkbox values to display in a HTML email template using the Contact Form extensions plugin.

Form snippet:

<input type="hidden" name="message[type]" value="">

<input type="checkbox" class="styled-checkbox" name="message[type][]" id="New" value="New">
New

<input type="checkbox" class="styled-checkbox" name="message[type][]" id="Used" value="Used">
Used

And the email template snippet:

{% if submission.message['type'] %}

Type of Quote: {{ submission.message['type'] }}

{% endif %}

Does anyone have a clue about this? I have tried many variations, the above is just one of them. Pulling my hair out ;)

TIA!

You're pretty close. In your input you have name="message[type][]". The little [] at the end there means means the data will be stored in an array, something like:

submission: {
  message: {
    type: ['New', 'Used']
  }
}

You have two options here:

Option one

You can change your inputs to be name="message[type]" instead of [type][]. This should result in a data structure more like you're expecting

submission: {
  message: {
    type: 'New'
  }
}

Then your conditional check can be kind of like you have it, but this won't allow multiple values (not sure if you want those or not).

Option Two

Update your conditional check and output to properly output the array values. This would mean something more like:

{% for type in submission.message.type %}
  <p style="font-size: 16px; line-height: 1.625; color: #51545E; margin: .4em 0 1.1875em;">
    Type of Quote: {{ submission.message.type }}
  </p>
{% endfor %}


Javascript event on save for custom field I have implemented a custom field type.

Is there any way to register a javascript event handler that is called before my custom field is saved?

Attach a submit event to the #entry-form element:

$('#entry-form').submit(function(e) {
    // code run on submit here
});


Multiple sites sharing global templates Our university is made up of many small sites.  I'd like to use craft for this.  Love the auto update feature.  I want each site to share template styles (ie. staff directories, document listings, etc.) but I want to be able to update this global library of templates as time goes on so all sites have access to the latest options.  Also being able to make a change to a global navigation and footer and have all sites updated at the same time would be key.

Does anyone have any suggestions on how to achieve this?

Global templates are absolutely possible by taking advantage of the Twig {% extends %} tag. You can read more about template inheritance in Twig's documentation.

If you set up multiple sections, you can assign certain users edit privileges to their appropriate sections.

You can set up your navs and footers as Globals (or use a plugin), you can set editing privileges just to admins. Simply create a header and footer partial template and include them in a main template file that your other templates extend.


what does {% set order = 'pin desc, postDate desc' %} do? I am new to using twig and I do not understand how this line of code works. If you could explain that would be wonderful! thanks:)

Craft uses the the template engine twig and there is a set tag that is the same as it's php equivalent for $order = 'pin...'

So you just set/declare a variable - in this case you set the string.


No input file specified - [proxy_fcgi:error] Got error 'Unable to open primary script: [PATH]/html/index.php (No such file or directory)\n' I have a peculiar situation that is only happening on the root domain and NOT subdomains.

For example, CraftCMS (2.6.3019) running on Apache with php-fpm works fine on dev.some-domain.tld and test.some-domain.tld, but for www.some-domain.tld it fails with:

In browser:

  No input file specified

In cPanel Apache log (/usr/local/apache/error_log):

  [Fri Aug 03 13:59:12.42352 2018] [proxy_fcgi:error] [pid 31552:tid 132443556343644] [client xxx.xxx.xxx.xxx:55292] AH01071: Got error 'Unable to open primary script: /home/USERNAME/public_html/production/current/html/index.php (No such file or directory)\n'

For identical installations for other subdomains, everything loads up and works great.  There is no difference in .htaccess or otherwise.

The only differential that we can figure must be something with how Apache's handling the root document location or permissions for the root domain... but we're not seeing anything.

For good measure, here's the .htaccess contents (that are identical on the working subdomains and this failing root domain):

<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresDefault "access plus 1 year"
</IfModule>

<IfModule mod_php5.c>
    php_flag zlib.output_compression on
</IfModule>

<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript
    BrowserMatch ^Mozilla/4 gzip-only-text/html
    BrowserMatch ^Mozilla/4\.0[678] no-gzip
    BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
    SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary
    Header append Vary User-Agent env=!dont-vary
</IfModule>

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
    RewriteRule (.+) index.php?p=$1 [QSA,L]
    RewriteCond %{HTTP_HOST} !^www\. [NC]
    RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
    RewriteCond %{HTTPS} !=on
    RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]
</IfModule>

I thought that perhaps it was the cgi.fix_pathinfo=1 setting for the php.ini, but that also didn't resolve this.

cPanel support is saying it is absolutely a code issue, but we're pretty much convinced it's an Apache / cPanel issue.  It would be nice to have some input on this since this particular incident of No input file specified does not seem to match the others already found here and elsewhere on the web.

It turned out that the problem was from customizing the domain's document root in the userdata files and then the PHP-FPM configuration had not been rebuilt and the service not restarted.  The following resolved the issue:

/scripts/php_fpm_config --rebuild
/scripts/restartsrv_apache_php_fpm

It's interesting since there are a broad variety of issue that seem to cause this No input file specified issue, but they all mostly revolve around Apache config issues.


How to Show the Total Word Count of an Entry? Any way to show the total word count in real-time to authors while they are writing an entry that has multiple blocks?

I don't need per-block word count ... I need total word count shown in real-time.

You'll need to add a plugin like this one from Lindsey DiLoreto that allows you to insert your own javascript into the CP.  Then you'll need to write some javascript that counts up each word in a textarea input for each block.  I'm sure stackoverflow has several answers on how to do that.  Keep in mind Craft already has jQuery installed if you choose to use it.


Is it possible to have category listing page of entries if the category is defined within a matrix block inside said entries? I think I have been staring at this problems too long and I need a kick in the right direction...

Here is what I have (the content modeling is a tad wonky but this is what we're dealing with):

Clients Channel

Work Samples Matrix Field (1 matrix block inside the matrix field)

Category matrix block field pulling from work categories
Assets matrix block field to upload images
Table matrix block field to enter youtube ID's

This is what I need to do:

When a category is selected by a user I take the user to a category listing page that contains all clients (from the Clients channel) with work samples within that category (categories within the matrix block from each client in the client channel).

For example: All clients with "website" samples should be displayed on a page at http://domain.tld/category/website

What is the most efficient way to pull this off in Craft/twig?

Reading the Craft docs is getting me about 1/2 there but something in the relationships docs isn't clicking yet.

First you need to define the category. If your category group has the “Categories in this group have their own URLs” checkbox checked, and the URL Format is set to category/{slug}, and this is happening on the template you’ve specified in the Category Template setting, then all the stars have aligned and this step is taken care of for you automatically. The category will already be available to your template, and it will be called category.

Otherwise you will have to fetch it yourself:

{% set category = craft.categories({
    group: 'workCategories',
    slug: craft.request.getSegment(2)
}).first() %}

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

Once you have your category, you can fetch the related Clients using the relatedTo param on a craft.entries query:

{% set clients = craft.entries({
    section: 'clients',
    relatedTo: {
        targetElement: category,
        field: 'workSamples.myCategoriesField'
    }
}) %}

That’s saying: “Give me the entries in the clients channel, which are related to category (where category is the target of the relation), via the myCategoriesField sub-field of a workSamples Matrix field.” Make sense?

Once you have those client entries you can loop through them, and show their respective Matrix blocks which are related to the category:

{% for client in clients %}

{{ client.title }}

    {% for workSample in client.workSamples.relatedTo({ targetElement: category }) %}
        {% for image in workSample.myAssetsField %}

        {% endfor %}

        {% for row in workSample.myTableField %}
            {{ row.youtubeId }}
        {% endfor %}
    {% endfor %}
{% endfor %}

If there are going to be a lot of clients/Matrix blocks/assets getting looped through, it’s probably going to be a good idea to wrap the whole thing in {% cache %}...{% endcache %} tags, as there’s potential for the query count to really pile up here.


Category slug variable is not available when category url's are disabled Just like the title states, the slug variable is not available when a category's url are disabled:

<select name="field-styles" id="field-styles" class="select">
    <option value="">Style</option>
    {% for style in craft.categories.group('productStyles').order('title') %}
    <option value="{{ style.slug }}">{{ style.title }}</option>
    {% endfor %}
</select>

The snippet of code above works when the URL's are enabled for this category group. When disabled, the input value is blank.

That's by design, slugs are used for building the url to link to a specific element, in this case, a category.

Edit: seems I was wrong on the above, see comment. Leaving the rest of the answer as using the ID offers a solution.

You'll have to use the id to refer to the category as value, like so:

<select name="field-styles" id="field-styles" class="select">
    <option value="">Style</option>
    {% for style in craft.categories.group('productStyles').order('title') %}
    <option value="{{ style.id }}">{{ style.title }}</option>
    {% endfor %}
</select>


Do I have to restart apache server every time I change a Craft PHP file? When I make a change to a .php file of Craft, say config/routes.php, do I have to restart the server to take effect ?

No, but make sure devMode is turned on in your development environment.


Showing different field layouts for entries within the same structure I set up a structure for pages that looks like this:
- All Services
  - Service 1
    - Service 1 subpage a
    - Service 1 subpage b
  - Service 2
    - Service 2 subpage a
    - Service 2 subpage b

I followed the accepted answer to this question to set up different templates within that structure, so now the level 2 pages (i.e. Service 1 and 2) use a different template than the level 3 subpages (i.e. a and b).
These templates have different elements, so now I want to show different fields/field layouts when I edit the page entries. For example, if I'm editing a level 2 page, it should show fields for the title, a rich text field, an image upload field, and a few other fields I've created, but if I'm editing a level 3 page, it should only show a title and rich text field.
Is it possible to do this? If not, what's the best way to handle this type of thing in Craft? I'm trying to avoid creating one structure for level 2 pages, and another structure for level 3 pages, because I'm not sure how to preserve the hierarchical relationship between level 3 and level 2 pages if I do that.

The only way to do this is to create multiple entry types for your structure section.
Each entry type has its own field layout (can have different fields from the other entry types in that section).
Sadly, it's not possible to restrict entry types to a particular level in a structure – i.e. if you create "Landing Page" and "Sub Page" entry types, there's no way in Craft to make sure that the level 1 and level 2 entries actually use those entry types, according to their level. So, ideally you should a) make sure whoever edits the content in that section makes sure that they should be careful to use particular entry types for particular structure levels, and b) design and create templates that are flexible enough to work even if, for example, somebody publishes a "Sub Page" entry at level 1.
Most likely, you should change your current templating setup with something like this, if you go down this route.


Twig Format Number Filter not working Twig docs include a format_number filter, as of ver 2.12
My install shows Twig at ver 2.12.5, so should work, but throws a Twig Syntax Error: Unknown "format_percent_number" filter.
This started with not being able to use the Craft "percentage" filter because I was doing this:
{{ var1 / var2 | percentage }}

That filter fails because 'var1 / var2' returns a number without a leading zero and Craft does not like that.
So, two issues:

the Twig filter format_number not work
any thoughts on how to get around the Craft percentage filter issue

Thanks!

You're getting the error because of Twig's operator precedence. Filters take priority over math.
So basically Twig was trying change var2 to a percentage first instead of using the results of the math expression first, ie:
{{ var1 / (var2 | percentage) }}
Generally this behavior is usually what you want but sometimes there's edge cases where it doesn't work out. As you figured out, putting parenthesis around expressions to group them is never a bad idea especially when filters are involved.


Headless CraftCMS: How can I tell Craft to load live preview from a different (sub)domain? I will be using CraftCMS (Craft Solo 3.3.18.4) in headless mode as the backend for a Rails app. The Craft instance lives on a different subdomain.

How do I instruct craft to use the rails app URI when loading live preview in the preview iframe?

For example, if we presume
admin.domain.com for craft admin and
domain.com for the front end

How do I make the live preview frame to load from the live app?
domain.com/posts/first-posts-slug?x-craft-live-preview=2OcHezCnU8&token=lY6F...

Since Craft 3.3.1, you can create a custom alias that resolves to your frontend base URL, and add that alias to the relevant preview targets' "URL Format" setting.

For example, assuming you put something like the below in your config/general.php file:

'aliases' => [
    '@previewBaseUrl' => 'https://domain.com',
],

...you'd be able to use that @previewBaseUrl alias in your preview targets, e.g. @previewBaseUrl/posts/{slug}


Craft User Permissions in subsites I'm still new to CraftCMS and still learning about site structure. The site that I am asking about below is not (yet?) in CraftCMS:
Our site is composed of many subsites which have different users contributing to them. Would it be possible within CraftCMS to restrict a user's login to only viewing the content that they can edit (ie- within their 'subsite' area)? I say viewing (not editing) since we have a LOT of content and I'd like to keep the content accessibility separate for different users to prevent confusion.

You can certainly restrict user's access to specific sections on a Craft site, using Craft Pro's user and user group permissions, both in the control panel and on the front-end.

Lots of different ways to setup these "sub-sites", but it sounds like you'll be wanting them to share the same Craft installation.


setRouteVariables doesn't return errors to the template So I've been breaking my head trying to figure this out. I'm working on a contact form plugin. Basically I'm coping exact same code craft uses to create form "fields". I have validation working like it should. And I have 2 required fields that should return error messages. But when I try to:

craft()->urlManager->setRouteVariables(array(
  'field' => $field
));

And in the template file {{ field }}, I get.. Variable "field" does not exist

I can't seem to get the value to populate on the form nor display the errors because of this. Anyone had problems like this before?

Here's my files:
https://gist.github.com/owldesign/e01b49fdb1da3ef23ef2

Sorry for weird file delivery.. this comment won't let me post more than 2 links.

Please let me know if you guys need more from me?
Thanks.

Edit: Repo https://github.com/owldesign/FormBuilder

I have finished the plugin, with much success, if you wondering you can see it here https://github.com/roundhouse/FormBuilder-Craft-CMS


Custom plugin field in Table Columns? I just created my first Craft 3 plugin. In the plugin I also have a custom (select)field. Everything is working as expected, which is great!
But I can't for the life of me figure out, how to add this field as a Table Column? It's not showing up. The field is added and filled in the entries within the section. Just to be clear, this is where I mean:

Thanks in advance!

If I understand your question well, you need to use the EVENT_REGISTER_TABLE_ATTRIBUTES event. This thread should get you on your way :)


Width, length and dynamic pricing - Commerce We've built quite a few sites in Craft CMS and have been waiting for a project to get stuck into Craft Commerce - that time is here! BUT, one thing - it's for a carpet company so allowing the user to add a width and length of carpet is critical.

After reading many similar questions, I see that everyone's pointing to creating variants for each option. This isn't practical for this case as they have many types of widths let alone being able to type in a length. Plus, they get new stock quite often.

They're currently using WooCommerce and we really don't want to go back to Magento so it'll be a shame if we couldn't use Craft Commerce.

So here are my questions - has anybody released a plugin that can do the above? If not, is a plugin the way to go for this? Finally, are there any plans to add this functionality into Craft Commerce?

Sounds to me like this is a job for a Custom Purchasable.

Basically you write a plugin such that your created element meets the Purchasable interface, which handles it's own pricing calculations etc., and that custom purchasable becomes a sellable item through Commerce.

Documentation is here: https://craftcommerce.com/docs/purchasables

Other than that, I can't see why Commerce wouldn't work well for such a scenario as it allows for complete flexibility with front end presentation and checkout.


Get user field category I have a matrix that contains a block with a category field. I want to loop over the matrix models, in PHP, to get data. Here's what I have so far:

foreach ($user->networksMatrix as $key => $networkLink)
{
    $netArr[$networkLink->id]["fields"]["networktype"] = $networkLink->networktype;
    $netArr[$networkLink->id]["fields"]["networkUrl"] = $networkLink->networkUrl;
}

networktype is a category field. How do I get the get the ID of the category a user selected?

Thanks!

UPDATE

I discovered that the following works:

foreach ($user->networksMatrix as $key => $networkLink)
{
    $netArr[$networkLink->id]["fields"]["networktype"] = $networkLink->networktype->ids()[0];
    $netArr[$networkLink->id]["fields"]["networkUrl"] = $networkLink->networkUrl;
}

Since networktype is a categories field and that field is limited to 1 category I'll only ever get a single result from the method:

ids();

So... I just do this and I'm good:

$networkLink->networktype->ids()[0];

For the sake of completeness, the question was resolved by the asker and I will quote his answer here, so this fine question is recognized by Stack Exchange as answered!

Matt V says:

  I discovered that the following works:

foreach ($user->networksMatrix as $key => $networkLink)
{
    $netArr[$networkLink->id]["fields"]["networktype"] = $networkLink->networktype->ids()[0];
    $netArr[$networkLink->id]["fields"]["networkUrl"] = $networkLink->networkUrl;
}

  Since networktype is a categories field and that field is limited to 1
  category I'll only ever get a single result from the method:

ids();

  So... I just do this and I'm good:

$networkLink->networktype->ids()[0];


How do I add html code to a page I want to add a Comodo Trust Logo to a Craft CMS website page per the instructions below:

Install Code Snippets
Please insert the following two snippets of HTML
code into your webpage document. You will need to repeat the process
for each web page you wish to display the TrustLogo.
<script type="text/javascript">//<![CDATA[
var tlJsHost = ((window.location.protocol == "https:") ? "https://secure.comodo.com/" : "http://www.trustlogo.com/");
document.write(unescape("%3Cscript src='" + tlJsHost + "trustlogo/javascript/trustlogo.js' type='text/javascript'%3E%3C/script%3E"));
//]]>
</script>

How do I access the Craft CMS code in order to add the above JS?
Thank you!

To edit the HTML code for your Craft site you're going to want to edit the appropriate template file in your Craft install. If you're running on Craft 2 your template files can be found in .craft/templates/; if you're on Craft 3 your templates are found in ./templates/.

You'll need to look in the Craft control panel and see which twig template the section containing the entry (or page) you're trying to edit references. You'll find that info if you try to edit the respective section in Settings > Sections.

I will mention as well, if you're looking to include some code that belongs in the HEAD of the html, you'll probably find that in a "master" twig template that contains the <head></head>. Once you find the twig template specified in the section settings in the Craft control panel, most of the time you'll see an {% extends %} tag which links back to that "base" template.

Hopefully that helps! I'd recommend maybe reading through the Craft docs, starting with Templating Overview. Cheers!


How to change the Craft 3 activation email? In my organization many of the employees believe the user activation email sent out by Craft is spam.  How do I change the email text and possibly add an image, like our company logo, to the email?

Under Settings > Email there is a field called "HTML Email Template" which you can use to point to a single template that handles all of the system emails. It's not very obvious from the Craft UI, but you can use that single template as a routing mechanism for including per-email templates using the variable emailKey which is available in the template. Your routing template could look like this:

{# Craft has four predefined email keys:

    account_activation
    verify_new_email
    forgot_password
    test_email

... route to them here, or fallback to default
#}

{% include [
    '_emails/' ~ emailKey ?? null,
    '_emails/default'
] %}

You'd then have another template called account_activation.twig where you can go wild with whatever modifications you like. Each email also has a link variable available in the template to output the link to whatever it is.


Assets Images not being found When importing local user assets to a development server with sftp (including a database import), some of the assets are missing (it gives the impression to be random). Even after updated the indexes.

When I try to access them directly in the browser, I get a Page not Found, but they are well present on the server, within the same folder/name.

How It is possible ?

I found out that, somehow, the files and the foldernames containing special characters where not well handled (In my case, a lot of é and è).

Removing the special characters, and adding 'convertFilenamesToAscii' => true to the general.php config file for future edition / creation / upload resolved this issue for me.


Get id of row inserted into database I insert data into database table using query builder:

$command = Craft::$app->db->createCommand()->insert('test2', array());
$command->execute();

How can i retrieve id of newly inserted db row?

I believe you can use getLastInsertID to fetch the ID:

Craft::$app->db->getLastInsertID();


Does each MatrixBlockModel in an entry have a unique dateUpdated? After doing some experimentation in looping through MatrixBlockModel, it seems that even though each block has a dateUpdated property, this value is never unique to each block, but is shared between all blocks in the Entry.

{% set timeLimit = now | date_modify("-2 min") %}
{% for block in entry.blocks %}
  {% if block.dateUpdated >= timeLimit %}

    {{ block.dateUpdated | date(dtFilter) }}

  {% endif %}
{% endfor %}

If the entry has 6 blocks, and I update one of those blocks and save, the same date will output 6 times for about 2 minutes, then nothing will output.

Can anybody confirm this?

Yes I can confirm, currently the dateUpdated property returns the same datetime object for every block model. It's actually the save date of the entry (entry.dateUpdated) that is saved to the craft_matrixblocks table in the DB.

Can't say if it's intended to work like this though.


How to pass an entry's Matrix fields as JSON? Have a JSON object that I'm trying to pass to my Javascript through a script tag in my markup like so:

<script type="text/json" id="json-data">
{
  "terms": "{{ entry.termsAgreement }}",
  "sectionHeader": {{ entry.formSection }}
}

However, I'm getting an error that says:

Object of class Craft\ElementCriteriaModel could not be converted to string.

formSection is a Matrix field. How can I pass this along to have access to it in Javascript? I tried

JSON.stringify({{ entry.formSection }})

but no luck.

Thanks.

I'd strongly recommend looking at the Element API plugin for this.

If you're dead set against that, there are other examples of how to pull out section data in Craft for rolling your own JSON.

For Matrix it'd be no different that if your were pulling Matrix data out to be output in HTML instead of JSON (looping through blocks, grabbing fields, etc). Lots of examples in the Matrix templating docs.

The error you're getting is because when you simply output entry.myMatrixHandle, you're technically given back an ElementCriteriaModel object and the Element API plugin tries to convert that to a string to display in the JSON data and it doesn't know how to convert that object to a string.


Dashboard Widget: Access widget settings from controller / service i wrote a plugin with an additional dashboard widget.

i have to refresh the widget data every hour with ajax. so i added a plugin controller in my plugin directory with the idea of re-rendering the widget template (called through ajax).

1) how can i (correctly) access the widget instance from the controller (or service)?

my try is $widget = craft()->dashboard->getWidgetType('name'). this gives me the correct instance. is this the right way?

2) no settings data from widget (needed in widget template)

in the widget template i need access to the widget settings (defined in the widget class with defineSettings()).

in the controller, i get the widget instance (as described in point 1) and do $widget->getBodyHtml(), but the settings attributes are empty. all other parts of the template are rendered correctly.

when the widget is rendered the first time (no ajax request), anything seems to be fine (settings loaded correctly).

can anyone explain my fault?

found a way to solve the problem.

feels a bit 'dirty' to iterate over all active widgets to get the one i need (in the service class). the other option is craft()->dashboard->getUserWidgetById(), but how the heck can i get the id of the widget by given type in a simple way?

how ever, this solution works:

controller method (requested through ajax)

public function actionUpdateWidget()
{
    $this->requireAjaxRequest();

    try
    {
        echo craft()->showcase_widget->get()->getBodyHtml();
    }
    catch (Exception $ex)
    {
        echo $ex->getMessage();
    }

    craft()->end();
}

service class

<?

namespace craft;

use Exception;

class Showcase_WidgetService extends BaseApplicationComponent
{
    protected $widgetType = 'Showcase_Feedback';

    public function get()
    {
        $widget = null;
        $userWidgets = craft()->dashboard->getUserWidgets();

        foreach ($userWidgets as $userWidget)
        {
            if ($userWidget->type === $this->widgetType)
            {
                $widget = craft()->dashboard->populateWidgetType($userWidget);
                break;
            }
        }

        if (!$widget)
        {
             throw new Exception(craft::t('Widget not found'));
        }

        return $widget;
    }
}


Why is Sprout Forms returning 302 for ajax requests? I am using Sprout Forms on a Craft 3 site and trying to submit my form via ajax.

I've been able to do this many times in Craft 2, but not having much luck with 3 (yet). The docs look mainly for Craft 2 - is there a better way to find examples for Craft 3?

Here is what the headers look like that I am sending:

CRAFT_CSRF_TOKEN: <huge string hash>
action: sprout-forms/entries/save-entry
redirect: <long redirect hash>
handle: contact
fields[fullName]: Damon
fields[email]: name@test.com
fields[phone]: 211-111-1111
fields[message]: Hello.

I am always getting a 302 response back - without any error or other indication of what might be missing. If I remove the handle field, I'll get a 400 error, so I know I'm hitting the correct method.

Status Code: 302 Found

Here is what my js looks like:

$.ajax({
    type: 'post',
    contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
    cache: false,
    data: $('#contact-form').serialize(),
    url: $('input[name=action]').val(),
    processData: false,
    dataType: 'json',
    timeout: 50000
}).done(function (response) {
    console.log(response);  // nothing.
}).fail(function (error) {
    // Total fail.
});

Here is what I am including in my form that is Craft/Sprout specific.

{{ csrfInput() }}
<input type="hidden" name="action" value="sprout-forms/entries/save-entry">
<input type="hidden" name="redirect" value="{{ form.redirectUri|hash }}">
<input type="hidden" name="handle" value="{{ form.handle }}">

Thank you for any suggestions!

First I want to say thank you to the support staff at Sprout for helping me figure out my error.

I have the default install settings/configuration for a Sprout form. Spam protection was enabled in my case and that's what was causing the 302.

If I want to have spam protection enabled, I need to have this inside my <form> tags:

{% hook 'sproutForms.modifyForm' %}

So my form looks like this now:

<form id="contact-form" method="post" class="main-form" accept-charset="utf-8">
    <fieldset>
        {% hook 'sproutForms.modifyForm' %}
        {{ csrfInput() }}
        <input type="hidden" name="action" value="sprout-forms/entries/save-entry">
        <input type="hidden" name="redirect" value="{{ form.redirectUri|hash }}">
        <input type="hidden" name="handle" value="{{ form.handle }}">
    </fieldset>

    <fieldset>
        {# Get the full name field. #}
        {% set fullName = form.getField('fullName') %}

        ...
    </fieldset>
</form>

I'm getting a 200 response back and the entry is getting created!


Replacement for deprecated AssetsService Im developing my first plugin and was interested in using the findFolder() method from AssetsService but i noticed the class is depreciated. What is the proper way of achieiving the functionality of findFolder() without using the deprecated class? TIA!

Most of the Assets related classes in Craft 2 have been deprecated because they've been completely re-written/refactored/removed for the upcoming Craft 3.

So if you're looking for a Craft 2 replacement, there isn't one... the replacements are in Craft 3.


Pruning the users table I have a site that deals exclusively with user generated content.

After a few years, the users table is getting to a stage where it can probably be pruned of folk who have registered but not actually submitted any content.

What query would I run to show the users who have zero posts?

I thought something like select id from craft_users where id not in (select distinct authorId from craft_entries) would do it.

The distinct query certainly returns 1020 rows where we actually have around 1800 users.

Looks like this will do the trick

select * from craft_users
left join craft_entries on craft_users.id = craft_entries.authorId
where craft_entries.authorId is null and craft_users.id <> "1"


Possible to re-use one field multiple times in a section? This seems like it should be possible but I may be missing a trick.

Is it possible to use a single field multiple times in a section? So, for example, if you have a simple 'text' field and you want to include that twice in one section. The field layout designer only allows you to drag it once and then just move it to different tabs but not create another instance of it.

You can re-use the same text field multiple times in a section on different Entry Types, but if you would like to re-use the same text field multiple times on the same Entry Type (or page) your best bet would be to make it a Matrix Block.

For a quick overview on Matrix Blocks: https://craftcms.com/features/matrix

More info on Matrix Blocks: https://craftcms.com/docs/matrix-fields


Have Craft deliver single page despite having a directory of the same name in the public folder? I just switched my company's website to Craft, and I have a lot of already existing static webpages that I would rather not remake as templates and define routes for. I have a single page made in Craft at /events, but when I add the subdirectory events/event-name, going to /events presents a 403 error. I know why this is happening, because of the way Craft handles routing, but is there any way (possibly in my .htaccess file) for going to /events to deliver the single page like normal, despite having the subdirectory in my public folder? Thanks.

You could update the links to your static HTML to point to the files directly

http://mygreatnewcraftsite.com/events/myoldstaticfile.html

or modify your .htaccess file like I described here: "Is it possible to tell Craft to ignore requests to under a certain path?"


Basic Amazon S3 Setup I'm a total S3 noob but would like to get it set up so that I can store Assets there. So far, I've:

created an AWS account (zing!)
created a bucket named mybucket
created a user in IAM myuser
assigned the AdministratorAccess policy to myuser*
created a new Asset source called s3
entered the user Access Key ID and Secret Access Key, which correctly shows me the mybucket destination
URL Prefix is auto-filled with http://s3.amazonaws.com/mybucket

OK! When I go to upload a file to the S3 source, I see the upload stripe go all the way across the page and the loading spinner happening at the top right of the page. But this process hangs and the file is never uploaded.

This is a tiny image, so I don't think it's a file size issue. No errors / warnings are produced. I don't see anything obvious in the logs.

Any help is appreciated! Thanks!

--

*I know that I'll eventually want a more restrictive policy but for the time being, just trying to get a Hello World working.

I did end up opening a support ticket with Craft- they immediately suggested that this could be caused by a firewall. To which I scoffed! But after talking with some other folks in the office, this seems to be the case.

Unfortunately we never found a firewall solution to this problem. What did work was to assign a static IP to my computer that bypasses the http-proxy packet filter.

So yeah. Firewall. Dang.


Database structure for Craft 3 to import from external source? Is there any best practice how to import info Craft 3 data from external source, or should I backtrack it from the database?

I think you have to know what you need and what you want to achieve.
You need to decide if you want to add elements or records because there is a huge difference between those two types of objects and how you need to import and implement them

Elements
Pros:

it does not take a lot of time to make them manageable for clients
they can use all Craft features (relation fields, lists, edit forms....)
they are really flexible

Cons:

you'll need a little bit of time to dig into the concept if you are totally new to Craft
they'll have a record in your elements table so for larger projects you'll have to pay attention at your performance

Records
Pros

easy to handle
it does not require much time to create/import records since they are standalone and have no requirements
Yii's activerecord object is really powerful and intuitive in searching records
they don't create a massive overhead in your db

Cons

If you are going to make your records editable to users/customers in the cp you'll need to create everything on your own (templates/forms....) because they have no field layout and it's a mess to redefine them as elements to use Craft features... I did it once, it was not funny
You are not able to use Craft relations by default and have to create custom relation tables if you are going to do fancy stuff

After you decided what to use, you have to decide how you would like to proceed. You can create a custom element type or use an existing one (entries, categories) and how complex it needs to be. But without more information from your site it's hard to give any further advice.

I suggest everyone to create a custom plugin for imports to handle them. Due to Crafts/Yii2's plugin management and services it's totally trivial to create a data import because everything is really easy to understand and to manage. You can create a custom controller to fetch the data you need, set the values of your elements/records and use their save functions. The rest happens nearly automatically