plugins route post controller? I am developing a custom authentication plugin for Craft 3. But I can't route to my Controller via POST request with my login form. Request via GET work

Although your question is lacking in detail, here is a shot at helping you track down the issue. The fact that GET requests are working but POST requests are not, your form is likely missing a CSRF token. You can add it to your form using the following twig code:

<form method="post" action="">

   {{ csrfInput() }}

If your POST request is coming through as an AJAX request then you can create and submit a CSRF token as described in this answer.


element-api plugin / get entry total in section in Craft 3 What is the best way to get only the total entry number from a section with the least overhead, in the element-api.php?

Thanks

Mark

Ok i think i stumbled on the answer -

$signees = Entry::find()->sectionId(4)->count();


baseUrl outputs environment variable The newer versions of Craft CMS stimulate using environment variables in the CP. It works perfectly. I have set two variables for sites in my .env file:

DUTCH_SITE_URL="http://company.test"
ENGLISH_SITE_URL="http://company.test/en"

One thing that's not clear to me is the right way to request the baseUrl in templates. For example: I'm using a simple language switcher to switch between two languages:

{% set sites = craft.app.sites.getAllSites() | without(currentSite) %}
{% for site in sites %}

{{ site.language }}

{% endfor %}

When viewing the Dutch website the language switcher shows the link to the English website. The problem is that site.baseUrl outputs the environment variables instead of the English site url. The link looks like this:

http://company.test/$ENGLISH_SITE_URL

What's the proper way to deal with this?

You can get it to return the url using the siteUrl function and passing it a siteId parameter. So do:

{% set sites = craft.app.sites.getAllSites() | without(currentSite) %}
{% for site in sites %}

{{ site.language }}

{% endfor %}

I don't know if it's the best way but it works :)


Matrix-field with a category-field to output category-title on single entry page Me and categories, always giving trouble :)

On blogs, we are using a matrix field and in one of the matrix-types, I have a category field.
This is to output the title of the category.

{% extends "matrix/default" %}
 {% block blockContent %}

    {% set merk = block.merkNaam %}
    {{ merk.title }}

{% endblock %}

The outcome is empty ...

What do I miss?

Nevermind, the problem is solved.

I just need to loop over the categories.

{% extends "matrix/default" %}
{% block blockContent %}

        {% for merk in block.merkNaam %}
            {{ merk.title }}
        {% endfor %} #}

{% endblock %}


Setup Multiple System Email Addresses Hey I have a problem that i need to fix for a client. I have to send emails from different email addresses in different circumstances. Is it possible that I can setup multiple system email addresses and use one of them in my different plugins?

I tried to change the fromEmail attribute as well as the sender attribute on the email model but it still sends from the same email (which I thought would be the case ).

Anyway please let me know if there is any plugin out there that can do that.

Thanks in advance!

Out of the box, Craft doesn't support sending with multiple email addresses unless you change the email settings each time you need to send from the respective email address.

Craft does allow plugins to do this though. I know of two to consider, and present them in alphabetical order:

Postmaster - Objective HTML
Sprout Email - Barrel Strength Design


LinkIt: transform content As Craft doesn't provide an all-in-one link field (that covers external as well as internal links) out of the box, I opted for LinkIt.

What I wonder, how do I

Obfuscate email-links?
Bring phone numbers to a working format, by removing whitespace and adding the + in the right spot?

I expected LinkIt would do that by itself, but I haven't seen where yet.

Not super familiar the LinkIt, but there is a feature request for email obfuscation here: https://github.com/fruitstudios/craft-linkit/issues/58 you can comment on and you can make a new one for phone numbers.

In the meantime, some other plugins might do what you're looking for:

https://plugins.craftcms.com/obfuscator

https://plugins.craftcms.com/phone-number

Or you could make your own custom link types: https://github.com/fruitstudios/craft-linkit#custom-link-types


How to add recipient drop-down selection field with the Contact Form plugin? There is a guide on GitHub page how to add additional fields, but how to add recipient selection?

There's no way to do this by default as far as I know so you'd need to create a small plugin to dynamically add the recipient email to the form.

You might be able to shortcut that a little by changing that hidden input value using JavaScript alone depending on what was selected in the dropdown but the toEmail param is meant to be hashed.


Save contact form data to database I have your standard contact form. (Name, email etc.)

When the user clicks "save" I want to capture what was entered via a plugin & have a CP page to show the people who have filled out the form. I'll get there eventually, but for now I am stuck actually inserting the record.

I am able to insert a record, but it's completely empty. So I know I'm getting close, just not passing off the right information to the right spot.

Model:

public function defineAttributes()
{
    return[
        'firstName' => [
          'type' => AttributeType::String,
          'required' => TRUE
        ]
     ....
    ];
}

Controller:

public function actionSaveContact() {
    $this->requirePostRequest();

    $model = new Model();

    $model->firstName = craft()->request->getPost('firstName');
    ....

    if ($model->validate())
    {
        craft->service->saveContact($model);
    }
}

Service:

public function saveContact(Model, $contact) {
    error_log(print_r($contact, true));

   // I know the data is showing, I can see it in the log
   // [_attributes:Craft\BaseModel:private] => Array(
   //     [firstName] => Bob
   // )

   // Here is where I am hung up. I don't know what to do next.
   // $record = new Record();
   // $record->save($contact); This creates an empty record in my db
}

I feel really silly asking for help on what seems like such an elementary task. I'm close - just need a little shove in the right direction I think.

Thank you!

EDIT

Thank you to Mats Mikkel Rummelhoff for your suggestion. It pointed me in the right direction. It seems what I am encountering now has been found in the past? Now it seems I am only saving one field? Using this post I was able to "manually" collect all data and save to my DB. I'm not sure why though - all of the data seemed to be available.

Service

....
$attributes = array(
    'firstName' => $model->getAttribute( 'firstName' )
    ....
);

foreach($attributes as $k => $v) {
    $record->setAttribute($k,$v);
}

if ( $record->save() )
{
    error_log('SUCCESS');
}
else
{
    ....
}

EDIT

Thank you so much for everyone's contribution(s). I'm going to keep updating this in the event that someone else comes across this same problem.

Going along with @Stuart Whitehead comments, right here is proof:
"AttributeType::String does not apply any validation rules." Which is why that field was not getting populated.

Which is what I was setting as my firstName, lastName and so on.

I have also found this article: The Definitive Guide to Validation in Craft Which, is making more and more sense each time I go though it.

The tricky part (for me) is that there isn't a direct corolation between craft and Yii. Meaning that Yii doesn't have a defineAttributes() method where the rules are defined. Craft uses this method, and translates it (for lack of better words) into the Yii equivalent. Pretty cool, just increases the learning curve a bit.

Light bulbs are coming on!

EDIT

This is probably pretty elementry, but I have also discovered that the attribute type that you define in your model, must match the same attribute type in your record. For example:

Record

public function defineAttributes() {
    'firstName' => AttributeType::Name,
    'lastName' => AttributeType::Name,
    ....
}

Model

public function defineAttributes() {
    return [
        'firstName' => [
             'type' => AttributeType::Name,
             'required' => TRUE
         ],
         'lastName' => [
             'type' => AttributeType::Name,
             'required' => TRUE
         ],
         ....
    ];
}

Now with things starting to get in the correct way of doing things, gasp stuff is working. Now using @Mats Mikkel Rummelhoff's comment (having all fields validate now) I am able to use:

$record->setAttributes( $model->getAttributes() );

Stripping this back, your basic problem is saving data to the database from an unreliable source. This is a fundamentally insecure operation—we've got no idea if this user is genuine or attempting something malicious. That's why the underlying Yii framework is trying to protect your install of Craft, and which is the reason you're seeing this ‘buggy’ behaviour with setAttributes().

The Yii framework implements a ‘safe’ validator. A key point made in this helpful article is this:

  Massive Assignment will only be made for fields which have passed
  some explicit validation rule.

This means that any attributes you define without an explicit validation rule will be considered unsafe. This will be the reason that only your email field was saving—it has an explicit validation rule (i.e. an email pattern).

How can you resolve this, then?

Set attributes explicitly

Firstly, you could explicitly set each attribute like you have been doing. Since this is not a massive assignment, the data is treated as safe and will save OK. Both $record->setAttribute() and $record->attribute() will work for this.

Define attributes with explicit validation

Another solution is to define explicit validation rules, and will allow massive assignment on these attributes, but explicit rules only really apply for some data types. What if you want a simple string?

Make existing attributes safe

A solution could be to add the safe rule to your attribute definition. If you follow the definition of attributes down the rabbit hole, you'll find that attribute configs are normalised by ModelHelper::normalizeAttributeConfig() (and subsequently ModelHelper::getRules()) which does not cater for this. Now where does that leave us?

It's possible to override (and extend) the inherited rules() method. Assuming you wanted to make all attributes safe and valid for massive assignment, I reckon something like this would work.

public function rules()
{
    // Are there any existing rules?
    $rules = parent::rules();

    // Make all attributes safe
    $rules[] = array(implode(',', array_keys($this->getAttributes())), 'safe');

    // Send it on outta here
    return $rules;
}

You should then be able to massively set attributes with $record->setAttributes().


Restricted access to assets in Redactor I have created several asset sources in craft and now i created user groups, with different view rights to this sources. When a user with restricted rights goes to the "assets" tab in craft, the rights management works as excepted: the user only see assets sources, where he has access to. But in redactor wysiwyg editor, using the insert image button or link to a asset function, it shows always all asset sources, even if the user has no view access to. Is there a way to restrict this list, based on users "view" permissions?  Maybe i missed it and there is something like a global config option (for example: restrictAssetsInRedactor = true)?

When i look in firebug, i see, that the modal window is called without any sources. Is there a way to modify/overwrite this call with a custom plugin?

There is no native way to limit which sources appear in the asset window. I imagine it can be accomplished with a custom field type. This would be a great feature for future releases; I recommend adding it to the Feature Requests forum.


How can I display the related posts (by category) at the bottom of each post? I'm converting a WordPress blog to Craft - first time playing with categories in Craft, so how can I display the related posts (by category) at the bottom of each post?

This can be accomplished using Craft's Relations.

My example code assumes you know the blog categories slug, and that you are pulling posts from a single category.

First, you'll have to get a reference to the category ElementCriteriaModel object pointing to the category of the blog post.

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

With a reference to the category model, you'll be able to find related entries.

{% for post in craft.entries.section('blog').relatedTo({targetElement: category}) %}
    {% if post.id != entry.id %}

{{ post.title }}

            {{ post.body }}

    {% endif %}
{% endfor %}

The if statement makes sure you aren't including the current post with the related posts.


Localhost: Why does {{ asset.url }} return {{siteUrl}}/path in the browser? I'm very new at Craft templating, and I can't seem to get an asset to link correctly in the browser.

{% block content %}

{{ entry.title }}

        {{ siteUrl }}

Posted on {{ entry.postDate.format('F d, Y') }}

        {{ entry.blog_body }}
        {% for asset in entry.blog_featured_image %}

        {% endfor %}

{% endblock %}

Becomes this:

New Blog 1

  http://localhost/craftcms/public/

Posted on January 15, 2017

"Body Text"

when output to a browser.

{{ siteUrl }} will display the path just fine, but when I'm using {{asset.url}} and it gets changed to {{siteUrl}} it doesn't create the path, it just stays at siteUrl. This is really confusing me.

Why doesn't {{ siteUrl }} return the base path when it's used in the asset.url?

What field type is blog_featured_image? Just an image asset?
Does it work with

<img src="{{ asset.getUrl() }}" alt="{{asset.title}}" /> ?


Custom field type file upload error [Uploaded File Class] I need to upload a file to my server via a custom field type and I'm trying it like this:

    public function prepValueFromPost($value)
{
    // Get file
    $file = \CUploadedFile::getInstanceByName('fields[handle]');

    // Determine folder
    $folder = 'folder/to/upload';

    // Ensure folder exists
    IOHelper::ensureFolderExists($folder);

    // Get filepath - save in storage folder
    $path = $folder . $file->getName();

    // Save file to Craft's temp folder for later use
    $file->saveAs($path);
}

public function getInputHtml($name, $value)
{
    return craft()->templates->render('_includes/forms/file', array(
        'name'  => $name,
        'value' => $value,
    ));
}

This sadly ends up in the following error:

Fatal error: Call to a member function getName() on a non-object in...

Does anyone have an idea how to solve this? My file input has the name "fields[handle]" but i also tried "handle" but nothing changes...

Yii’s CUploadedFile class actually doesn’t support retrieving uploaded files that came from a file input whose name was “namespaced” (e.g. name="fields[handle]" rather than just name="handle").

However, Craft has its own UploadedFile class which extends CUploadedFile, and the whole point of it is to add that namespaced input name support. It uses a dot syntax rather than square brackets, so if a file input had the name fields[handle], you would fetch that file like this:

$file = UploadedFile::getInstanceByName('fields.handle');

Problem is, you can’t actually rely on the file input name having a fields namespace – it will vary depending on the form. In fact many element forms within Craft have randomized namespaces (e.g. the Quick Post dashboard widget, or the modal windows that come up when you double-click on an element within a relational field).

That’s why field types have a getContentPostLocation() method, which returns the input name that would have been used for the current field, namespace and all, converted into dot syntax. So you can plug that value directly into getInstanceByName() and get your uploaded file.

$contentPostLocation = $this->getContentPostLocation();

if ($contentPostLocation)
{
    $file = UploadedFile::getInstanceByName($contentPostLocation);

    // ...
}


Search for assets containing a custom field How can I search for assets containing a custom field? The field on the asset is called lang. When I use this code no assets are found.
{% set folderId = craft.app.request.getQueryParam('folderId') %}
{% set query = craft.app.request.getQueryParam('q') %}
{% set lang = craft.app.request.getQueryParam('lang') %}

{# Search for assets in the downlaoads folder #}
{% set assets = craft.assets().volume('downloads') %}
{% set assets = assets.folderId(folderId).includeSubFolders() %}

{% set searchQuery = [] %}

{# Check if a query was supplied, if so then search for it. #}
{% if query is not empty %}
{%     set searchQuery = searchQuery|merge({query: query}) %}
{% endif %}

{% if lang is not empty %}
{%   set searchQuery = searchQuery|merge({query: 'lang:' ~ lang}) %}
{% endif %}

{% paginate assets.search(searchQuery).limit(10) as pageInfo, pageEntries %}
I also tried:
{% set query = query ~ ' lang: ' ~lang %}
{% paginate assets.search(query).limit(10) as pageInfo, pageEntries %}

If I remove the lang part results will show up.
The field is a Dropdown field with languages. Value is ISO code and Label the language name. The variable lang in the code contains nl, en etc.

Caveat: This is totally untested, and could be nonsense. I'm sure you'll let me know. It assumes that the Craft element query methods can be used here.
If you have a 'lang' value, add a where to your basic assets element query
    {% set folderId = craft.app.request.getQueryParam('folderId') %}
    {% set query = craft.app.request.getQueryParam('q') %}
    {% set lang = craft.app.request.getQueryParam('lang') %}

    {# Search for assets in the downloads folder #}
    {% set assetsQuery = craft.assets().volume('downloads') %}
    {% set assetsQuery = assets.folderId(folderId).includeSubFolders() %}

    {# If there's a lang value, add a where to the element query #}
    {% if lang is not empty %}
    {%     set assetsQuery = assetsQuery.where(expression('[[field_lang]] = :lang', {lang: lang})) %}
    {% endif %}

    {% set searchQuery = [] %}

    {# Check if a query was supplied, if so then search for it. #}
    {% if query is not empty %}
    {%     set searchQuery = searchQuery|merge({query: query}) %}
    {% endif %}

    {% paginate assetsQuery.search(searchQuery).limit(10) as pageInfo, pageEntries %}

*Note that I've changed the variable 'assets' to 'assetsQuery'


How to filter entries by clicking multiple categories on front end I would like to be able to filter my entries list by multiple categories on the front end. For example, if I first click a category button "lunge" then the results would show entries which are categorized as "lunge".  If I click a second category button labeled "dumbbell" then the results would be filtered more and show only entries that are categorized as both "lunge" and "dumbbell".

I found some similar threads but haven't been able to get the suggestions to work for me.  I believe I need to pass the categories into a URL query string like this:

www.website.com/training/exercise-list?q=lunge,dumbbell

where q is my search query parameter and lunge and dumbbell are the categories that were clicked.

Section is called exercisesDb
Category Group is calledtrainingCategoryGroup
Category Field in the section is called
trainingCategory

Thanks so much!

First, I would use something like training in your query string. It's a little more readable and you aren't searching for the words lunge and dumbbell anywhere in those entries, just entries related to those category slugs.

{# First you would find any training categories in the URL query string. #}
{% set trainingQuery = craft.request.getParam('training') %}

{# Then find categories that match the slugs in your query string. #}
{% set trainingCategories = craft.categories.group('trainingCategoryGroup').slug(trainingQuery) %}

{# setup your search parameters #}
{% set searchParams = {
  relatedTo:  trainingCategories,
  section: 'exercisesDb'
} %}

{# Find your entries #}
{% set entries = craft.entries(searchParams).order('score') %}

Your search form just needs to have the checkbox's input name as training[]. If it's on the same page, test to see if the category slug is in the trainingQuery array so it can be marked as checked or not.
Create this by finding all the categories in the trainingCategoryGroup group.

<form action="http://www.website.com/training/exercise-list">

  {% for category in craft.categories.group('trainingCategoryGroup') %}
    <input type="checkbox" name="training[]" value="{{ category.slug }}" {{ category.slug in trainingQuery ? 'checked'}}>{{ category.title }}

  {% endfor %}

  <button type="submit">Search</button>
</form>

Then output your list of entries. This is a simple example.

{% if entries | length %}

    {% for entry in entries %}

        {{ entry.title }}

    {% endfor %}

{% else %}

No results

{% endif %}

If the query string is blank, this will show all of your entries. If you want to restrict that, you can wrap the previous code block in this...

{% if trainingQuery %}
  ... (entries) ...
{% endif %}

This is an inclusive search that will match entries in ANY selected categories. If you want an exclusive search instead (category AND category), you have to do it a little differently.

{# Get search parameters from the URL query string #}
{% set trainingQuery = craft.request.getParam('training') %}

{# Start an array of search parameters (relationParam) with 'and' to match ALL categories #}
{% set relationParam = ['and'] %}

{# Find categories that match the slugs in your query string... #}
{% for querySlug in trainingQuery %}
  {% set trainingCategory = craft.categories.group('trainingCategoryGroup').slug(querySlug) %}

  {# And merge them into the relationParam array. #}
  {% set relationParam = relationParam|merge([{ targetElement: trainingCategory }]) %}
{% endfor %}

{# Avoid passing an array with `['and']` only #}
{% if relationParam|length < 2 %}
  {% set relationParam = '' %}
{% endif %}

{% set searchParams = {
  relatedTo:  relationParam,
  section: 'exercisesDb'
} %}


How can I translate static text in my templates that have accents? Using this help page https://craftcms.com/support/static-translations I've created a fr.php file in a translations folder - and it's working OK. Except when I have "Telephone" => "Téléphone" in the array - the two é get output as black diamonds with a question mark in.

How should I be adding Téléphone in the array so that it outputs correctly?

Many thanks
Lee

We are in the process of translating one of our client sites into 16 (yes that's 16!) languages and we haven't had any issues with accented characters.

The only thing I can suggest off the top of my head is to ensure you are using UTF-8 character encoding. Pop this in your <head>:

<meta charset="utf-8">

Hope that helps.


Fetching localized globals? I have a site that is mixed English and Chinese.  I've properly set up the locale to include Chinese as a locale, and have put Chinese translations for my fields in place.  That all works.

However, the site isn't one where you'll pick Chinese or English, it's going to display both in many cases.

So is there a way to explicitly set the English or Chinese translation of a global (or any field for that matter)?

I tried:

{{ myGlobalSet.myGlobal.en }}

As well as:

{{ myGlobalSet.en.myGlobal }}

...but it didn't like either one of them.  Is there a way to retrieve the localization of a field without having to switch the locale of the entire site?

It looks like I can do:

{% set myGlobalSet = craft.globals.getSetByHandle( 'setName', 'zh' ) %}
{{ myGlobalSet.myGlobalVar }}

If anyone has a better way to do it, please let me know... my plan is just to put this into a base template so that all of the pages can access the localization easily.


How to store json data in a custom fieldtype so that it's data can be referenced as attribute values? I would like to store a json object in a custom fieldtype, and be able to traverse the object's attributes using twig dot syntax in my template. I am currently storing the raw json object as a string, but I'm not sure what I need to do to be able to reference the stored string as an object.

Here is a shortened example of the raw json string that is being stored:

"Stripe_Customer JSON: {
    "id": "cus_4v68MrZu3za8XT",
    "object": "customer",
    "cards": { "object": "list", "total_count": 0, "has_more": false, "url": "/v1/customers/cus_4v68MrZu3za8XT/cards", "data": [ ] },
    "subscriptions": { "object": "list", "total_count": 0, "has_more": false, "url": "/v1/customers/cus_4v68MrZu3za8XT/subscriptions", "data": [ ] },
    "etc": "etcetcetc"
}"

In my template I would like to be able to reference the objects properties in some way (i.e. {{ fieldHandle.id }}) for display only; and on the back-end within a service, I would like to set object properties before saving back to the DB (i.e fieldhandle->id = value).

I am not sure whether defineContentAttribute should return AttributeType String or Mixed in this case.

public function defineContentAttribute()
{
    return AttributeType::String;
    //return AttributeType::Mixed;
}

And if it should be a string, how would one define the column type as "Text" vs the default VARCHAR(255)?

Update: I see that there is a similar question regarding custom fieldtype with multiple values, however, in this case, the end-user will not be manipulating the data directly in any way — they will be filling in dummy fields that will be send to a third party service via javascript/ajax, a result object returned, and then forwarded (again via ajax) to a back-end service method to be processed and saved to the DB.

You already mentioned the related answer in custom fieldtype with multiple values, and it actually is perfect for your usecase.

It doesn't really matter how you transport the data over to Craft, because if the content is set to AttributeType::Mixed, then Craft will JSON encode/decode it when requested.

So, to save your data, send over an array, like so:

$stripeCustomer = [
    "id" => "cus_4v68MrZu3za8XT",
    "object" => "customer",
    "etc" => "etcetcetc"
    ];

// Transport $stripeCustomer to Craft with Ajax

In the context of Javascript, you'd send over the serialized form data.


How to get all users with active Commerce 2 subscription How do I get all the users with an active subscription in Commerce 2? I want to be able to filter entries by subscribed users.

I solved this by creating a simple plugin.

use craft\db\Query;

class MyPluginVariable
{
      public function allActivelySubscribedUserIds()
      {
           $subscribedUserIds = (new Query())
                ->select('userId')
                ->from(['{{%commerce_subscriptions}}'])
                ->distinct()
                ->all();

            // Create array of just user IDs
            $subscribedUserIds = array_column($subscribedUserIds, 'userId');

            return $subscribedUserIds;
       }
 }

I my case I needed to display all entries authored by users that are currently subscribed. In my template I used the variable like this:

{% set subscribedUserIds = craft.MyPlugin.allActivelySubscribedUserIds %}

{% set entries = craft.entries()
    .authorId(subscribedUserIds)
    .all()
%}


How to directly access translated variables by language I have a localized, two language site (en and fr) that I have a translated global variable set for. My question is: is there a way on a Craft 3 template to directly access a translation of a variable that isn't the same as the currentSite language. Specifically, I'd like to show both translations of the same variable on one page.
I am getting the variable with this currently: siteOwnerInfo.siteOwner

Take a look at the Craft docs page for "Globals" under Querying Globals.
You can pass a site ID number to an element query to get globals from another site/language. For example, if your French site id number is 2, you could do this:
{% set siteOwnerInfoFrench = craft.globalSets()
  .handle('siteOwnerInfo')
  .siteId(2).one() %}

{{ siteOwnerInfoFrench.siteOwner }}


Localization - Getting page not found from CP when trying to edit new locale I've set up a new locale fr_ca according to the localization guide.
I've defined my site url's accordingly and set the files like so that english is on the top level and an fr_ca folder contains the index.php file.

I've set the craft folder accordingly, and defined CRAFT_LOCALE.
I've also enabled the locale in all my sections.

Now when i access a singles entry, and I click Canadian French on the right to switch locales, I get a Page Not Found error, the requested URL was not found on this server.

I've also set my templates so that inside my templates folder, i have a folder fr_ca containing a new index.html file to be served. When I try to access the site from the front end, using www.example.com/fr_ca, I get an entry is not defined error (which makes sense).

When a new locale is added to an existing site, Craft re-saves the entries in the background. If you're unable to edit the entry in the new locale, it would indicate that the task has not completed. Check the craft_tasks table in your database to see if this is the case. More info on stuck tasks here.


Display entries that meet multiple tag params how would I go about setting up a route and twig template to filter by multiple tags?

Example URL scheme: example.com/tags/tag1/tag2/tag3

where tag1, tag2 and tag3 are tags defined in a tag field inside an entry. The resulting entries list should only output entries with tag1 AND tag2 AND tag3. tag2 and tag3 should be optional. I want to avoid the use of get params such as ?tag=tag1,tag2,tag3.

The ultimate goal is chain multiple tags to get finer results, similar to pinboard.in tag chaining.

Example:https://pinboard.in/t:javascript/t:css/t:webdev
will return entries with javascript AND css AND webdev

My route looks as follows

URI: tags/tag-token/tag-taken2/tag-token3

and my twig template looks like

{% set entries = craft.entries.relatedTo(tag) %}

{% if craft.request.getSegment(2) !='' %}

Entries tagged with “{{ tag.title }}”

{% if entries | length %}

        {% for entry in entries %}

{{ entry.getLink() }}..

        {% endfor %}

{% else %}

No entries could be found with that tag.

{% endif %}
{% endif %}

{% if craft.request.getSegment(3) !='' %}
{% set tag2entries = craft.entries.relatedTo('and',
    { element: entry, field: 'tags' },
    { element: entries, field: 'tags' }
) %}
{% set tag2entries = craft.entries.relatedTo(tag2-token) %}

Entries tagged with “{{ tag.title }} and {{ tag-token2}}”

{% if tag2entries | length %}

        {% for entry in tag2entries %}

{{ entry.getLink() }}..

        {% endfor %}

{% else %}

No entries could be found with those tags.

{% endif %}
{% endif %}

{% if craft.request.getSegment(4) !='' %}
{% set tag3entries = craft.entries.relatedTo(tag3-token) %}

Entries tagged with “{{ tag.title }} and {{ tag-token2}} and {{tag-token3}}”

{% if tag3entries | length %}

        {% for entry in tag3entries %}

{{ entry.getLink() }}..

        {% endfor %}

{% else %}

No entries could be found with those tags.

{% endif %}
{% endif %}

I'm am not sure how to go about using the relatedTo() function to filter entries based on those 3 tag parameters in the URL.

Any insight on how to go about this?

Ideally, you'll use a dynamic route that can match any number of tags – negating the need to hard code the number of possible tag segments.

You can't pull this off using the Routes admin inside the CP, so crack open your /craft/config/routes.php file and add this:

return array(
    'tags/(.+)' => 'path_to_your_tags_template',
);

The above route can have any number of segments under /tags, but will require at least one. Be sure to delete any conflicting routes defined in Settings -> Routes!

Inside your tags template, you can get an array of all the tags in the URI like this (the |slice(1) part removes the first segment, i.e. "tags"):

{% set tagSegments = craft.request.segments|slice(1) %}

To pull the actual tags, you can do something like this:

{% set tags = craft.tags.slug(tagSegments) %}

Pulling it all together, here's how a (simplified) version of your template could look:

{# Get tags #}
{% set tagSegments = craft.request.segments|slice(1) %}
{% set tags = craft.tags.slug(tagSegments) %}

{# Get entries related to tags #}
{% set relatedTo = [] %}
{% for tagId in tags.ids() %}
    {% set relatedTo = relatedTo|merge([{
        targetElement: tagId,
        field: 'tags'
    }]) %}
{% endfor %}
{% if relatedTo|length > 1 %}
    {% set relatedTo = ['and']|merge(relatedTo) %}
{% endif %}
{% set entries = craft.entries.relatedTo(relatedTo) %}

{% if entries|length %}

Entries tagged with {% for tag in tags %}{{ tag.title }}{% if not loop.last %}{{ loop.revindex == 2 ? ' and' : ',' }}{% endif %}{% endfor %}

        {% for entry in entries %}

{{ entry.getLink() }}..

        {% endfor %}

{% else %}

No entries could be found with {{ tagSegments|length > 1 ? 'those tags' : 'that tag' }}.

{% endif %}


Change naming of sections in Craft Commerce CMS Is it possible to change the name of the of 'Products' to 'Projects' & Variants to 'Pledges'? I would like to use the Commerce CMS as a base to start from but need to be able to change certain naming of sections. Where can I do this?

You can do this using a custom translations file for Commerce and override some of the default translation strings.

Go to vendor/commerce/translation/[your-language].php
Review the instances of the word you want to translate (could be a lot)
In your project root, create a directory called translations
Inside of this directory create a directory with your language code (for me it's en).
Inside of the language directory create a file called commerce.php.

In commerce.php start with something like this:

<?php
  return [
     'Products' => 'Projects'
  ];

And keep going until you have all the strings you want translated added.


Order Users List by Last Entry Date I am trying to order a list of Users by the date of their last entry. order('postDate desc') works for entries of course, but I can't find a way to order the Users of those posts based on their latest post date. This is the code I am using now which orders the User by the date their account was created.

{# Grab all the Design Entries #}
{% set allDesigns = craft.entries.section('designs').limit(null).find() %}

{# Group by the authorId #}
{% set allDesignsByAuthorId = allDesigns|group('authorId') %}

{# Grab all of the users with the userIds in allDesignsByAuthorId #}
{% set designers = craft.users.group('designers').id(allDesignsByAuthorId|keys).order('dateCreated desc') %}

Thank you in advance for any help you can give!

I just noticed that you've posted an answer to your question already.

Your approach using the group filter is probably all you need, as the allDesigns array is sorted by postDate desc and by using the group filter you'll keep that sort order, your author IDs and the nested entries will both be sorted by the design post date.

To query the user models in the order of the IDs passed to the id param, you just need to add the fixedOrder param to your craft.users criteria model.

{# Grab all the Design Entries #}
{% set allDesigns = craft.entries.section('designs').limit(null).find() %}

{# Group by the authorId #}
{% set allDesignsByAuthorId = allDesigns|group('author.id') %}

{# Grab all of the users with the userIds in allDesignsByAuthorId #}
{% set designers = craft.users.group('designers').id(allDesignsByAuthorId|keys).fixedOrder(true) %}


Check if Assets Field Contains File of Type What’s the best way to check if an assets field contains a file of a certain type?

Something to the effect of: if assetsField.contains.file-of-type('image')

See kind in the docs: https://craftcms.com/docs/templating/assetfilemodel

I haven't tried it but I suspect it's something like this:

{% set file = assetsField.first %}
{% if file.kind == 'image' %}
  // blah blah
{% endif %}

There's also extension but kind is probably better here.


Corruption of Link to an Entry links within Rich Text field On a local government website running Craft CMS a lot of in-body links are effected with the Link to an Entry function within the Redactor editor. I have encouraged the content editors to use this instead a directly coded URL on the basis that if the linked-to entry changes location the link will still work. So far so good until sometime in the last week around 140 of these internal links corrupted.

So what used to be

Please see Schedule of fees and charges

became

Please see Schedule of fees and charges

and of course no longer work.

Understandably there is a lot of upset, both around the fact that access to important documents is no longer available, and that fact that someone has to find and repair 140 links, and then check that they were repaired correctly.

Can anyone offer any suggestion as to how this may have happened? All I can offer is that a Pending Task held up the task list for a while (I don't know how long). The task hadn't failed but after seeing no action on it for a day or so, I deleted it and this caused a backlog of tasks to run. While I don't know if there was any connection, but the timing of the start of the problem does match the running of the tasks.

The links have also been changed in all the entry revisions. At first this made me suspicious that they were never right, but as we run a link checker looking for broken links around once a month, or whenever a bigger set of edits have been made, I can confirm that this change happened recently. This points me back to the tasks.

It's entirely possible it was the stuck tasks depending on how the task originally failed, how many (and which ones) were backed up behind it and how many (and what kind of) changes were made on the site while the tasks were stuck.

Hard to know with 100% confidence, though.


Craft Commerce - Edit Complete Order Address from frontend We are trying to give our clients the ability to update an order's shipping address before the order has been actually shipped.

We've created a members area where they can list their orders and access them individually. When in an order, we have a link that loads a specific address form template e.g. /addresses/edit/{{order.shippingAddress.id}} but the address form doesn't load throwing the error Impossible to access an attribute ("id") on a null variable.

This exact same address edit form works fine when loading the address from the craft.commerce.customer.addresses model e.g. addresses/edit/{{ address.id }}. Having a look at the DB, we've found that the address if from the order model doesn't actually exists in the craft_commerce_customers_addresses table which would explain it.

Is there anything we've missed?

Cheers,
Alberto

When the order is completed a copy of the address is made which is created for that specific order, that explains why it doesn't show up in the customers_addresses table.

This is so that the address is unique to that order and can be edited by an admin without affecting the customers address book. Are you wanting customers to be able to edit that address after the order is complete?


Query Entry Using multiple custom Fields Element API I'm trying to return just one entry from Element API based on custom fields created?

return [
    'endpoints' => [
        'students.json' => [
            'elementType' => 'Entry',
                'criteria' => [
                    'studentNumber' => craft()->request->getPost('studentNumber'),
                    'email' => craft()->request->getPost('email'),
                    'section' => 'students',
                ],
                'transformer' => function(EntryModel $entry) {
                return [
                    'studentNumber' => $entry->studentNumber,
                    'email' => $entry->email,
                ];
            }
        ]
    ]
];

The Fields are studentNumber and email but it seems to be returning everything. Even when specifying first => true

Anybody point me in the right direction on this? I'd imagine I'm missing something obvious?

Even hitting the url students.json?studentNumber=001 is returning everything.

getPost() will search the request’s POST data, but you are setting the parameter values as query string params, so you should be using getQuery().

'studentNumber' => craft()->request->getQuery('studentNumber'),
'email' => craft()->request->getQuery('email'),


Custom Redactor Setting not Working Craft 2.6.2972

I've created a new redactor config called Basic Config and saved the json in craft/config/redactor based on this Strait Up Craft post. I then created a field and selected the correct config setting and added it to a channel.

However when I go to edit the entry it's not using my config setting as all the formatting options including code etc are there.

the json is:

{
    buttons: ['html','formatting','bold','italic','unorderedlist','orderedlist','link','image','video'],
    plugins: ['fullscreen'],
    formattingTags: ['p', 'blockquote', 'h3', 'h4', 'h5']
}

Not sure why code, h1, and h2 tags are available when clearly they are not in the above formatting options

Please advise.

That Straight Up Craft article is pretty old and based on the Redactor I API, I believe.

Pretty sure in Redactor II, formattingTags got replaced with either formatting or formattingAdd, depending on your needs.


Why does {{ user.getPhotoUrl(64) }} point towards storage/runtime and not to storage/userprofiles? I am trying to load user profile pictures (the Craft ones), but they don't load. The getPhotoUrl() seems to point to the wrong folder(?).

The profile images seem to be stored in the userprofiles folder by default

{% set users = craft.users %}

{% for user in users %}

{{ user }}

    {% if user.getPhotoUrl %}

    {% else %}

    {% endif %}

{% endfor %}

  2017/04/24 11:24:10 [error] [application] Tried to read the folder contents of /Applications/MAMP/htdocs/craft/storage/runtime/assets/sources/, but could not.
  2017/04/24 11:24:10 [error] [application] Tried to read the folder contents of /Applications/MAMP/htdocs/craft/storage/runtime/assets/tempuploads/field_3/, but could not.
  2017/04/24 11:24:10 [error] [application] Tried to read the folder contents of /Applications/MAMP/htdocs/craft/storage/runtime/assets/tempuploads/field_4/, but could not.
  2017/04/24 11:24:10 [error] [application] Tried to read the folder contents of /Applications/MAMP/htdocs/craft/storage/runtime/assets/tempuploads/user_1/field_3/, but could not.
  2017/04/24 11:24:10 [error] [application] Tried to read the folder contents of /Applications/MAMP/htdocs/craft/storage/runtime/assets/tempuploads/user_1/field_4/, but could not.
  2017/04/24 11:24:10 [error] [application] Tried to read the folder contents of /Applications/MAMP/htdocs/craft/storage/runtime/temp/uploads/userphotos/harry/, but could not.
  2017/04/24 11:24:10 [error] [application] Tried to read the folder contents of /Applications/MAMP/htdocs/craft/storage/runtime/temp/uploads/userphotos/remco/, but could not.

the console gives this error

GET http://localhost/cpresources/userphotos/remco/64/17492405_10212330524487585_7776812525773615973_o.jpg?x=UoEZXg1dH net::ERR_CONNECTION_REFUSED

I don't think the /Applications/MAMP/htdocs/craft/storage/runtime/assets/sources/ log entries are related to the request when getResourceUrl() is called.  Of if they are, they are elsewhere in the request and not as a direct result of calling getResourceUrl()`.

The error in the console seems like the one to investigate.  Based on net::ERR_CONNECTION_REFUSED, I'd check to make sure that craft/storage is recursively writable by PHP as a starting point.


Link to the product from the shopping cart Is it possible to link to the product from the shopping cart?
Something like {{ item.url }} within cart.lineItems

When using {{ product.url }} looping through craft.commerce.products I am getting a list with all product entries.

{{ item.purchasable.url }}

should do it.


Find Entries based on Field Values I have a set of events I want to query based on user-input date times.
How do I achieve something like this?

{% set entries = craft.entries.section('events').minScheduleDate('>=', 'now').maxScheduleDate('<=', 'now') %}

Where maxScheduleDate is a field for user to input date?

I believe this link solves your issue.
https://docs.craftcms.com/v3/date-time-fields.html#settings


Need help with dynamic image grid I am trying to make my image grid form out dynamically. I got it kinda working, But I need to figure out how to make my grid rows dynamic. I am kinda forcing it to start a new row at every 4th item right now, but dossent feel like the right way to do it.

This is my code:

 {% for entry in craft.entries.section('knapperForside').limit(50).find() %}

                    {{ entry.bilde }}

{{ entry.title }}

{{ entry.title }}

  {% endfor %}

To add a row at every 4th item, you can use twig's batch filter:

Twig Batch

Alternatively(a little more hacky) you can do {% if loop.index is divisible by(4) %} stuff {% endif %}. But batch is probably better.


What files does Craft store in "craft/storage/runtime/temp" What files does Craft store in craft/storage/runtime/temp folder.
And what is the purpose of it.
And how to stop it form getting huge.

The easiest thing is to look it up. Craft CMS is usually really self-explaining So when you take a look at your folders in craft/storage/runtime/temp you'll see the following

/assets <- for example cached thumbnails/preview icons and all those things
/cache
/compiled_templates <- templates that have cache tags, that should only compiled once... for example static pages that does not change that much
/HTML <-- mostly some json objects
/logs <-- well seems obvious
/state <-- Yii.CSecurityManager.validationkey a json object

The compiled_templates folder could become huge when you messed around with cache tags too much or if you have a really large site.
assets will grow when you insert many assets.

The purpose of this folder is to make Craft CMS faster because it does not have to generate HTML, thumbnails and so on with every page refresh, instead it uses already generated files.

How big is this folder for you? Does it require too much space?


Parse html on first and last occurrence of a matrix block type in a series of that same block type I'd like to wrap a series of block.type (images and description) in a div. So at the first iteration of this block type it needs to parse the start of the div. In the last iteration of this block type it needs to close the div.

I tried something like this, if there is a next block from the same type but no previous block, start the div and visa versa:

{% for block in entry.detailMatrix %}
    {% if block.type=="images" %}
        {% if block.next().type == 'images' and not block.prev().type == 'images'%}
            <div class="section" >
        {% endif %}
            {{block.image}}
            </div>
        {% if block.prev().type == 'images' and not block.next().type == 'images'%}
            </div>
        {% endif %}
    {% endif %}
{% endfor %}

You need to define the block previous/next variables outside of your for loop. Also you should check for the last element in the loop.

You can find a great working example on the happy lager demo website (https://github.com/pixelandtonic/HappyLager).

The relevant code part is here: https://github.com/pixelandtonic/HappyLager/blob/master/craft/templates/_includes/article_body.html.


How to find pros to take on maintenance/improvement of pre-existing sites built with Craft? I know of the Craft Professionals page on Straight Up Craft, but I'm curious if there is a more targeted way to find Craft pros who are willing and able to take on maintenance of pre-existing Craft sites.

This Q/A site seems obviously wrong for that. Are there other places to post requests or find a list of potential partners?

I hope this question is considered on-topic. Thanks!

As of this posting, there isn't another reliable source for Craft professionals. The CMS is so new compared to other systems that a 'base' of well-known, reliable companies/developers hasn't had the chance to form yet.

You could google and find a few, but they're spread out among developers that most likely wouldn't give you good results. I'd stick with the Straight Up Craft list, since you're at least sure they've seen/read about best practices on the Straight Up Craft site.

You could also post jobs to places like Authentic Jobs, and specifically ask for Craft experience, or Straight Up Craft's Job Board.


Craft query Matrix blocks in twig Is it possible to query elements of type MatrixBlock in Twig like other elements? You can get entries with

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

Is there something similar available for Matrix blocks?

Yes you can. craft.entries returns an object of type EntryQuery

There is a function matrixBlocks in the CraftVariable that returns an object of type MatrixBlockQuery

Both of them have nearly the same functionality  since they extend the ElementQuery

{% set allMatrixBlocks = craft.matrixBlocks.all() %}


Missing field validation on user account edit I've been implementing a user account page with Craft Commerce and copied over the template found here: https://docs.craftcms.com/v3/dev/examples/user-profile-form.html#simple-profile
The issue is though that the form doesn't seem to show any errors for individual fields, you just get the generic error message in the flash response.
If you take the example from the above link and enter an intentionally invalid email address (e.g a random string) theres no error response for the email field, just a generic "Couldn't Save User." response.
I've tried dumping out {{ craft.app.session.get('error') }}  in an attempt to see if theres some extra data and its just the above error.
Am I missing something here, or is it just not possible to get field based error messages out of Craft CMS / Craft Commerce?

Errors for the users/save-user action are recorded against the user object, not the session object. If the user is logged-out, the object is named user but if they are logged-in you must use currentUser.
Generally speaking you can retrieve errors from Yii objects in several ways, but for field-by-field errors, I prefer the simplicity of getFirstError() (You might also want to use getErrors() or getErrorSummary()). Here's what I'm using for each question:
{% set user = currentUser ?? user ?? null %}
...

    Email &bull;
    <input required id="email" type="email" name="email" value="{{ user is defined ? user.email }}">
    {% if user is defined and user.getFirstError('email') %}
        {% include '_partials/fieldErrors.twig' with { errors: user.getErrors('email') } %}
    {% endif %}

(You could of course use a macro instead of an include as many examples demonstrate).
fieldErrors.twig:

{% if errors %}

        {% for error in errors %}

{{ error }}

        {% endfor %}

{% endif %}


Loading dynamically-named classes in a plugin's service I'm in the process of building a plugin that'll have extensible 'Providers' to allow developers to build connections to other services. These 'Providers' will just be classes that are built to an interface I've included in the plugin. (It's currently in an 'interfaces' directory of my plugin; I'm not sure about the best-practice for where interfaces should be stored.)

My question: What I'm having trouble with is how to include the developer's Provider class when I don't know what the name will be. Here's what I'm doing now:

require_once(CRAFT_PLUGINS_PATH . 'location/providers/' . $this->settings->provider . 'Provider.php');

$provider = '\Craft\\' . $this->settings->provider . 'Provider';

return new $provider();

$this->settings->provider just returns the 'handle' of their Provider, like sampleService. The file they place in the providers directory would be sampleServiceProvider.php, in that case.

If something doesn't make sense, I'll gladly clarify. Any help is greatly appreciated!

Rather than assuming that the providers will live in a specific location, I'd be inclined to implement a custom hook, which allows third party plugins to register a new provider.

This also allows third parties to do any initialisation of their provider, prior to handing it to you.

For example, your plugin could do something like this:

$providers = craft()->plugins->call('registerProviders');

And a third party could then do something like this, in its main plugin file:

public function registerProviders()
{
    $instance = new MyProvider('custom', 'dependencies');

    return ['myProvider' => $instance];
}

Greatly simplified, but hopefully you get the idea.


Order by fields after searching I need to order the results of a search query after I got back the results. The reason to do this is that I want to make different lists on the same page (with the same results) and I dont't want to search over and over again just to reorder te results. Can I do that? So basically I do this:

{% set results =  craft.entries.section('player').search('team:"thenameoftheteam"') %}

What I want to do with this result is:
loop

through the results and order them by playerPosition
show the longest player (lengths are in the field playerHeight)
show the oldest player (birth dates are in the field playerBirth)

I could run this query 3 times and order by a different field each time, but I don't think that's the way to go.

Not really feasible without a plugin – fortunately, there's the excellent SuperSort:

{% set results =  craft.entries.section('player').search('team:"thenameoftheteam"') %}

{% set resultsByPlayerPosition = entries|supersort('sortAs', '{playerPosition}') %}
{% set resultsByPlayerHeight = entries|supersort('sortAs', '{playerHeight}') %}
{% set resultsByPlayerBirth = entries|supersort('sortAs', '{playerBirth}') %}

If you need the sorted results in the opposite order, you can just apply the |reverse filter, i.e.

{% set resultsByPlayerHeight = entries|supersort('sortAs', '{playerHeight}')|reverse %}

If e.g. playerPosition is a relational field (a category, perhaps), you'll need to do something like this:

{% set resultsByPlayerPosition = entries|supersort('sortAs', '{{ playerPosition.first.title }}') %}


Registering events for a specific feed in Feed Me I'm working with Feed Me to run several feeds, bringing in multiple Entry types. I need to do some additional preparation work via an EVENT_AFTER_PARSE_FEED handler, which works well when I only have a single feed, but fails when I add a second feed.
I want to run the event handler for Feed A, but not for Feed B: Is there a simple way of specifying the feed when registering the event handler, or querying the event name inside the event handler?

it seems parse feed event only provide url and response. i don't know about specifying additional data for feed but some other solutions are:

add feed name as query string to feed url (if it is url and you have have control over it) and parse url on EVENT_AFTER_PARSE_FEED to detect feed name

Event::on(DataTypes::class, DataTypes::EVENT_AFTER_PARSE_FEED, function (FeedDataEvent $event) {
   $url = parse_url($event->url);
   $path = $url['path'];
   $query = $url['query'];
 });

using EVENT_BEFORE_PROCESS_FEED and changing feed data before processing

<?php
use craft\feedme\events\FeedProcessEvent;
use craft\feedme\services\Process;
use yii\base\Event;
Event::on(Process::class, Process::EVENT_BEFORE_PROCESS_FEED, function(FeedProcessEvent $event) {
    if ($event->name == 'feed A') {
      foreach ($event->feedData as $key => $data) {
        $event->feedData[$key]['title'] = 'item' . $key; //changing data attribute of each data
      }
    }
});
?>


Send activation mail from front end I am building a site where all the content (and users) are being managed using the front end. The site owner needs to invite customers to the site but would like to control the time when that customer receives his activation mail. Is that possible without having access to the control panel?

So ideal journey would be:

The site owner creates new customer via the front end (no activation
mail sent)
The site owner does stuff on the site (preparing content
for the customer)
The site owner pushes a button on the customer’s
profile which fires off the activation mail to the customer
Profit

I could just have my client send out a password reset mail (?) but that seems a bit hack-ish and raises security concerns since that form needs to be publicly available.

There are no methods available which are giving me access to the verification code so that route wasn’t successful either. Is there a way to grab that code and serve it to the template? That would do it for me.

Is there another way to make that happen? It might actually be easy to solve. I would be grateful if someone could push me in the right direction.

I'll focus on the "sending an activation email from the front end" part of your question, since that seems to be the crux of it:

You'd have to write a very simple, custom plugin. For instant success, scaffold your plugin using the Plugin Factory. Under Plugin Components, enable Controllers.

Unzip and install your plugin.

In the Controller class, add something like the following method:

public function actionSendActivationEmail()
{

    // Get the user from the `id` URL parameter
    $user = craft()->users->getUserById(craft()->request->getParam('id'));

    if ($user) {
        // Send the activation email
        craft()->users->sendActivationEmail($user);
    }

    // Redirect back to the page we came from
    $this->redirect(craft()->request->getUrlReferrer());

}

To create a link to this controller action in your template, do something like this:

Send activation email


After migration to staging, requesting any page other than Home results in 500 error I've developed my site locally and now need to migrate to staging. The Home page is displaying correctly so I would assume that a database connection is not the issue. But requesting {staging_url}/{any_segment} results in a 500 Internal Server error.

Here I'm setting the environment in index.php:

if (substr($_SERVER['SERVER_NAME'], -strlen('.dev')) === '.dev') {
    define('CRAFT_ENVIRONMENT', 'development');
} else if ($_SERVER['SERVER_NAME'] == 'staging.blah.com') {
    define('CRAFT_ENVIRONMENT', 'staging');
} else {
    define('CRAFT_ENVIRONMENT', 'production');
}

Here's my general.php:

return array(
    '*' => array(
        'extraAllowedFileExtensions' => 'vcf',
        'omitScriptNameInUrls' => true,
    ),
    'development' => array(
        'devMode' => true,
        'siteUrl' => 'http://blah.dev',
        'environmentVariables' => array(
            'baseUrl' => 'http://blah.dev',
        ),
    ),
    'staging' => array(
        'siteUrl' => 'http://staging.blah.com',
        'environmentVariables' => array(
            'baseUrl' => 'http://staging.blah.com',
        ),
    ),
    'production' => array(
        'siteUrl' => 'http://blah.com',
        'environmentVariables' => array(
            'baseUrl' => 'http://blah.com',
        ),
    ),
);

This is solved by this thread.

The common thread here is Rackspace Cloud Sites, which apparently needs a RewriteBase / instruction in .htaccess.

Thanks @maxx and @christopher-healey


Solspace Freeform: Looping through Radio group options in template Using Solspace Freeform, I am trying to hardcode a radio gorup and its options in to a template. My effort is below but its not working

{# get the radio group field #}
{% set interestedIn = form.get("interestedIn") %}
{# Loop through the radio options #}
{% for option in interestedIn %}
<input type="radio" id="form-input-{{ interestedIn.handle }}" name="{{ interestedIn.handle }}" value="email">
<label for="form-input-{{ interestedIn.handle }}">Email</label>
{% endfor %}

To manually generate multi-option fields like radios, your code would look something like this:

{% set yourFieldHandle = form.get("yourFieldHandle") %}

{{ yourFieldHandle.label }}
{% for option in yourFieldHandle.options %}

         <input type="radio" name="yourFieldHandle" value="{{ option.value }}" {{ option.checked ? "checked" }} />
         {{ option.label|raw }}

{% endfor %}


Transaction Error Message in Template When a payment is made and something is incorrect e.g. card number is invalid, expiry date is in the past etc. The form just refreshes with no warning / notification of what's happened.

I've noticed that this message is stored in the CMS on each order, under the "Message" column (e.g. Card Has Expired)

Is there a way to output this message in to the template when the error occurs? Even on the example templates it does this issue.

The error messages are returned to the template as flash messages.

Handling those is documented here:
https://craftcms.com/docs/templating/craft.session

One thing to watch out for is that flash messages are only available once, and are by default 'consumed' when you retrieve them:

{{ craft.session.getFlashes() }}
...some other template code here....
{{ craft.session.getFlashes() }}

...if there is a message, the first tag will output it, but the second one won't as it has been consumed.  So best to set the message to a variable if you want to save it, or you can call craft.session.getFlashes(false) to stop the message from being consumed if you'll want to use it later in your template.

During development it is worth having some code to always display the flash messages at the top or bottom of your main layout template, so you can see them as they are occurring, and thus anticipate what you might need to handle.  I use something like this:

    {% if craft.config.devMode and (craft.session.hasFlash('notice') or craft.session.hasFlash('error')) %}

    {% set noticeFlash = craft.session.getFlash('notice')|join('|') %}
    {% set errorFlash = craft.session.getFlash('error')|join('|') %}

    Notice: [{{  noticeFlash }}]
    Error: [{{  errorFlash }}]

    {% endif %}

Now, if you're doing your payment operations via ajax, things are a little different...that case you'll get back results in json.  If there is an error, it will look something like:

{"error":["Credit Card Invalid"]}

So in your js you would check for the lack of response.success and then look for this error message.


How can you check if "public user registration" is turned on or off on the front-end? I'm trying to make a rather bullet proof front-end template that can toggle a sign up link based on if public registration is enabled or not.

Is there a way I can query to see if the system currently has public registration turned on from the front-end?

You can write a plugin that has a Template Variable that exposes Craft's SystemSettingsService->getSettings() method like so:

public function isPublicRegistrationEnabled()
{
    return craft()->systemSettings->getSetting('users', 'allowPublicRegistration');
}

You'd call it from the template via:

{% if craft.myAwesomePlugin.isPublicRegistrationEnabled() %}
    Enabled!
{% endif %}


Add / Update context from macro I'm trying to update the context from within a macro. Is this possible at all? I'm pretty close with the below code.

The var_dump within the below function shows the updated context. But when doing a {{ dump(_context|keys) }} after the macro call the context is unchanged.

Any ideas, much appreciated.

<?php
namespace Craft;

class TwiggedTwigExtension extends \Twig_Extension
{
  public function getName()
  {
    return 'Twigged';
  }

  public function getFunctions()
  {
    return array(
      'addVar' => new \Twig_SimpleFunction('addVar', array($this, 'addVar'), array('needs_context' => true)),
    );
  }

  public function addVar($context, $str, $val)
  {
    $context['context'][$str] = $val;
    var_dump(array_keys($context['context']));
  }
}

So I took another approach to my problem and ended up creating a plugin variable allowing me to set data inside a macro and have it accessible in the template. It's not complicated and does the trick.

class MyPluginVariable
{
  /**
   * Store data for use within both
   * templates and macros. Easy way around
   * macros having their own context
   * @var [Array]
   */
  private static $store = [];

  /**
   * Set data in storage array
   * @param [String] $key
   * @param $value
   */
  public function set($key, $value) {
    self::$store[$key] = $value;
  }

  /**
   * Retrieve data from storage array
   * @param  [String] $key
   */
  public function get($key) {
    return self::$store[$key];
  }
}

To set data you simply call {% do craft.MyPlugin.set('myVar', true) %} and to retrieve it {% set myVar = craft.MyPlugin.get('myVar') %}


Commerce Discount: spend $X, get product free I want to make a promotion where at a certain cart total threshold, if a particular product is in the cart, it would be free. (e.g. spend $50 and get a free mug).

Trying to sketch out the best way to achieve this.

It seems like if a discount had a a "Cart total" condition, I could pull it off w/o a custom adjuster. It has "Purchase Total", but that says only applies to the matching products, not the entire cart. In this case I would want to select the mug in the "products" condition, and set the percent discount to 100% (I think).

Any ideas where to start?

I don't think avoiding an adjuster or plugin approach here really gains you anything much and it probably creates potential issues - it will likely just make the discount rules confusing as you can't really document the special conditions anywhere on those rules etc (and experience shows over time editors are likely to forget the special conditions and make mistakes with these sorts of hidden logic approaches).

Personally I would approach this by listening to onAddToCart and onRemoveFromCart

https://craftcommerce.com/docs/events-reference#commerce_cart.onaddtocart
https://craftcommerce.com/docs/events-reference#commerce_cart.onremovefromcart

In each of these I would call a function that inspects the order total and either adds the free item (if not already in the cart) if the total is high enough, or removes it if it is present but the order total slips below the desired total.  And you'd want to look at the item total, not the cart total presumably.

To make it editor friendly, I would also add a control panel page that allows the editors to set the cart total threshold and the free product they get if the threshold is exceeded.


if entry has specific category, show specific html block I have entries, which can have several categories.
These categories are in different categorie groups.
Now if i show an entry page, i want to display i certain html block
based on a specific category, the entry has or not.
i tried this, but its not working, i think i get the relatedTo thing wrong:
//i loop through all the categories in my group

{% for category in craft.categories.group('catGroup1') %}

//the i go to the section my entries are in and relate that to the categories i want to filter

{% set categoryListings = craft.entries({
  section: 'kelims',
  relatedTo: [
    { targetElement: category, field: 'filterThisCategory' }
  ]
}) %}

//if the entry has this category

{% if categoryListings|length %}

  display some html block

{% endif %}
{% endfor %}

craft.entries() returns an EntryQuery. You must then execute the query with one of those methods:

one()
all()
count()
exists()

In your case, I think .exists() is the best choice: {% if categoryListings.exists() %}
Edit: You may also have to execute your category query with {% for category in craft.categories().group('catGroup1').all() %}. See https://craftcms.com/docs/3.x/categories.html#querying-categories.


How do you download multiple plugins vis Command Line? Coming from Drupal, we often use drush to download modules (plugins) and install them. For example this is what we might do using drush:
drush dl bootstrap mailchimp stripe-php
This would download the modules (plugins), then we'd have to install/enable them.
On CraftCMS the ./craft utility is great for installing, but not downloading. I know you can use composer require vendor/plugin-name — but that requires me to know the vendor name as well. This came up when I was applying a project.yaml file to a fresh CraftCMS install and it notified me that a bunch of plugins were not installed — but only gave me the plugin-name for each — meaning I would have to look up the vendor -or- search for each in the plugin store and install.
Is something like the drush dl command available with the ./craft cli utility at this time?

You can use the plugin/install command for the ./craft cli utility, I'm not sure if you're aware of this:
https://craftcms.com/docs/3.x/console-commands.html#plugin-install
You'll need to know the plugin's handle, but that's all you need. I've never tried specifying multiple plugins in the one command, but that's an easy one to test.
Now, as to why you're needing this is the real question. If you've got your workflow correct, you shouldn't need to be manually downloading/installing plugins with the cli anywhere other than local dev. Project config (if you're using it) and composer should handle all of this. Typically, a basic deployment is as follows:
composer install
./craft migrate/all
./craft project-config/apply

I guess it would help to know why you're downloading and not installing, and in which kind of environment this is happening.


Triggering the start of a task from a CRON job I have a site setup which is for subscribers only. I have added a user expiry date field to the users section and everything is working perfectly on the front end in that I can restrict access to accounts that have already passed their expiry date.

However I need to send notification emails to accounts that expire today or will expire in 7 days time.

I am using the mailer plugin in combination with a basic plugin I have made. I have setup a basic plugin with a controller which calls the following function from the plugins service:

public function sendNotificationEmail()
{
    //Create an EmailModel
    $email = new EmailModel;

    //Set the necessary attributes
    $email->fromName = 'Joe Blogs';
    $email->fromEmail = 'joe.blogs@example.com';
    $email->subject     = 'Email subject';
    $email->htmlBody    = 'The message';

    //RecipientsModel
    $recipients = new Mailer_RecipientsModel();
    $recipients->recipients = array(
        array(
            'to' => 'jane.doe@example.com'
        )
    );

    if( $recipients->validate()){
        //Create mailer
        craft()->mailer_main->newMailer($recipients, $email); //This will start the MailerTask
    }

}

As you can see, at the moment I'm just sending a single test email each time. Everything works as expected but I've noticed that the task does not get triggered until I refresh the CP. This is a problem in my case, I think, because I want to trigger everything from a CRON job.

If anyone has any solution as to how to automatically trigger the task or if there are any alternative methods to solve this problem, I'd love to here them :)

btw, the reason I went down the task route was that the system could be sending to 100s of email addresses at a time and I didn't want to be (a) treated as spam or (b) get a timeout from the request

Everything you need to manage tasks is in the TasksService, so you should be able to just use that in your controller action to kick off any pending tasks, using something along the lines of:

if (!craft()->tasks->isTaskRunning())
{
    $task = craft()->tasks->getNextPendingTask();

    if ($task)
    {
        craft()->tasks->runPendingTasks();
    }
}

If you have a look around craft/app/services/TasksService.php you'll see you can also grab and run tasks by type which might be useful in this situation.


Unable to sort large number of blocks in Matrix field in CP and template I have about 145 blocks in a single Matrix. If I try and re-arrange (drag&drop) the first few blocks, and then hit save, all is well. However, trying to re-arrange the last few blocks doesn't save at all, reverting the order as soon as I refresh.

I've pumped the php.ini settings (upload_max_filesize=128M, post_max_size=256M
,max_input_vars=4000) and set the block limit in CP to 200 so that shouldn't be the issue.

I'm also not getting a logged error.

Does this ring a bell with anybody?

This is because Craft stores the sortOrder values in the database with a MySQL column type of tinyint that happens to be signed, which means it can store a range of -128 to 127.

Aside from the fact that negative sort orders don't make much sense, that means if you have 127 or more Matrix blocks to sort, things will stop working as expected.  Because 127 things to sort ought to be enough for anyone, right?

Regardless, in the next (post 2.5.2765) release, we've changed all sort order column in the database to be unsigned smallints, which means they can store a range of 0 to 65535.


How do I add the Categories and tags related to each entry? This is my basic entry layout and I just want to display the linked category and tag names as indicated…

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

            {{ entry.postDate | date("d") }}
            {{ entry.postDate | date("M") }}

            {{ entry.title }}

Category: Category Name

Tags: Tag 1, Tag 2, Tag 3

Share

        {{ entry.body.getPage(1) }}
        Read more

{% endfor %}

Supposing your categories and tags fields are named, respectively, newsCategories and newsTags, you could do the following for the categories:

{% for category in entry.newsCategories %}
    {{ category.title }}
    {% if not loop.last %},{% endif %}
{% endfor %}

And for the tags:

{% for tag in entry.newsTags %}
    {{ tag.title }}
    {% if not loop.last %},{% endif %}
{% endfor %}

This code is untested, but I think this should more or less do what you want to achieve.


Globals (template tags) in entries? Is it possible to use template tags within an entry? Specifically, I'd like to use Globals I've set up within an entry, so I can manage a brand name globally.

You can, using reference tags, but unfortunately they only work in plain text fields:

Reference tags in rich text fields parse and converted on save


Craft 2 to Craft update - timeout when updating database I am trying to update a site from Craft 2 to Craft 3. I first set up a new server, installed Craft 3, copied over config settings from the original site, and moved over a copy the original database. I have done this successfully on quite a few Craft 2 to 3 updates with no problem.
After pointing my browser to mysite/admin I got the prompt to finish up / update the database as expected, but the process timed out. The sql file I moved over is about 8mb, not especially large. In any case, is there any way I can run the database update process from the console in order to avoid the timeout issue?

The console command you are looking for is:
./craft migrate/all


Plugin not showing up in CP I'm attempting to install the Contact Form plugin. I believe that I've uploaded the correct folder to the correct location, but it's not showing up in the control panel. I'm relatively new to Craft, so this is the first plugin that I've installed.

This is my folder structure:

I've seen a couple questions that indicate that the most common problem is improper capitalization on the plugin folder. However, as you can see, mine is all lower case.

I'm building this site on a Linux localhost and I've even gone so far as to chmod 777 plugins -R just to be sure it's not a permissions issue.

I've made sure to clear caches after every change, but no matter what I do I can not get the plugin to show up in the CP.

What else should I look at to diagnose and fix this?

Well, I deleted the whole contactform folder, downloaded it again, and added it back to the plugins folder. Just to be safe, I ran service httpd restart. After that, it showed up immediately.

I can't be sure, but I'm assuming that there was just something wrong with the originally downloaded files.

I hope this helps someone else in the future.


Craft 3.5.1 CLI Update Error: Failed to instantiate component or class "yii\shell\Bootstrap" when I try to update Craft via CLI to 3.5.1. I get the following error:
Failed to instantiate component or class "yii\shell\Bootstrap
in /vendor/yiisoft/yii2/di/Container.php:449

Stack trace:
#0 /vendor/yiisoft/yii2/di/Container.php(374): yii\di\Container->getDependencies()
#1 /vendor/yiisoft/yii2/di/Container.php(159): yii\di\Container->build()
#2 /vendor/yiisoft/yii2/BaseYii.php(345): yii\di\Container->get()
#3 /vendor/yiisoft/yii2/base/Application.php(294): yii\BaseYii::createObject()
#4 /vendor/craftcms/cms/src/console/Application.php(72): yii\base\Application->bootstrap()
#5 /vendor/yiisoft/yii2/base/Application.php(273): craft\console\Application->bootstrap()
#6 /vendor/yiisoft/yii2/console/Application.php(124): yii\base\Application->init()
#7 /vendor/craftcms/cms/src/console/Application.php(58): yii\console\Application->init()
#8 /vendor/yiisoft/yii2/base/BaseObject.php(109): craft\console\Application->init()
#9 /vendor/yiisoft/yii2/base/Application.php(206): yii\base\BaseObject->__construct()
#10 /vendor/yiisoft/yii2/console/Application.php(89): yii\base\Application->__construct()
#11 /vendor/craftcms/cms/src/console/Application.php(48): yii\console\Application->__construct()
#12 [internal function]: craft\console\Application->__construct()
#13 /vendor/yiisoft/yii2/di/Container.php(400): ReflectionClass->newInstanceArgs()
#14 /vendor/yiisoft/yii2/di/Container.php(159): yii\di\Container->build()
#15 /vendor/yiisoft/yii2/BaseYii.php(365): yii\di\Container->get()
#16 /vendor/craftcms/cms/bootstrap/bootstrap.php(245): yii\BaseYii::createObject()
#17 /vendor/craftcms/cms/bootstrap/console.php(51): require('/var/www/client...')
#18 /craft(21): require('/var/www/client...')
#19 {main}

does anyone know what to do about it?

This ended up being a bug we were able to work-around on our side via our web service calls.
If you restore your site from a pre-update attempt database backup and composer.json file, then attempt the update again, it should go through fine.


Is it possible to limit users to adding/editing entries in specific categories? I'm building a site that regroups several properties, and I'd like each manager to edit content in his property only. All properties use the same templates and share content between each other.

I first tried to create a new section for each property, but it occurs to me that it would be much simpler to have a "room" and "facilities" section (and templates), and then divide everything using categories.

However at the moment user permissions only allow a user to add any category to their entries, which could lead to mistakes if users are not careful.

Would it be possible to limit users to a single category, so that user1 can only edit entries in category1 and user2 in category2? Any tips on how to approach this?

Thanks in advance

Entry permissions are sort of an all or nothing thing. If they can publish entries, they can publish all entries or just their own entries. The tricky part of this kind of permission is that Craft doesn't know if a category field will be on a particular entry type.

A possible way to make this work is to create a custom plugin that fires the entries.onBeforeSaveEntry event, and checks each user's category access with the entry's categories. Granted, you run into the issue of them being able to remove the category to remove any problems.

A second option is to give them a special front-end portal area that will let them edit entries, and let you filter those entries to what they can edit. You will also then be able to omit fields that you don't want them to edit (including the categories that prohibit their access).


Configuring Element API 1.2.1 Plugin I'm running Craft CMS 2.6.2972 so I had to use the older Element API plugin.

I have downloaded the zip and then copied just the "elementapi" file in the zip to the plugin's folder.

Then I installed the plugin in the admin panel.

Then I made a file craft/config/elementapi.php with the contents

<?php
namespace Craft;

return [
    'endpoints' => [
        'news.json' => [
            'elementType' => 'Entry',
            'criteria' => ['section' => 'news'],
        ]
    ]
];

But if I hit the URL <myserver>/api/news.json then I get the following error:

2017/05/12 17:31:47 [error] [exception.Craft\HttpException.404] exception 'Craft\HttpException' in C:\inetpub\wwwroot\craft\app\controllers\TemplatesController.php:59 Stack trace:
#0 [internal function]: Craft\TemplatesController->actionRender('api/news.json', Array)
#1 C:\inetpub\wwwroot\craft\app\framework\web\actions\CAction.php(109): ReflectionMethod->invokeArgs(Object(Craft\TemplatesController), Array)
#2 C:\inetpub\wwwroot\craft\app\framework\web\actions\CInlineAction.php(47): CAction->runWithParamsInternal(Object(Craft\TemplatesController), Object(ReflectionMethod), Array)
#3 C:\inetpub\wwwroot\craft\app\framework\web\CController.php(308): CInlineAction->runWithParams(Array)
#4 C:\inetpub\wwwroot\craft\app\framework\web\CController.php(286): CController->runAction(Object(CInlineAction))
#5 C:\inetpub\wwwroot\craft\app\framework\web\CController.php(265): CController->runActionWithFilters(Object(CInlineAction), Array)
#6 C:\inetpub\wwwroot\craft\app\framework\web\CWebApplication.php(282): CController->run('render')
#7 C:\inetpub\wwwroot\craft\app\framework\web\CWebApplication.php(141): CWebApplication->runController('templates/rende...')
#8 C:\inetpub\wwwroot\craft\app\etc\web\WebApp.php(290): CWebApplication->processRequest()
#9 C:\inetpub\wwwroot\craft\app\framework\base\CApplication.php(185): Craft\WebApp->processRequest()
#10 C:\inetpub\wwwroot\craft\app\index.php(62): CApplication->run()
#11 C:\inetpub\wwwroot\public\index.php(14): require_once('C:\\inetpub\\wwwr...')
#12 {main} REQUEST_URI=/api/news.json
---

What might be wrong?

This is running on IIS and I've added .json to the mime types for the site.

This error is the same error as an unhandled link/route. So seems like it's not picking up the config or I have the wrong URL. The plugin did install ok.

If you're hitting /api/news.json in the browser, you'd want to define the endpoint as 'api/news.json' as well.  i.e.

<?php
namespace Craft;

return [
    'endpoints' => [
        'api/news.json' => [
            'elementType' => 'Entry',
            'criteria' => ['section' => 'news'],
        ]
    ]
];


Using Conditionals in Title Format I've got a new channel for Authors where there are 3 fields:

firstName
middleName
lastName

and I'm using these fields to generate the Title of the channel entry. However I would like to add a conditional around middleName so that it isn't used if empty and I can avoid have double space between first and last name.

How can I do this?

The title field supports ternary syntax conditionals. You could do that like this:

{firstName} {middleName|length ? middleName ~ ' '}{lastName}

That says "if middleName has length, print it out, and append a space with ~.

Also part of the ternary syntax is the "else" statement, which looks like the below. This is the code I use for most of my asset alt texts for accessibility.

{{ asset.assetAltText|length ? asset.assetAltText : asset.title }}

If asset.assetAltText has a length, use that. Otherwise use the asset title as the alt text


Updating Craft to 3.3.19 gives 503 error only for logged-out users Working on an outdated client project and updated craft on staging from 3.0.30.1 to 3.3.19

I'm getting 503 errors (site temporarily unavailable) when trying to visit any page on the site -- but only for logged out users. Once I log in, everything works normally.

I've checked that the DB connection is working correctly. When I performed the updates, I got a dialog from Craft to update my database and performed it so the schemas should be up to date.

The stack trace shows where the error occurred but I'm stumped as to why it's happening or how to fix it:

From vendor/craftcms/cms/src/web/Controller.php (starts line 157):

        if (!($test & $allowAnonymous)) {
            // If this is a CP request, make sure they have access to the CP
            if ($request->getIsCpRequest()) {
                $this->requireLogin();
                $this->requirePermission('accessCp');
            } else if (Craft::$app->getUser()->getIsGuest()) {
                throw new ServiceUnavailableHttpException();
            }

The exception at the bottom of this check is what is thrown and causing the error, but why would a visit to the homepage be detected as a CP request? I'm assuming CP means control panel.

Any ideas?

I've found this question through search.

I did not perform any update which broke my controllers, but I was unable to access them publicly.

My solution was adding $allowAnonymous = true; to my controller:

class MyController extends \craft\web\Controller
{
    public $allowAnonymous = true;
}


Display a user's selected checkbox options for a category field type in a front-end Edit Profile form I have a user field called "designOptions" that is a Categories Checkbox field type. I have this field in the Edit Profile front-end form so that the user can see the saved options that they had selected previously (if any) and then change or add to those selections in the Edit Profile form. I am having a hard time finding anything in the documentation or SE about how to display all of the user's category checkbox options while displaying the options that are already selected in their account for that field. This is what I have so far, but it is checking all category options instead of just the 4 that the user has selected - likely because the length conditional is only looking at whether this field has 'any' value and not checking the value of each option.

I would appreciate any guidance you can give on the best way to do this. :)

Thank you!

{# Grab all categories in the group and set variable. #}
{% set categories = craft.categories.group('designCategories') %}

{# Grab the categories that the user already selected #}
{% set userOptions = user.designOptions %}

{# Display all category checkboxes in the form, with the logged in user's saved selections already checked.#}
{% for category in categories %}
    <input type="checkbox" id="designOptions" name="fields[designsOptions][]" {% if userOptions | length %}checked{% endif %} value=" {{ category.id }}"> {{ category.title }}</input>
{% endfor %}

Try something like this (completely untested):

{# Grab all categories in the group and set variable. #}
{% set categories = craft.categories.group('designCategories') %}

{# Grab the categories Ids that the user already selected #}
{% set userOptionIds = user.designOptions.limit(null).ids() %}

{# Display all category checkboxes in the form, with the logged in user's saved selections already checked.#}
{% for category in categories %}
    <input type="checkbox" id="designOptions" name="fields[designsOptions][]" {% if category.id in userOptionIds %}checked{% endif %} value=" {{ category.id }}">
        {{ category.title }}
    </input>
{% endfor %}


Can't get past the install on local MAMP Pro install... "Oops screen" Can't seem to get past the install screen for some reason or other... I fill in the relevant information, it starts to install then I get the OOPS screen... I looked in the log and I'm seeing the following ...

[Mon May 11 13:25:08 2015] [error] [client ::1] FastCGI: comm with server "/Applications/MAMP/fcgi-bin/php5.3.29.fcgi" aborted: idle timeout (30 sec), referer: http://travelexperience/admin/install
[Mon May 11 13:25:08 2015] [error] [client ::1] FastCGI: incomplete headers (0 bytes) received from server "/Applications/MAMP/fcgi-bin/php5.3.29.fcgi", referer: http://travelexperience/admin/install

But I have no idea what's up...

UPDATE

Okay I'm getting the following error in the craft log...

2015/05/11 12:48:19 [warning] [application] Skipping record /sites/travelexperience/craft/app/records/BaseRecord.php because it’s abstract or an interface.

See this answer for how to work around the MAMP incomplete headers bug: https://craftcms.stackexchange.com/a/6573/57

The [warning] [application] Skipping record... log entry isn't an error at all and is completely normal to see during installation.


Sprout Forms notification test giving me an internal server error We have set up this particular Craft CMS site with smtp details and when testing from the Settings > Email page it works fine.
We've installed Sprout Forms and created some forms - all seems pretty good, but when we test a notification email from within the Sprout Forms admin area we just get an 'internal server' error. No specifics at all. just 'Internal Server error'.
Anybody been through this before?

As the original poster reported in the comment above. This "looks like a completely different issue unrelated to email."


Issues with returnJson not returning html? Im running in to issues with returnJson not returning html or just returning and empty object:

$userHtml = craft()->logic->renderSiteMacro('_macros/elements', 'listing', $args);

$this->returnJson(array(
     'success' => true,
     'existing' => $userHtml
));

The return JSON is always:

{"success":true,"existing":{}}

I have double checked the html output exists and the issue persists:

Whether returning a simple string or large chunk of html
And with and without single quotes
When renderSiteMacro functions runs the code through the raw filter and not

It appears whitespace was the cause here, just running a quick whitespace filer on the return value resolved the issue:

$userHtml = craft()->logic->renderSiteMacro('_macros/elements', 'listing', $args);

$userHtml = preg_replace('~>\\s+<~m', '><', $userHtml);

$this->returnJson(array(
    'success' => true,
    'existing' => $userHtml
));


How to merge SEOmatic object in Craft 3? I'm using SEOmatic plugin in craft cms 3 and I need to set the seoTitle in my template but can't figure out how to do it...

I know that in Craft 2, it was possible to merge the seomatic variable. I tried something like this :

{% set seomatic = seomatic|merge({
    meta: {
        seoTitle: 'my title'
    }
}) %}

But it doesn't work because the merge filter only works with arrays or "Traversable", and I got object... I'm kind of stuck with this issue.

Has anyone ever managed to make a merge of seoTitle?

Based on the SEOmatic docs, something like this should do the trick nicely:

{% do seomatic.meta.seoTitle("my title") %}


How do you tell Craft to change post directions from row-to-row? I have a grid.  The pattern is:

**Row 1** = 1 x featured post and 2 x vertical posts.  (The feature is the equivalent of 2 vertical posts.)
**Row 2** = 2 x horizontal posts  Row 2 starts with the 4th most recent post.
**Row 3** = 4 x vertical posts
**Rows 4-n** repeat Row 2 and Row 3...

I have experimented with {% if loop.index is divisible by(2) %}stuff{% else %}other-stuff{% endif %} to switch between the horizontal and vertical alignments.

So, this is a 2 part question.

How do I pull the 2nd and 3rd most recent posts to populate the 2 vertical posts in Row 1?

I am already calling the featured post using {% for post in craft.entries.section('posts') %}{% if loop.first and craft.request.pageNum == 1 %}...

Next, how do I then tell Craft to populate 2 horizontals in Row 2 and then switch to 4 verticals in Row 3?   I assume its best to separate step #1 from step #2 which would require Row 2 to start with 4th most recent post

You could do multiple "for" loops on the first craft.entries request using limits and offsets:

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

{# ROW ONE #}
{% for post in posts.limit(1) %}
   html stuff for first post
{% endfor %}

{% for post in posts.limit(2).offset(1) %}
   html stuff for 2nd and 3rd posts skipping 1
{% endfor %}

{# ROW TWO #}
{% for post in posts.limit(2).offset(3) %}
   html stuff for 4th and 5th posts skipping 3
{% endfor %}

etc.

For the switching back and forth between horizontal and vertical, you can set up a couple of macros and call them where needed(or includes for that matter, lots of ways to skin this cat).

{% macro vertical(url, title) %}

    {{ title }}

{% endmacro %}

{% macro horizontal(url, title) %}{# different html #}

{{ title }}

    Learn More

{% endmacro %}

and then where you need them in the first part of your question above:

{% for post in posts.limit(2).offset(3) %}
   {{ _self.vertical(post.url, post.title) }}
{% endfor %}

and

{% for post in posts.limit(2).offset(3) %}
   {{ _self.horizontal(post.url, post.title) }}
{% endfor %}

Twig Macros

Using Macros by Mijingo

alternatively with includes

{% for post in posts.limit(2).offset(1) %}
  {% include "_includes/vertical_layout" %}
{% endfor %}


How to create a CMS editable channel section index page? If I have a section called 'blog', and its handle is 'blog', and it's a Channel, all of the entries appear under http://mysite.com/blog/{slug} - which is great; but how would I create a page at mysite.dev/blog which is editable in the CMS, with its own fields? I'd like to do this so I can have a CMS editable introduction to the blog section, rather than having to hard-code an introduction into the template that would then list the latest X blog posts.

I can't create a Single called 'blog' because that handle is already taken by the Section itself, so how would I go about this? I'd considered using a Global, but that seems a bit off (it's not global content, it's a singular page's content) not to mention repetative/non-DRY if I had multiple sections to do similar things with, or if there were multiple fields I wanted applying on the overview/landing page. Is there a neater solution?

Create a Single called "Blog Overview" and set its URI to "blog" and its "Entry Template" to "blog/index" (your blog listing template).

Then just override the title to "Blog" either by hard coding it in the index template, using an "title override" field, not showing its title etc.


Loop over table field in Element API plugin How can I output the rows and values of a table field using the element api plugin?

Where I have entries I do

...
$industries = [];
foreach ($entry->industries->all() as $industry) {
  $industries[] = $industry->title;
}
...
return [
    'industries' => $industries
];

but ->all() doesn't work in the scenario of a table.

A table field contains a simple array, you can serialize and unserialize it as it is. So there is no custom action required by your side.
Just use it in PHP like every other textual field


How to use Super Table to create an Image Carousel? I'm very new to Craft and am having some trouble creating an image carousel from a Super Table. I created a Matrix field called 'rotator' it has one field called 'rotatorContents' which is a Super Table:

rotatorContents has 3 fields: slide image, slide description, and slide title. I'm using a for loop to loop through the rows of the Super Table

{% if module.type == "rotator" %}
    {% for row in module.rotatorContents %}
        {% set slide = row.slideImage.first() %}

        ‹

     {{need prev slide title here}}

    {% set title = row.slideTitle.first() %}
    {% set description = row.slideDescription.first() %}

{{ title }}

{{ description }}

       ›

     {{need prev slide title here}}

 {% endfor %}
 {% endif %}

As you can see from the code above I am not sure how to reference the previous row in the Super Table. From a user standpoint they can input as many slides as they like. So at any given time there should be an active slide that is displayed and arrows linking to the previous slide and next slide.

How do I go about fetching the slide that's before the active slide and the slide that's after the active slide? Or in other terms getting the previous row and the next row after the current one in the Super Table?

Also I'm sure there are also some other things I'm referring to wrong since this is my first time using Super Table, such as my usage of .first().

Welcome to Craft!

Is it essential that you use SuperTable for this? The behavior you are describing is exactly what Matrix fields are designed to do, so you could quite easily achieve this without using SuperTable.

Take a look at this screenshot; this is how I would set up my matrix field to allow me to content manage a slider (using the field names in your example):

Hopefully that screenshot is easy to follow. This also means the markup is much easier:

{# Check if the "Rotator" matrix field has any content #}
{% if entry.rotator %}

    {# For each slide, do this #}
    {% for slide in entry.rotator %}

{{ slide.rotatorTitle }}

{{ slide.rotatorDescription }}

    {% endfor %}

{% endif %}

Just a quick markup example to get you started. Take a look through the Craft Docs for using matrix fiels as well.

But to answer your question, I'd recommend checking out BXSlider. The markup is very simple and easy to integrate with Craft/Twig. It's what I use myself and I love it. It will just build a simple next/previous slider for you.


entry.url forcing https {{ entry.url }} is generating a https:// link. I don't have SSL on this site, so the page errors out.

Settings > General > Site Url is "http://..."

My .htaccess is below (though I've read the redirect doesn't work on shared hosting).

    RewriteEngine On
    RewriteBase /
    RewriteCond %{SERVER_PORT} 443
    RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Aside from "Get an SSL certificate," any suggestions on a fix?

I got the link to work, but it seems like a dumb workaround. For some reason, http://example.com redirects to https://example.com when I use {{ entry.Url }}, but when I use http://www. the redirect doesn't occur. I changed my Site Url to www. and created a redirect to www. in the .htaccess file.