Search for related entries via AJAX given multiple parameters I am attempting to create a relationship between products.
I have a section named "product" which is a Structure. Each "product" entry has a category field called "species" and a category field called "category".

My "species" category is a nested category. For example:

Dogs
  |-- Dachshund
  |-- Chiwawa
Cats
  |-- Long Hair
  |-- Short Hair

My "category" category is a single list. For example:

Yellow
Green
Blue

I have a form that I am trying to filter back my entries based on which "species" and/or "category" is chosen from the drop-down menu(s).

I have the ajax part down - no problem. I am sending a request to a twig .json template, and I am always getting into my "No Results" condition.

Here is the twig syntax I'm using. I have to be close (hopefully)...

{% set species = craft.request.getParam('species') %} // returns "Dachshund"
{% set category = craft.request.getParam('category')  // returns "Yellow"

{% set products = craft.entries.section('product').relatedTo('or',
{ sourceElement: category, field: 'category' },
{ targetElement: species, field: 'species' }
) %}

{
    "results": [{
        {% if products|length %}
            "status": "OK",
            "products": [
                {% for product in products %}
                    {
                        "name": "{{ product.title }}"
                    } {% if not loop.last %},{% endif %}
                {% endfor %}
            ]
        {% else %}
            "status": "NO_RESULTS"
        {% endif %}
    }]
}

I have also been trying to follow this thread in SO to search for entries.

I know I need a conditional (this or that) since a user could choose a "species" but not a "category" so this article from the docs is where I need to be.

I have gotten results back, but then run into an error that a class can't be converted to a string. I assume that's because I don't have the syntax correct to dig down into the category group correctly.

Within my "product" entry, the "species" category field looks like this:

Dogs
  |--Dachshund

I am also 100% confident the ElementAPI would be extremely helpful, I just haven't figured out how to incorporate it.

EDIT

Here is my updated products.json file that I am submitting the form to. I still fall into the NO_RESULTS condition.

{% if craft.request.isAjax %}
{% set species = craft.request.getParam('species').first() %}
{% set category = craft.request.getParam('category').first() %}

{% set foo = craft.entries.section('product').species(species) %}
{% set bar = craft.entries.section('product').category(category) %}

{% set products = craft.entries.section('product').relatedTo('or',
    { sourceElement: foo, field: 'species' },
    { targetElement: bar, field: 'category' }
) %}

{
    "results": [{
        {% if products|length %}
            "status": "OK",
            "products": [
                {% for product in products %}
                  {
                    "name": "{{ product.title }}"
                  } {% if not loop.last %},{% endif %}
                {% endfor %}
            ]
        {% else %}
            "status": "NO_RESULTS"
        {% endif %}
    }]
}
{% endif %}

I finally figured everything out, It took a long time to figure out what I actually needed to search for to find the answers I needed.

I put a comment at the bottom of this thread that was also of tremendous help. Passing multiple arguments to find related entries via categories.


Output javascript inside twig variable I am using the Enupal Stripe Payments plugin to pass line items to Stripe. The line items get passed in an array. I want to use a javascript cart to hold the items in local storage, reformat that and then send them to the twig array that will eventually be sent to Stripe.
I have reformatted the JSON from local storage using javascript and can see the output in my console. How can I include that javascript inside the twig array? I have read some vague feedback about using AJAX for this but I do not fully understand how to accomplish that or if it is the correct solution for this use case.
Stripe TWIG array example:
{% set options = {
    lineItems : MY JAVASCRIPT GOES HERE
} %}

Since Twig is server-side, and Javascript (usually) is client-side, you would need to change your code's logic so that the desired value you need inside that Twig command can be injected using javascript on the client's side.
Then you could send that data back along with the rest of the submission.
If you need server-side javascript, you would want to look at node.js


Could different entities have the same handle? I'm currently setting up a site. One routine operation there is to 1) create a category group and 2) create a 'Categories' field for it to attach to a section later.

Now for safety's sake I'm giving different handle names to the category group and the related field. For example, a category group has a handle called genre and the field — genre_field, just to ensure that no clashes between them would happen.

But is it actually a possible situation that handles of two different entities (here, fields and cat/groups, but it could be sections and fields as well and so on) could conflict?

No, having a field and a category group (or a section and a user group etc) share handles isn't dangerous at all.

Being specific and semantic with handles in general can be a huge boon for keeping things easily memorable and templates and other source code readable, though – so for example you might want to have handles like genre (for the category group) and selectedGenres (for the categories field), instead of both using genre. Though technically, both can be named genre, no worries.


Craft Commerce: Custom address model validations How/Where/Can I add more address model validations than just "firstName" and "lastName"...?

You can do either or both of:

Use javascript validation on the front end (with e.g. parsley)
Create a plugin with a method that is registered as a listener on this event:
https://craftcommerce.com/docs/events-reference#commerce_addresses.onbeforesaveaddress

...and perform validation on the address model before it is saved.  use $event->performAction = false; to stop the address actually being saved if need be.

General notes on how to listen to events and get at parameters is here.

Most likely, the best way will be to use a bit of both front end and back end validation here to make sure you're getting the data you want in the format you want in to your address fields.

(If you don't yet have a business logic plugin for your Commerce setup, then create one using either of two excellent options:
Business Logic Plugin or via http://pluginfactory.io)


Redis cache memory usage I’m runnung a few Craft sites with Redis cache enabled. It works fine. Except that Craft only uses around 3mb of Redis memory, with peaks up to 5, while there’s 128mb available.

Is there a way to set the amount of memory Craft can use? I couldn’t find anything in the documentation.

You don't mention if it's Crat 2 or Craft 3, but I'm not seeing anything in either codebase where Craft (or Yii) would limit the amount of memory available in its caching classes.


Can someone demystify tasks with a little more detail? I love the notion of tasks, especially for large processes, but I've found that their isn't a lot of documentation around it which makes trouble shooting them via an authoritative source difficult.

A few things I've found out that I had misconceptions on:

A task is one request, no matter how many steps it has, that runs in the background.
Sub tasks are all part of that initial task's one request
Since a task is a single request it is subjected to the same PHP Limitations that a normal request would be (i.e., memory limit) (this really comes into play when important large amounts of data in a dev environment because there's a lot of information that's being logged via a single request -- could be 100s of MB of log files in request

Some things I'm still confused about:

Does a task run with a separate session ID and thread than the browser that initiated the task via the CP request? I've noticed using the Power Nap plugin that if I initiate the running of task via a CP request I can navigate to other pages while the task is still running, but with other plugins that import Commerce data, I have to wait until the entire import is done before I can navigate to another page.
Do multiple queued tasks all get a single request or are they lumped into a single request?
If I need to insert thousands of entries is it more performant / desirable to place all entries in a single task or queue a task for each entry?

I'm sure their will be more, but I definitely think a single location for figuring out the benefits / use cases / pitfalls of Craft Tasks will be hugely beneficial.

Thanks in advance for the discussion.

One pitfall: In Craft 2 I've had troubles with a script that created thousands of entries.

The CP totally hung because it could not process the numerous tasks that were created (tasks of the like 'updateUri' ..). This was probably due to time limits and memory consumption; tasks were not processed anymore.

To solve that I created a task runner plugin, that processes a limited amount of tasks in the background through a cron job, and disables task execution on control panel access.


Mutiple sites and locales I'm trying to setup alternate locales for content across several sites. I have the following scenario:

- Group siteA
  - siteA.com/product-1

- Group siteB
  - siteB.com/product-2
  - siteB.com/fr/product-2

Content remains the same within a site group, where an entry in one locale is a translation of an entry another locale (as in Craft 2). Other site groups will have the same sections, but different content and perhaps locales. Propagating entries will not work in this case.

It's a scenario I've seen mentioned elsewhere, but I fail to understand the setup.

Is there a way to assign locales to multiple sites in general.php config the same way one would for siteUrl?

'production' => [
  'siteUrl' => 'siteA.com',
  'siteB' => [
    'en_gb' => 'siteB.com',
    'fr' => 'siteB.com/fr/'
  ]
],

Perhaps with alias?

Edit:

Ideally it would be something like propagating entries amongst site groups but not all sites, so product-2 would be propagated in siteB only.

Add your sites in the CMS, under Settings > Sites.
You can setup the Base URL and language per site.


Missing Matrix row types on output after upgrade to Craft 3 (subsetting and cloning ElementQueries) Update: Now I know the cause of my problem, I have appended to the original question title to try and help other people stumbling across the same issue.

I have a pending support ticket open with P&T on this, but just wondering if anyone else has had a similar experience and might be able to point me in the right direction.

I have a development site running happily on Craft 2.6.3013. As a first foray into Craft 3 I thought I would upgrade it to Craft 3 in a dedicated folder and DB of my local setup.

All seemed to go fine. I worked through and eliminated deprecation errors in my 2 well developed templates.

But one of the templates utilises a Matrix field with 2 block types -- subsection and item -- and only subsection rows are publishing.

The 20 rows originally in the field (in its singles entry) are all there in the back end, and their respective types show up as they should there: 5 for subsection and 15 for item.

But a simplified front end loop of:

    {% for row in entry.timeline.all() %}

{{ row.type }}

    {% endfor %}

…only produces the following outcome:

subsection

subsection

subsection

subsection

subsection

Turns out my issue is because I am running 2 loops through entry.timeline:

A subset of the field with only subsection blocks to generate a table of contents
The entire field contents with a mixture of both subsection and item block types.

Craft 2 was totally OK with me defining a subset and then looping through the entire set, but with Craft 3, if the subset is defined first, it seems to persist when the second loop runs, even if the scope of the second loop is defined differently.

So my current solution is to have a template structured like this:

{# Fetch the entire set first even though it will run second #}
{% set timelineItems = entry.timeline.all() %}

{# Fetch the subset second even though it will run first #}
{% set tocItems = entry.timeline.type('subsection').all() %}

{% for item in tocItems %}
    {# do subsetted ToC stuff #}
{% endfor %}

{% for row in timelineItems %}
    {# do entire timeline stuff #}
{% endfor %}

See https://github.com/craftcms/cms/issues/2160 for more background, and cloning element queries in the docs.


Neo plugin - Displaying an image from a Matrix field I am using the Neo plugin in my project. I have made a Neofield article content with several block types in it. Amongst the block types that I have in it, is a gallery as well. Gallery block type has amatrix field imageWithCaption, and the field imageWithCaption has fields file which is the assets field, and fields imageTitle and caption which are plain text fields. I am able to display imageTitle and caption in my template but not a file, or the image itself. This is my template:
     {% for image in block.imageWithCaption %}

{{ image.title }}

{{ image.caption }}

      {% endfor %}

I get an error:

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

What I am doing wrong and how can I display the image?

It's tough to see the full context, just based on what you have here. From what I can tell, it seems like you might need to change  to .

Since the asset field can hold many assets, you have to declare .first() to grab the first one -- even if there's only one image. Then you have to grab the url property from the image, in order to get the correct src value.


Search all Sites on Multisite I have a multisite setup and and a search bar at the top of each site. Currently it just searches within that site:

{% set theSite = craft.app.request.getSegment(1) %}
{% paginate craft.entries.search(search).site(theSite).orderBy('score').limit(9) as pageInfo, pageEntries %}

The first segment defines the site.
I need to expand the searches to include all entries in all sites. Is this possible? I tried variations of getAllSites and just .site but of course those didn't work.

If its not possible to search all sites at once I may look at running each search and adding all of the results together.

Currently, you unfortunately can't query all sites within your entires, you will have to separate your results out with a for-loop by site, as @aran did above.

Craft 3.2 will thankfully fix this by allowing you to pass sites to an array or query sites('*') to return entries from all your sites:

https://github.com/craftcms/cms/commit/d01702278bd84b84392e11da72aa4d0b6f4f0943


Trying to crawl a site I'm trying to crawl a site, I've tried using Screaming Frog and https://www.internetmarketingninjas.com/seo-tools/google-sitemap-generator/ and both return the same results when I try a crawl.  It finds the home page, but it then will give 404's for all the links it finds on the page.  If I got to the site manually I don't get 404's.

I'm new to Craft CMS so I don't know much (yet).  Inherited this site not too long ago.

Site is: https://highparknaturecentre.com/

In addition, I also noticed that If I go to https://highparknaturecentre.com/about the server returns http status 404 but returns the body content.  Could this be a server issue?

Yeah the server is probably misconfigured. Craft relies on a 404 happening to do some of what it does, but the status code should be changed before the response is returned.

I don't have enough information to tell you how it is misconfigured. Would depend on the webserver (Nginx/Apache/whatever) and we'd need to see the specific config.

There also is no /sitemap.xml on the site.


Easily update the query string with a link I'm working on a site with some filters that result in a page with a URL similar to this:
domain.com/led-products?series=67&efficacy=1000to5000&lumens=over150

That results page contains buttons/links like so:

[Series Name x]
 [1,000 to 5,000 Efficacy x]
 [Over 150 Lumens x]

Clicking on one of those would remove that filter. Let's say a user clicks on Series Name to remove that filter, the resulting URL would then be: domain.com/led-products?efficacy=1000to5000&lumens=over150

My problem is that I have no idea how to get that filter/parameter removal functionality in Craft. Does this require a JS solution?

I've played around with something like this and can't seem to get it to work for my needs.

Help?

OK, this should be a working code example:

{% set queryParams = craft.app.request.queryParams %}
{% for key, value in queryParams %}
  {% set url = siteUrl ~ craft.app.request.fullPath %}
  {% set arr = queryParams | filter((v, k) => k != key) %}
  {% if arr|length > 0 %}
    {% set url = url ~ '?' ~ arr|url_encode %}
  {% endif %}
  {{key}} {{value}} x
{% endfor %}

Line by line:

Create an array based on the current request parameters:

{% set queryParams = craft.app.request.queryParams %}

Loop through the array and get the key/value pair:

{% for key, value in queryParams %}

While inside the loop, get the URL that we want to modify, minus the request params:

{% set url = siteUrl ~ craft.app.request.fullPath %}

Filter a local copy of the array to remove the current key:

{% set arr = queryParams | filter((v, k) => k != key) %}

If there are any parameters left, modify the URL we previously set with the remaining parameters:

{% if arr|length > 0 %}
  {% set url = url ~ '?' ~ arr|url_encode %}
{% endif %}

Output the link that will load the page without the current parameter.

{{key}} {{value}} x

I would probably do this in a macro to keep the template code a bit cleaner and easy to read.


Matrix field containing asset field blocks entry editing I am new to  Craft CMS and am testing it. I encountered a problem.

I have a matrix field, containing an asset field. When I add this matrix field to the page field layout, then visit single entry, put something inside this asset field of the matrix field and save - things break, I can't access this entry in backend later, all that shows is this:

I have local assets source set up, and images do upload there, I can see them in assets explorer later.

When I just fill in other fields of matrix field, omitting asset field or don't use matrix field at all, things are ok.

I work on Windows, on XAMPP server.

Well, i found an answer. It seems it was caused by xdebug.

All fields disappearing except 'Title' after saving

Adding this to php.ini helped:

xdebug.max_nesting_level=200


PHP Exception for errors on Craft Contact Form with additional fields I'm having trouble with additional message fields in my Craft Contact Form using Craft 3 and the Pixel & Tonic Contact Form plugin.

I've added two additional fields by splitting up the message field as described in the plugin documentation. If all the fields are filled in, everything goes smoothly. But if the form is submitted with any blank required fields, I get a PHP error "Array to string conversion." Live example at http://striveforfive.creativeforthepeople.org/contact.

EDIT: The code is:

    {% if entry.formCopy|length %}{{ entry.formCopy }}{% endif %}
    {% macro errorList(errors) %}
        {% if errors %}

                {% for error in errors %}

{{ error }}

                {% endfor %}

        {% endif %}
    {% endmacro %}

    {% from _self import errorList %}

    <form class="contact-form" method="post" action="" accept-charset="UTF-8">

            {{ csrfInput() }}
            <input type="hidden" class="form-control" name="action" value="contact-form/send">
            {{ redirectInput('contact-ty') }}

            <input id="from-name" class="form-control" type="text" name="fromName" value="{{ message.fromName ?? '' }}" placeholder="your name">
            {{ message is defined and message ? errorList(message.getErrors('fromName')) }}

            <input id="from-email" class="form-control" type="email" name="fromEmail" value="{{ message.fromEmail ?? '' }}" placeholder="your email">
            {{ message is defined and message ? errorList(message.getErrors('fromEmail')) }}

            <input id="affiliation" class="form-control" type="text" name="message[Affiliation]" value="" placeholder="your school / organization / home locations">

            <select id="position" class="form-control" type="text" name="message[Position]" value="">
                <option value="" selected disabled>your position</option>
                <option>Educator / Care Giver</option>
                <option>Family Child Care Provider</option>
                <option>Center Director</option>
                <option>Student Teacher</option>
                <option>Other</option>
            </select>

            <textarea rows="5" cols="40" id="message" class="form-control" name="message[body]" placeholder="your message">{{ message.message ?? '' }}</textarea>
            {{ message is defined and message ? errorList(message.getErrors('message')) }}

            <input id="bluebeard" name="bluebeard" type="text">

            <input id="contact-submit" type="submit" class="btn btn-outline-primary" value="Send">

    </form>

All help is appreciated!

I think this:

{% for error in errors %}

{{ error }}

{% endfor %}

  ... is where the error originates.

  I memory serves me right, errors is an array like this:

[
    ['fieldHandle' => ['Something went terribly wrong!', 'Really, two errors in ONE FIELD?']],
    ['orderFieldHandle' => 'I AM REQUIRED, y\'all!'],
];

  In which case {{ error }} would dictate Twig (and therefore PHP) to
  echo an array (['fieldHandle' => ['Something went terribly wrong!',
  'Really, two errors in ONE FIELD?']]), resulting in the error you
  mentioned.

  You can fix this, by using the following code:

{% for fieldHandle, fieldErrors in errors %}

{{ fieldHandle }}: {{ fieldErrors |join(', ') }}

{% endfor %}

My original answer was not what caused the error (so, apparently, errors was not what I thought it was).

This type of error is caused by an array being echoed by PHP, and not a string. In this case, the cause of the problem is {{ message.message ?? '' }}, which turned into an array because it contains multiple field values.


Update a lightswitch field in Craft CMS 2 How can I edit a lightswitch field in an entries field layout via PHP? This is my current approach

public function actionSponsoredEntriesPriority() {
    $this->requireAdmin();
    $this->requireAjaxRequest();
    $success = false;
    $message = Craft::t('Any message from controller');

    $newPriority = craft()->request->getPost('newPriority');
    $entryId = craft()->request->getPost('entryId');

    $entries = craft()->entries;

    $entry = $entries->getEntryById($entryId);

    if ($entry != null) {
        $entry->getContent()->setAttributes(array(
            'lightswitchFieldHandle' => 1
        ));

        $success = $entries->saveEntry($entry);
        $success == true;
    } else {
        //return null;
        $success = false;
    }
}

But since there are other required fields that are currently empty for this entry I receive the following response

  message: {featureImage: ["Feature Image cannot be blank."], hero: ["Header cannot be blank."]}

I tried to resave the required fields still stuck at matrix field.
Here is code Reset required field

  Error : Correct the errors listed above.

Do i need to update the required field as well or there is a way to bypass while updating a field ?

  Update : Solution as suggested in answer [Update field directly ]

public function actionSponsoredEntriesPriority() {
        // $this->requireAdmin();
        // $this->requireAjaxRequest();
        $newPriority = craft()->request->getPost('newPriority');
        $entryId = craft()->request->getPost('entryId');
        $success = false;
        $message = Craft::t('Any message from controller');

        // entries object
        $entries = craft()->entries;
        // entries  by id ( $entryId passed by js )
        $entry = $entries->getEntryById($entryId);

        if ($entry != null) {
                $command = craft()->db->createCommand();
                $success = $command->update(
                    'content', // table name
                    array(
                    'field_lightswitchFieldHandle' => 1,
                    'field_sponsoredEntriesPriority' => $newPriority
                    ), // fields
                    'elementId=:id',
                    array(':id'=> $entryId)
                    );
                $message = Craft::t('Priority saved');
                $success == true;
            } else {
            //return null;
            $success = false;
        }
        // send response true/false with message
       if($success == true){
           $this->returnJson(
            array(
                'success' => $success,
                'message' => $message
            ));
       }else{
           $this->returnJson(
            array(
                'success' => $success,
                'message' => $entry->getErrors()
            ));
       }
    }

If it's only one single field and you want to bypass all Craft validations for required fields you can change the value directly in your database using Yii commands and the update function

function update($table, $columns, $conditions='', $params=array())

$command = craft()->db->createCommand();
$command->update('craft_content',
    array(
        'field_yourLightSwitchField' => 1,
    ),
    'elementId=:id', array(':id'=>1)
);

If you have a multilocale setup you need to include the condition for the correct locale as well


Custom Category order in a Categories Field I have a load of projects, each of which can have zero or more categories which indicate the particular type(s) of work involved. As well as using these categories to produce a 'category page' of filtered entries, they are also pulled through to each index page listing, to show the types of work involved in that particular project.

Therefore, these ideally should be ordered by priority, so one project may feature more use of category 1 so that would want to come first, whereas one project may feature more use of category 2.

For Assets Fields (and I think also Entries Fields), I seem to be able to order the respective elements by dragging and dropping them in the field, but for Categories Fields, the order seems to be determined by the order of the Structure in the Categories page in the CMS.

Is there a way of allowing the user to customise the order the Categories in a Categories field?

Thanks!

No, it’s not possible to change the order of related categories.

(Think of the field as a big checkbox list; you can change which checkboxes are checked, but you can’t change their order. The only reason it’s not a simple checkbox list is to save visual space.)

If you really want to be able to set the order, you can put the Categories field inside a Matrix field, where each block selects a single category, and then you can reorder the blocks.


Set a route for all requests within a plugin I’m trying to use a plugin to set up a site route that will direct every page request to a special template.

This is what I’ve set up in my plugin file.

public function registerSiteRoutes()
    {
        return array(
            '*' => 'special/index',
        );
    }

Using the above doesn’t seem to do anything. If I replace * with a word, then try to visit that URL I get something different but not my template.
would love it if someone could put me right here

UPDATE
If I change tact a bit and route to a controller using a specific url then I can see it gets there

public function registerSiteRoutes()
    {
        return array(
            'beer' => array('action'=>'beer/index'),
        );
    }

But I can't figure out how to catch all requests  using * doesn't appear to do anything

UPDATE
@robin helped me out massively here with some more info outside the comments.

Basically  in Craft 2 the plugin routes get called first no matter what. So I can hijack the init method to load my special template

UPDATE 2
I made this into a Craft 2 plugin.
https://github.com/moresoda/craft-emergency-mode

Craft 3 plugin coming soon.

You can use the catch all route

'catchAll' => ['site/offline'],

For yii1 you can also do

'<url:(.*)>' => 'controller/action'


new locales not showing up We have created a site with locales (English, German and Italian). We want to add an extra locale to the home page so we went into the locales admin area and added the new locale. But when we edit the home page this new locale does not show up, it seems like the locale list for a page is setup when the page is created and the new locales are only available to newly created pages.

regards

Andrew

You have to activate the new locale in the section's settings.


Hide plugin menu item Is there a way to hide the menu item that plugins add to the control panel menu?  As seen in the picture below, I do not need the "DashCols" link in my main menu, but would like to keep the plugin installed.

If you're looking for a more robust and easy-to-use solution, have a look at the CPNav plugin, which allows you to re-order, rename and hide menu items.


Using the required field validation in custom element types/plugins? I am finishing up the last few details on my custom element type. I have custom statuses and public submissions working. The last detail is providing validation on custom fields set through the field layout outside of the control panel.

Here is a brief overview of the plugin:

PluginNameElementType - that allows custom fields via the field layout.
PluginNameController - which has an action 'actionSubmit' which is allowed public access to submit entries outside of the control panel.

The code for public submission is on this post:

Allow anonymous submission on a custom element type?

I have seen some Yii examples that include CActiveForm::validate() and pass a  model to validate the input, but I don't see that anywhere in Craft.

The way I see it, there are two parts to validation on custom element types from outside of the control panel.

The first part being providing authentication for the attributes defined as 'required' in the element types model.

For example, if you have the following code:

protected function defineAttributes()
{
    return array_merge(
        parent::defineAttributes(), array(
            'formId' => array(
                AttributeType::Number,
                'required' => true
            ),
            'fieldName1' => array(
                AttributeType::String,
                'required' => true
            ),
            'fieldName2' => array(
                AttributeType::String,
                'required' => true
            ),
        )
    );
}

How would I access and return this in the controller action method that allows public submission? Does Craft provide an additional layer on top of Yii to assist with validation?

The second part of the question is similar, but unique all the same. The other part I need to provide validation for is the custom fields set in the field layout of the element type. If a user sets the fields to required in the same method they would with a regular entry field. How would I access validation on the custom fields level?

Custom field validation happens automatically for you when you pass your element into craft()->elements->saveElement(). That function will return true or false, largely depending on whether custom field validation passes.

See EntriesService::saveEntry() for an example.


Updated the PHP on server. Getting this error: Please ensure that $craftPath is set correctly I am running Amazon Ec2 instance and tried updating the PHP on the site using this guide: http://brianshim.com/webtricks/update-amazon-ami-php5-3-to-php5-4/

And now this is the error I am receiving:
Please ensure that $craftPath is set correctly in /var/www/html/staging/public/index.php

I tried resetting the permissions, and restored the old http config files, to no avail. I have no idea what it could be. I checked php.ini for open_basedir and did not find it.

Could it be the permissions?

All Craft is doing is using PHP's is_file() method to check if the supplied path to craft/app/index.php returns true or not.

Take Craft out of the picture and setup a simple PHP script that does

<?php

if (is_file('path/to/craft/app/index.php')) {
    echo "found it";
} else {
    echo "oops";
}

If you get an "oops", then there is some environmental issue (PHP permissions, open_basedir restrictions, Suhosin, mod_security, etc.) that is preventing PHP from finding that file that will need to be addressed.

If it is permissions related (the most common cause), there is a handy script here that will properly set the permissions for a Craft install: https://github.com/nystudio107/craft-scripts/tree/master/scripts


Using pagination on a page with url with query string data I have an index page that filters entries based on url query strings, eg: site.com/inductees?county=123.

I put together a very simple pagination setup with next/prev links. However, when I click "next" I am brought to site.com/inductees/p2 and I lose my filtered set of entries from the ?county=123 bit.

How can I get pagination working and keep the query string in my url?

Thanks!

In most Craft projects I do I'll create a pagination include file so anything I need that requires pagination, I can just include that and I get the same pagination pattern anywhere within my site when I need it.

While you do have to set the country attribute with each link, sometimes it might get a little tedious to do this manually or you may expand your attributes to include other options, like ?country=123&distance=50.

This is where Craft's craft.request.getQueryStringWithoutPath() comes into play. In Craft 3 this has been changed to craft.app.request.queryStringWithoutPath. But you could do something like this:

{% if craft.request.getQueryStringWithoutPath() %}
  {% set queryString = "?" ~ craft.request.getQueryStringWithoutPath() %}
{% endif %}

Previous

Then no matter what URL attributes you have, they'll always be included within your pagination links.


Website structure with Craft This is my first try at Craft, was planning on replicating a current site as practice, had a question about the sites architecture.

I have a Brands page:

Brand/Company info
-Brand product line
--individual products within that line

What would be the best way to implement this?
I'm thinking a structure? They are child's of each other?

Thank you.

I'd probably have products as a channel and then a product being tied to a category so and then category urls would be something like /products/category


String interpolation in Redactor I have a redactor field whose HTML contents contain links to other parts of the website.

How do I render variables located in the HTML content of a Redactor field in Twig?

Sample redactor content:

About

Contact

In output of this results in the braces being encoded:

About

Contact

But I want it the output to be whatever siteUrl is. Eg on localhost:

About

Contact

Redactor fields are not meant to process twig both for security reasons (as they can be changed by any user) and for usability (you cannot expect authors to remember / preserve twig tags).

In your specific example, the site url is probably not necessary (starting a URL with / will link to the current domain just fine) - so you would not actually need twig.

However I cannot think of one good reason to build a menu in a redactor field. I would either include it directly in the page templates (.twig files) or use a matrix field as a content builder.


How to apply multiple Twig filters to text - SOLVED **

After continuing to play around with this I realized that I did not need to add nl2br, adding hacksaw was actually removing the formatting from the rich text field.  I opened a new question here
 if anyone can help or has encountered this issue any help would be appreciated.

**

I have a line

{{ workItem.summary | hacksaw(words='75', append='...') }}

I need to add

 nl2br

to it.  I have tried

{{ workItem.summary | nl2br | hacksaw(words='75', append='...') }}

and

{{ nl2br (workItem.summary hacksaw(words='75', append='...')) }}

Neither worked.

Can anyone shed some light on the syntax I need to get this to work correctly?

I believe filters are applied in the order they're written. So in your example you're probably applying the new line breaks with nl2br and then removing them again with hacksaw.

Try:

{{ workItem.summary | hacksaw(words='75', append='...') | nl2br }}

Alternatively you could try setting hacksaw to allow line break tags. Something like this (untested):

{{ workItem.summary | nl2br | hacksaw(words='75', append='...', allow='
') }}

I'd go with the first option though.


Order Adjusters in Commerce 2 In Craft Commerce 1, there is documentation on how to re-order adjustments that do similar things.
https://docs.craftcms.com/commerce/v1/adjusters.html#ordering-adjustments

But I don't see any similar documentation for how to do that in Commerce 2.

I have 2 plugins that make adjustments to the Sale price and then Order total, but if run in the wrong order, it doesn't work.

Simple solution is to uninstall the plugins and install them in the correct sequence, but was wondering if there was still a way to force them to run in a certain order.

Looking at the \craft\commerce\services\OrderAdjustments you should be able to change the ordering of your adjustments by using the \craft\commerce\services\OrderAdjustments::EVENT_REGISTER_ORDER_ADJUSTERS event.

use craft\events\RegisterComponentTypesEvent;
use craft\commerce\services\OrderAdjustments;
use yii\base\Event;

Event::on(
    OrderAdjustments::class,
    OrderAdjustments::EVENT_REGISTER_ORDER_ADJUSTERS,
    function (RegisterComponentTypesEvent $e) {
        $e->types = [
            // Add the adjusters in whatever order you want here. Leaving this empty would disable all adjusters.
        ];
    }
);


Repopulate a static select input I have a form that contains a static select input of U.S. States:

<select id="state" name="state" class="form-control">
<option value=""> Select </option>
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option>
....
</select>

I have the validation figured out on my form, and also have my text inputs getting repopulated if there are any validation errors. I am curious about the best method to repopulate my select input.

I can access the value that was entered via:

{% set state = craft.request.getParam('state') %}

Which will give me "AL" or "AK" (whichever was chosen). This is fine, but because my list is static, do I now need to have logic on every option?

For example, something like this...

<option value="AL" {% if state == AL %}selected="selected" {%endif%}>Alabama</option>

Or, is there a better way all together?

FWIW, here is how I am repopulating my text inputs:

value="{% if model is defined %}{{ model.name }}{% endif %}

Thank you!

No, I don't think there's a better way, you need to add that conditional to each select option.
But what you could do is to refactor a bit and move that logic to a Twig macro.

{% macro stateOption(id, name, selectedId) %}
    <option value="{{ id }}"{{ id == selectedId ? ' selected="selected"' }}>{{ name }}</option>
{% endmacro %}
{% import _self as forms %}

{% set selectedId = craft.request.getParam('state') %}

{% set states = {
    'AL': 'Alabama',
    'AK': 'Alaska',
    'AZ': 'Arizona',
} %}

<select id="state" name="state">
    <option value="">Select</option>

    {# Go through states and use the custom macro to generate the select options #}
    {% for id, name in states %}
        {{ forms.stateOption(id, name, selectedId) }}
    {% endfor %}
</select>


Have a custom plugin do something on every page load? For an upcoming site build, I'm going to need to capture information on every page load for a number of sections. These will be pages based on standard entries, so I'd prefer to use traditional routing (so not handled through a custom controller). There will probably be three different sections that will each have the same information captured when the page is loaded – basically just a list of categories so we can track the most popular type of content and display it as a dashboard widget.

At first I assumed I could do this with an event, but it doesn't look like there are any events for a page being loaded. I'm currently thinking that I use JavaScript to fire an AJAX request to a plugin and send the data along. This will work, but generate extra page loads. I'm thinking it'd be more efficient if I could keep everything server side.

Is there some way to do this that I'm not seeing?

Add a init() method to your plugin and as long as it's installed and enabled, it'll be called on every request.

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

    /* Do your stuff */
}

If you want it to only happen on front-end requests, you can use:

if (craft()->request->isSiteRequest()) { ... }


Can't login after installing Craft CMS 3 I just installed Craft CMS 3 and I tried logging in as my admin user but it's not working. I enter the correct login information and nothing happens. I tried the reset password option but never got the email for some reason. Anyone have any ideas what is going on?

It was a permission issue. I used the command below on the entire craft folder to get this to work:

sudo chmod -R 777 craft/

The logs were saying that it didn't have permissions to open many files.


Move entries between sections I have some entries that I'd like to move to a different channel, but I don't see any way to do this. Is it possible?

It’s currently only possible via direct manipulation of the entries in your database.

You will first need to visit your sections table to determine the desired section ID, and then the entrytypes table to determine the desired entry type ID.

Once you have those, find your entry’s row in the entries table, and change its sectionId and typeId columns accordingly.

NOTE: If either of the the old/new sections are Structures, there’s quite a bit more work involved, and your best bet will be to write some PHP code to handle the migration. See https://craftcms.stackexchange.com/a/4467/9 for a complete example of how to do that.


Is there a way to define a global var within a twig block? Something that would work like this:

{% block A %}
  {% set testVar = "foo" %}
{% endblock %}
...
{% block B %}
  {{ testVar }}
{% endblock %}

The scope of testVar seems limited to {% block A %}

I'm looking for a way around this, so that the child template can pass content to the parent to use in other blocks.

This is an issue since the child template that extends the parent cannot have content outside a defined block.

Twig variables are only accessible inside their own scope.

.

What is a scope:

Tags like {% block %}, {% for %}, {% nav %} create a 'scope', which means that variables defined inside them, can't be accessed from outside. This is similar to local variables inside php-functions:

{% block A %}
    {% set var = 'apple' %}
    {{ var }} {# This prints apple #}
{% endblock %}

{% block B %}
    {{ var }} {# This doesn't prints anything, since var isn't defined #}
{% endblock %}

.

Variables outside their scope:

To make variables accessible outside their scope you have to define them before:

{% set var = 'apple' %}

{% block A %}
    {{ var }} {# This prints apple #}
{% endblock %}

{% block B %}
    {% set var = 'banana' %}
    {{ var }} {# This prints banana #}
{% endblock %}

{% block A %}
    {{ var }} {# This prints banana #}
{% endblock %}

.


What’s the recommended way to set the site URL? There are multiple ways to set the site URL. What is the recommended way?

As of Craft 2, you should be using the new siteUrl config setting.

There are two advantages to setting your site URL using this config setting.

First, The value can be set on a per-locale basis, in a way where Craft is actually aware of all locales’ URLs on every request (unlike the CRAFT_SITE_URL constant, where Craft only knows the current locale’s URL). That’s a good thing because it means you can easily link to entries’ URLs across different locales, for example.

return array(

    'siteUrl' => array(
        'en_us' => 'http://example.com/',
        'de'    => 'http://example.com/de/',
    ),

    // ...

);

Its value can also be set directly on a per-environment basis. (Yes you can achieve this using the environmentVariables config setting combined with a {siteUrl} tag inside the Site URL setting within the CP’s general settings, but that’s much less direct/obvious.)

return array(

    '.dev' => array(
        'siteUrl' => 'http://example.dev/',
        // ...
    ),

    '.com' => array(
        'siteUrl' => 'http://example.com/',
        // ...
    ),

    // ...
);

Those of course can be combined as well:

return array(

    '.dev' => array(
        'siteUrl' => array(
            'en_us' => 'http://example.dev/',
            'de'    => 'http://example.dev/de/',
        ),
        // ...
    ),

    '.com' => array(
        'siteUrl' => array(
            'en_us' => 'http://example.com/',
            'de'    => 'http://example.com/de/',
        ),
        // ...
    ),

    // ...

);


Models v Records - confused If a Model can be used to save entries, what is a Record for? Is it literally just to define the schema? I've seen a few examples where the defineAttributes methods have duplication of code too, so I'm a little confused...

I might be wrong here, but I don't think a model can be used to save entries. You populate a model, then populate a record with that model and save it. Once saved, you get data from the db as a record, then populate a model with it to pass that to a view, for instance.

If everything works as it should, a record is never used outside the service.


Sort entries in a category or entries field? I have a Products Section and a Product Category Structure Section
In Products there is an Entries Field where the Category is selected from the Product Category section.

Is it possible to sort the products per category manually?

I see with the ManytoMany Plugin - https://github.com/page-8/craft-manytomany
You can display the products which appear in each Category and the Custom Ordering of the second Relationship is in the pipeline which would probably work but not available yet.

Is there any other option?

To order the products you'd make the Products section into a structure and display the category you were sorting by in the listing as a table column.

You can then re-order all products to be in category order (using the table column), then re-order each product for each category.

You can then output each product grouped by category with something along the lines of:

{% for cat in categories %}

  {% set products = products.relatedTo( cat ) %}

  {% for product in products %}

    {{ product.title }}

  {% endfor %}

{% endfor %}


Set execution order of plugins listening to same event I have 2 separate plugins that listen to same event.

Now I want to make sure Plugin B starts its action only after Plugin A has finished its job.

Is there a way in Craft CMS to set priority / execution order for plugins that listen to same event?

Not really – there's no priority system built into events for Craft or Yii.

The easy way out is taking advantage of the fact that Craft actually loads plugins alphabetically, by name (i.e. the string returned by the plugins' getName() method). This means that if your plugins are in fact named "Plugin A" and "Plugin B", then Plugin A will be loaded before Plugin B and you can be sure that its event listener is also attached earlier, meaning that – in theory, I haven't tested this – it's event listener should also be called before Plugin B's event listener.
Edit: This doesn't actually appear to work, at least not reliably.

Of course, the correct way to solve the issue is to write your code in a way that negates the need for sequentially dependent event handlers. One way to do this is to use custom events – for instance, you could have Plugin A listen to the native entries.saveEntry event, but have Plugin B listen to some custom event instead, where Plugin A fires the custom event after completing its work inside the saveEntry handler.

You could also consider dropping the event listener altogether for Plugin B, and just call one of its service methods directly from Plugin A's event listener (you can even pass in the event object if you need it):

// Plugin A
craft()->on('entries.saveEntry', function (Event $event)
{
    ...
    // Stuff happens, then let Plugin B do its thing
    $pluginB = craft()->plugins->getPlugin('pluginB');
    if ($pluginB) {
        craft()->pluginB->someMethodName($event);
    }
}

Beyond this, its hard to advise without seeing some code examples or a more elaborate use case.


Donation Status Commerce 2 Currently trying to use the new Donations feature of Commerce 2 - https://docs.craftcms.com/commerce/v2/donations.html

The order goes through fine and I can see the donation purchasable in the order.

What I can't do though is get it to assign the status of Donation to the donation/order. It currently comes through as a New status.

This is extremely handy to break apart Orders from Donations and vice versa.

Is there a way to set the donation status as default to all donations, or somehow assigning the status to the donation via the form when the payment is processed?

Donations are like anything else, and can be bought along side regular products so they are a part of normal orders.

You can use the event below to inspect the order and choose youre own default status if you want.

use craft\commerce\events\DefaultOrderStatusEvent;
use craft\commerce\services\OrderStatuses;
use yii\base\Event;

Event::on(OrderStatuses::class, OrderStatuses::EVENT_DEFAULT_ORDER_STATUS, function(DefaultOrderStatusEvent $e) {
 // Do something - perhaps figure out a better default order statues than the one set in CP
 // $e->order
 // $e->orderStatus (the order status to set as the default for this order)
});


Can I use Craft to Manage Site Access? User Access Question...

Can I use Craft to create users that can only use the site?  These users would only be viewers of the content.  They would NOT have access to Craft or any of its features.

Put another way, users login to my site and I have Craft (theoretically) setup to control their access to either the entire site or specific sections only, NOT edit or have access to any Craft features.  I don't even want them to know craft exists. '

Basically, I only want paid clients to have access to the site.

Yes, absolutely. You can use the {% requireLogin %} tag at the top of any templates that you want to protect, and you can create a login form very easily to allow registered users to login and access the site:

https://docs.craftcms.com/v3/dev/examples/login-form.html


Setup default Matrix blocks and default values for sub-fields? Question is
what table can't achieve, can be achieve by matrix but problem is matrix cannot have default row value like table have.

Anyway to achieve it?
Thanks.

It's not possible to have default values for most field types and it is also not possible to have default matrix block already added to your new entries.

If there was an event that gets raised before an entry is displayed in the Control Panel's "Edit Entry" view, you could set default values rather easily with a custom business logic plugin.

There's no such event available yet, but you could vote for the feature request I just added:

Raise an event before entry is edited/loaded in CP


Element API display entries by category With v2 of the Element API plugin, I'm having issues with working out how to return entries that are in a particular category.

I've got the slug in the API route but can't work out what the query should be in the transformer.

Should I be doing this query in a total different way?  I keep thinking I've just gone down the wrong way to do it completely.

'api/v1/category/<slug:{slug}>.json' => function($slug) {

        return [
            'elementType' => Entry::class,
            'elementsPerPage' => 30,
            'criteria' => [
              'section' => 'posts',
              'relatedTo' => ['targetElement' => ***category slug($slug)***],
            ],
            'transformer' => function(Entry $entry) {
                return [
                    'title' => $entry->title,
                    'id' => (int) $entry->id,
                    'slug' => $entry->slug,
                    'postDate' => $entry->postDate
                ];
            },
            'pretty' => true
        ];
    }

Your targetElement needs to be the category object or the ID of your category.
So if the id of your category is 5 you need

'relatedTo' => ['targetElement' => 5],

If you really want to be able to fetch your category by slug (which I would not suggest since your slug can be changed in the cp but the ID can't, if someone changes the slug by accident your entire logic will break) you can create an ElementCriteriaModel to search for the category with the slug and insert the object there.

$criteria = craft()->elements->getCriteria(ElementType::Category);
$criteria->slug = $slug;
$category = $criteria->find();

And inside your array

'relatedTo' => ['targetElement' => $category],


How do you require specific dimensions when uploading an image? I think the transform feature is great, although in my case I need to request that certain images be uploaded at specific dimensions to an assets field. (i.e. 500 x 300 pixels). These dimensions will also need to be required on the front-end Guest Entries form. Although I don't see this option in the control panel or in the docs. Is this something that can be done?

Currently, no. The only file-based validation Assets fields have right now is the type. If you want to enforce a certain size, you can do that on the template end using image transforms. I would suggest adding some instruction text to your Assets field that provides a minimum suggested size, and note that smaller images will be scaled up and look gross.

That said, if you really want to enforce a minimum width/height, or other properties, you can do so by writing a plugin that provides its own field type, which extends AssetsFieldType and overrides its validate() method with your custom validation:

public function validate($value)
{
    // Let AssetsFieldType do its validation first
    $errors = parent::validate($value);

    if (!is_array($errors))
    {
        $errors = array();
    }

    if (is_array($value) && !empty($value))
    {
        foreach ($value as $fileId)
        {
            $file = craft()->assets->getFileById($fileId);

            if ($file)
            {
                if ($file->width < 600 || $file->height < 400)
                {
                    $errors[] = Craft::t(
                        '{filename} must be at least 600x400px.',
                        array('filename' => $file->filename)
                    );
                }
            }
        }
    }

    if ($errors)
    {
        return $errors;
    }
    else
    {
        return true;
    }
}


Blank white pages after moving index.php I was developing a site on my server. Craft was living at ~/mysite.com/craft/, the webroot was ~/mysite.com/www/, and the URL was dev.mysite.com.

Now I want to deploy the site to www.mysite.com, but the host (HostGator) requires that the hosting account's primary domain (www.mysite.com) point to ~/public_html/. Ok, fine. First, I changed the dev subdomain to point to ~/public_html/ instead of to ~/mysite.com/www/. Then I moved the index.php and .htaccess from ~/mysite.com/www/ to ~/public_html/ and updated the $craftPath variable to point to the proper directory, but now all I get is blank white pages, both on the frontend and the admin.

I deleted everything under the craft/storage/runtime/cache/ and craft/storage/runtime/logs/ directories, opened up an incognito Chrome window, and pointed it at dev.mysite.com/admin (which is now pointing and .htaccess-requesting ~/public_html/index.php?p=admin, I believe...). I get redirected to dev.mysite.com/admin/login, but still end up with only a blank white page there.

The only [error] appearing in the log file is related to testPathInfo:

2016/06/08 21:52:06 [error] [application] Unable to determine if PATH_INFO is enabled on the server: [curl] 6: Couldn't resolve host 'dev.mysite.com' [url] http://dev.mysite.com/index.php/testPathInfo

Halp?

Not sure the underlying cause, but clearing the craft/storage/runtime/cache folder that both sites shared caused both sites to start working as expected.


How to add Redactor Image resizing and positioning to the Rich Text field in Craft? Can anyone provide details on how to add Redactor (II) Image resizing and positioning to the Rich Text field in Craft?

Many thanks!

If you're on Craft 2.6.2950 or greater, it includes Redactor II 1.3.1, where they re-introduced image resizing and positioning support.

You'll just need to add:

imageResizable: true,
imagePosition: true

to whatever craft/config/redactor config file your Rich Text field is set to use under its settings.


Template not found error when template file does exist I am getting a Template not found error.

Template not found error: case-studies/_category

However the template does exist (see screenshot).

I have tried clearing the template cache but still the issues perssits.

Update

I'm doing tests with other files - like image files - uploading them to the server. They are not getting picked up as existing and throw up 404 errors.

Update - Fixed

Looks like we moved the server droplet and were uploading files to the wrong location.

_category can only be viewed if it's included in another file, because of the underscore. A twig file with an underscore cannot be loaded directly via the URL.

You may also read What is with the underscore in twig template filenames? or hidden templates from the Craft Docu.


Using PayPal Express with Commerce? PayPal Express is one of the payment gateways included in Craft Commerce but I can’t find an example of how to set this up. Is it something that would require a custom plugin for posting secure data to PayPal or is there an easier way to do this out of the box?

I currently have a payment form as per the Commerce example templates with everything working through the Dummy gateway but now looking to replace that form with a simple PayPal Express checkout button, returning to the order page if successful. Any examples or pointers appreciated.

The example templates work with PayPal express out of the box, there is nothing special you need to do.

You can only add PayPal Express as a Payment method when you have bought and registered Craft Commerce.

Paypal Express is an 'offsite' gateway, and it uses the exact same form as the dummy payment form but posts the form without the credit card inputs - that form then redirects you to PayPal.


Craft Commerce: Upload File Field in Order? I'm looking at Craft Commerce as a possible solution.

In the order process we want customers to be able to upload a file against their order which can then be accessed by the shop administrators. Is this possible and how would we go about that?

I have been looking through the documentation and seen nothing that clearly demonstrates this (yet!).

This is definitely possible. First create a file field to attach to your order in the control panel. Then create a file input type with a name attribute that uses the field you created name="fields[fieldName]". This would then get sent in the post request to updateCart.

<form method="POST" enctype="multipart/form-data">
  <input type="hidden" name="action" value="commerce/cart/updateCart">
  {{ getCsrfInput() }}
  <input type="file" name="fields[fieldName][]">
  <button type="submit">Upload file</button>
</form>

Then you could show the image on the cart/order using something like the following:

{% if cart.fieldName|length %}
  <img src="{{ cart.fieldName[0].url }}">
{% endif %}


Is there a way to remove or filter out duplicate entries? I have imported some data for a client, and it turns out there are some duplicates in the csv-files.

Is there an easy way to remove or filter out duplicates, either in my entries-query or in my template?

My query looks like this now

{% set dealers = craft.entries({section:'dealers'}).order('dealerName') %}

Thanks!

First you would need to figure out how to identify duplicates.

Craft doesn’t allow duplicate entry slugs; it will append “-1”, “-2”, etc. to them to keep them unique. So that would probably be a good starting point.

Use this query to get a list of all entries that have a number appended to the end of the slug. It’ll tell you the entry title, its section’s name, and the URL to edit it in the control panel. (Just update “example.com” with the actual host name.) Go through those and use your best judgement to decide which ones should be deleted.

SELECT c.title, s.name AS sectionName, CONCAT('http://example.com/admin/entries/', s.handle, '/', el.elementId) AS cpUrl
FROM craft_elements_i18n el
INNER JOIN craft_content c ON c.elementId = el.elementId
INNER JOIN craft_entries en ON en.id = el.elementId
INNER JOIN craft_sections s ON s.id = en.sectionId
WHERE el.slug REGEXP '\-[0-9]+$'


Craft Commerce 2 — Remove Line Item (and other actions) Knowing that all other actions besides update-cart has been deprecated I'm curious what needs to be passed with the action to remove a line item from the cart using a button as opposed to check a checkbox > update cart (essentially removing a click for the user).
The same would apply for +/- buttons/inputs for adding/removing from quantity.

I see in the example templates there's a checkbox input with name="lineItems[{{ item.id }}][remove]". Is it as simple as changing the input to a submit (or button submit) using the same name tag contents? Would this then also carry over to be posted via ajax in the same way as an update-cart action?

That's a long question. Trying to wrap my head around the changes as I'm just getting into Craft 3 and Commerce 2...

Is it as simple as changing the input to a submit (or button submit)
  using the same name tag contents?

Yes.

  Would this then also carry over to be posted via ajax in the same way
  as an update-cart action?

Yes.

Everything can be done on a single line item basis to the update-cart acton, just use the new param names.


How to manually run pending tasks in Craft CMS 3 I have a task that I want to run, but unfortunately I dont seem to be able to disable mod_gzip/mod_deflate on this server, so that task will not run in the background and causes the site to hang while processing the task.

Therefore, I have set the "runQueueAutomatically" config setting to false.

I want to trigger the task queue to run manually (via a cron job), but I'm not sure how. In Craft CMS 2 I could visit "/index.php?p=actions/tasks/runPendingTasks" as per the docs here https://docs.craftcms.com/v2/config-settings.html#runtasksautomatically but I can't find the same action for v3. Have gone through the docs and can't see it anywhere - can someone help?

Thanks.

Craft 3 default action to run the queue is

public function actionRun(): Response
{
    // Prep the response
    $response = Craft::$app->getResponse();
    $response->content = '1';

    // Make sure Craft is configured to run queues over the web
    if (!Craft::$app->getConfig()->getGeneral()->runQueueAutomatically) {
        return $response;
    }

    // Make sure the queue isn't already running, and there are waiting jobs
    $queue = Craft::$app->getQueue();
    if ($queue->getHasReservedJobs() || !$queue->getHasWaitingJobs()) {
        return $response;
    }

    // Attempt to close the connection if this is an Ajax request
    if (Craft::$app->getRequest()->getIsAjax()) {
        $response->sendAndClose();
    }

    // Run the queue
    $queue->run();

    return $response;
}

So all you need is Craft::$app->getQueue()->run(). Every Craft 3 project comes with a default module so you can Enhancing a Craft CMS 3 Website with a Custom Module or if You Wanna Make a Craft 3 Plugin?


How to display a list of next entries Is there a technique for displaying a list of “Next Entries”, which come from the current Channel. The solution I am using at the moment isn’t cutting it…

I’m using an Entry Offset of 1 to display Entries in a sidebar. This works OK if the Entry Detail page the user is looking at happens to be for the most recent Entry, but this quickly breaks down if displaying any other Entry, as the sidebar always displays a list starting at the second most recent Entry.

How would I display the next entries in the sequence, regardless of which Entry detail page the user is on?

Thank you

.getPrev and .getNext sounds like what you're asking for:
http://buildwithcraft.com/docs/templating/entrymodel#isSiblingOf

{% set params = {
    section: 'cocktails',
    order:   'title'
} %}

{% set prevCocktail = entry.getPrev(params) %}
{% set nextCocktail = entry.getNext(params) %}

{% if prevCocktail %}

Previous: {{ prevCocktail.title }}

{% endif %}

{% if nextCocktail %}

Next: {{ nextCocktail.title }}

{% endif %}


Get Kind of Asset Field I have an entry with one asset field and i need to determine if the 'kind' of asset is either 'json' file or 'video' file. Basically I swap my HTML based on the return 'kind'.

Any help is greatly appreciated. Craft CMS beginner.

{% set videoEntries =  craft.entries({ section: 'mediaRoomVideos' }).find %}
{% if videoEntries is not empty %}

    {% for entry in videoEntries %}
        {% set asset = entry.mediaVideo.first() %}

        {% if asset %}

            {% set json = asset.kind('json') %}
                {% if json %}
                    Do Embedded Video
                {% else %}

                    <video width="320" height="240" controls>
                        <source src="{{ entry.mediaVideo.first.getUrl() }}">
                    </video>

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

{% if json %}

Replaced with.

{% if asset.kind == 'json' %}


Relationship through Matrix field I'm having a little trouble wrapping my head around Relations through a Matrix field.

I have a Structure called exhibitors.

I have a Matrix field on a Page called rooms, This has one block type room and within that block there is an entries relationship field called exhibitors.

What I'm wanting to do is loop through the exhibitor entries and for each one, I want to find the first room they are related to via the matrix field.

I've tried various flavours of the relatedTo method, but I just can't seem to get them related, I just get null back from every one I've tried.

Here's an example of one I've tried:

{% set exhibitors = craft.entries.section('exhibitors').order('title') %}

{% for exhibitor in exhibitors %}
    {% set room = entry.rooms.relatedTo({
        sourceElement: exhibitor,
        field: 'room.exhibitors'
    }).first() %}

{{ room }} <-- Always a null entry

{% endfor %}

So, it looks as though I was overcomplicating things! All it needs to be is this:

{% set exhibitors = craft.entries.section('exhibitors').order('title') %}

{% for exhibitor in exhibitors %}
    {% set room = entry.rooms.relatedTo(exhibitor).first() %}

    {{ room }} <-- No longer a null entry

{% endfor %}


What is the correct syntax to check if a user has permission? In my plugin, I am checking to see if the current logged in user has permission to save a commerce product.

$user = craft()->userSession->getUser();
if (craft()->userPermissions->doesUserHavePermission($user->id, 'ManageClothingProducts')) {
    // yes permission
} else {
  // no permission
};

However, it seems I'm always getting into the else.

The commerce docs mention this:

  Manage [type] products

Maybe I'm not using the correct syntax? I'm only using the clothing products as an example. Ultimately I'll be checking for my own products.

Thank you for any suggestions!

The correct permission key is:

commerce-manageProductType:ID_OF_PRODUCT_TYPE_HERE

for example:

commerce-manageProductType:2

Your code would therefore be:

$user = craft()->userSession->getUser();
if (craft()->userPermissions->doesUserHavePermission($user->id, 'commerce-manageProductType:2')) {
    // yes permission
} else {
  // no permission
};

Or you could use UserSessionService::checkPermission(), which is a shortcut for checking permissions for the currently logged-in user:

if (craft()->userSession->checkPermission('commerce-manageProductType:2')


Any limit on number of Matrix Blocks? I have run into an issue where the following code will only return 100 blocks, despite the fact that there are more. Is there some limit I am not aware of? Running the latest version.

{% for block in entry.supporters.type('individuals').order('firstName') %}

Every criteria model in Craft 2 has a limit set to 100 by default. You can override it by setting a limit parameter on the model.

{% for block in entry.supporters.type('individuals').order('firstName').limit(null) %}


Singles Entry return content I am brand new to Craft so excuse me if the question seems a little simple. Is this the best way to return the contents of a 'singles' section. Does everything end up in a for loop even if you are only returning a single entry.

{% for entry in craft.entries.section('sectionHandle').limit(1).find() %}
  {{ entry.title }}
{% endfor %}

Also I am curious if 'entry' in the for loop actually means anything or is just a good symantic name to use for example could you say

{% for oranges in ...%}{% oranges.title %}{% endfor %}

It's not a simple question, but a fundamental one.

Whenever you query one of Craft's Element API services (such as craft.entries, craft.assets and craft.categories) or a relational field (such as an Entries or Assets field, i.e. entry.myAssetsField) you'll get back an ElementCriteriaModel instance.

The ElementCriteriaModel is basically a fancy wrapper for your query, which you can call methods on (such as .find(), .ids(), .first() and .last()), in order to actually pull elements based on your criteria (e.g. .section('sectionHandle')). Some methods – such as .find() – will return an array of elements (Craft actually calls .find() implicitly unless you use one of the other methods), while others will return a single element (.first(), .last()). There are also methods that can do different things entirely, such as returning an array of matching element IDs (.ids()).

In your example, you're using .find() – which means Craft will return an array of elements (even if there's only one). In such cases, it usually makes more sense to use .first(), to make Craft return a single element and avoid the for loop:

{% set entry = craft.entries.section('sectionHandle').first() %}

However, since the query may not always return any matching elements, it's usually a good idea to wrap the result in a conditional:

{% set entry = craft.entries.section('sectionHandle').first() %}
{% if entry %}
    ...
{% endif %}

The above will of course also be true for any relational fields – consider an Assets field for a "featured image"; even if you limit the field to a single image, simply accessing the field in a template will always return an ElementCriteriaModel, unless you use .first():

{# Returns an ElementCriteriaModel #}
{% set featuredImage = entry.someAssetsField %}

{# Returns an array of elements #}
{% set featuredImage = entry.someAssetsField.find() %}

{# Returns a single Asset #}
{% set featuredImage = entry.someAssetsField.first() %}

  Also I am curious if 'entry' in the for loop actually means anything or is just a good symantic name to use

It's just a semantic name – the result variable for your query can be named whatever you want:

{% set myAwesomeSingleEntry = craft.entries.section('sectionHandle').first() %}

However, a good thing to know about is that whenever Craft matches the current URL request to an element – e.g. your Single entry – it'll automatically populate your template with an entry variable. In other words, if the current page is the actual URL for your Single entry, you won't need to do any craft.entries query at all (this is true for all Entries and Categories that have URLs enabled).


Where does Craft store HTML Templates? I have recently been given access to a Craft site's control panel. I need to edit the homepage to add data in the footer. As I didn't create the Craft website, how can I access the HTML I need to add the code?
I've seen tutorials opening it from your localhost but as this is on an external server I am unaware how to access it.

It sounds like you have access to the CP, but not the server.
In order to modify the template files (usually stored in the templates directory, next to the public web folder), you'll need SSH or FTP access to the server itself.
For example, if your site's web root was here:
/home/username/website.com/web

…your templates folder is probably here, out of public view, but still accessible to Craft:
/home/username/website.com/templates

To find the template you need to edit, look in Settings → Sections -> Section Name, under the "Site Settings" heading. This table will show you what template is rendered (relative to the templates directory, above) for each type of content defined in the CP.
Depending on how the site is structured, each page may be assembled from many Twig "includes," so not all the HTML for a page will be present in the primary template!
Craft doesn't provide a template editor as part of the CP, so your only option is to edit or replace the Twig templates that live on-disk.

I strongly recommend heeding the advice you've seen, vis-a-vis working locally. Whenever possible, it's a good idea to keep a local copy of the site's files (checked in to Git or other source control)—that way, if you edit a template on the server and break something, it's easy to undo and copy an old version back.


Change user password on the front end I'm building a profile page for members on a site where members can change their password. I'm sending the request with ajax, and can successfully change password if I have the input name "password" correct with the users current password.

My problem is that I get a success-response, when I should have gotten an error-response. (Password isn't changed, but I have no way of telling the user there was en error).

My JS is something like this:

$.ajax({
    type: "POST",
    url: "",
    data: dataString,
    success: function(data) {
        console.log("Password successfully changed");
    },
    error: function(data) {
        console.log("Error. Password did not change");
    }
});

Currently the users/saveUser (and the deprecated users/setPassword) controller action doesn’t support Ajax requests, so there won’t really be an easy way to tell if it worked or not.

If you really want to update user passwords over Ajax, your best bet will be to write a plugin with its own custom controller action, which mimics the password-related stuff in UsersController::actionSaveUser(), but probably calls UsersService::changePassword() rather than saveUser() since you only care about updating the password. And have that controller respond with JSON if it’s an Ajax request, rather than assuming it’s not.

Take a look at EntriesController::actionSaveEntry() for an example of a controller action that does support Ajax.


Bold first word in title field Site design I am working on the first word of ever page title is bold. The code looks like this;

Discover Riaflex Today

I am struggling to find a simple solution to do this in Craft.

If I setup a simple rich text field then it wraps "p" tags around it. I have tried to used Markdown but this is the same and also end up with ** in the <'title'> output.

Anyone done something similar or can offer a fairly simple approach. I had a quick  attempt at editing radactor but dropped it as it didn't seem to work and remove 'p' tags.

Thanks.

You can grab the first word with the split filter according to this thread

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

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

I didn't test this tough.

Edit: there is a Twig Fiddle demonstrating it.


Best practices to name Matrix fields handles About matrix block fields handles: should they be unique ?

For instance if I have a matrix with handle galleryMatrix,
than should I name my block galleryMatrixImage or just image?
And than my fields in my block: galleryMatrixImageName, galleryMatrixImageAsset or name and asset?

I'm not quite sure about how to manage these handles the proper way?

I would prefer being able to name them with short handles, but i'm not sure if they have to be unique within a block, or unique for a whole website ?

Thanks

They only have to be unique within a block. So your initial idea would be best.
Have a galleryMatrix field with an image block and fields with handles imgName and imgAsset.

I don't think you can use name as a handle, because it is a reserved word. Asset may be possible.


Can you extend "_layouts/cp" in a plugin settings page? I'm aware that I could enable the plugin to have it's own CP section, but I don't feel that this would be the right place for it to live due to its nature, when you view the settings page it wouldn't be a list of inputs, it would be a table view.

Ideally the plugin page would reside in settings > plugins > myPlugin but have the same template as a plugin with a CP section, just like the sections settings page.

This is my template in pluginHandle/settings.html

{% extends "_layouts/cp" %}
{% import "_includes/forms" as forms %}

{% set title = "My Plugin" %}

{% set content %}
  Some content should appear here maybe?
{% endset %}

I don't get any errors when I view the page it just looks like this:

As you can see the title variable gets ignored and has taken the plugin name, but if I remove the {% set title = '' %} part it throws an error of Variable "title" does not exist.

I tried to match the basics of what the sections settings template that craft has. Am I just trying to do something that was never an intended purpose or is just bad practice ?

Any clearance would be great, thanks!

Your settings page doesn't need to include {% extends "_layouts/cp" %}.

Also there's no need to define any block section. What's in your template/settings.html file will be shown within that CP-area per default.


CraftCMS Redactor is adding  tags to viewable source code... but then removes them when saving We are in the midst of a migration from WordPress to Craft.  Much of the content contains line breaks, which are converted to <p> tags in Redactor (as seen in Redactor's view source plugin).

But when the entry is saved (or previewed, as seen in the attached image), those <p> tags are stripped back out and never make it to the database.

Is there a config setting to "retain the automatically applied formatting from redactor when the entry is saved"? (we want to keep these styles that were temporarily added in by redactor)

In the Advanced section of your field definition, there are settings for clean-up actions and Purify HTML.

I suggest trying to disable Purify (or use a custom config).


Updating Craft removed a channel from the CMS? Anyone experienced this problem?

I have a dev site set up which we updated to 2.4.2702. After updating one of my section channels has disappeared from the CMS.

The entries for the channel are still showing and I can see the channel set up in craft_sections on the database so any ideas what has happened to it and why it is no longer in the CMS?

This was resolved with the above comments from @mmikkel

  Craft Personal is limited to a single channel. Your license.key file must've been overwritten/deleted somehow when you updated – which is weird unless this was a manual update? In any case, if you have purchased a license and don't have a copy of the license.key file you'll need to contact support@buildwithcraft.com to restore it. If this is a dev build and you haven't purchased a license, just click the upgrade link in the CP footer and then the "Test" button under Craft Pro in the modal that appears.


craft_searchindex table keeps crashing On my local machine, every time I've added a new field and want to add content to it for the first time I get the following error:

  CDbException

  CDbCommand failed to execute the SQL statement:
  SQLSTATE[HY000]: General error: 145 Table
  './databasename/craft_searchindex' is marked as crashed and should
  be repaired.

A simple mysql repair table fixes it, but this happens way too often. Is there something I can do to prevent this?

TL/DR: MySQL is horrible.

The craft_searchindex table is the only table that uses MySQL's older MyISAM storage engine, instead of InnoDB (like the rest of the tables), because InnoDB didn't add support for MySQL's full text search capabilities until very recently (version 5.6.4).

One of the many drawbacks of the MyISAM storage engine, as you've discovered, is that the tables using it can crash easily.  The crashes can occur for a variety of reasons... low disk space, firmware issues, buggy MySQL, sudden server reboot, etc.

From the command line, you can run a "repair all" like so:

mysqlrepair -A --auto-repair
mysqlrepair -A -o

Or start a test that might help you diagnose why it's crashing:

mysqlrepair -A -c

Also, if you know you're running > MySQL 5.6.4 across all of your environments, you can change the storage engine for that table from MyISAM to InnoDB.


Craft entries statements failing I'm try to use related entries from different channels to display content on a home page. Using the code following with "selectNews" as a entries fieldHandle in the Home Page:

  {% set entry = entry.selectNews.first() %}
  {% if entry %}
     ...
  {% endif %}

This places field entries from craft section "news", the first & only entry. Following that is a div with the same code, but with a new entries field and fieldHandle, "messageBanner", relating to an channel named "Banners". This second set of code fails to display anything. I see that

... {{ entry }}...

tested in the failed div, outside of {%set entry =... endif %}, prints to screen the related entry title from the previous code. How can I get this fixed and what am I missing. Pretty confused.

{% set entry = entry.selectNews.first() %}
  {% if entry %}
...

   {% set asset = entry.newsImage.first() %}
      {% if asset %}

      {% endif %}

...
{% endif %}

{% set entry = entry.messageBanner.first() %}
  {% if entry %}

 some text  {{entry.bannerText}}

{% endif %}

I'm not 100% following your question, but it's likely a variable re-use issue.

Basically, you're setting the variable once, and if it exists, do blah....

Then, you're attempting to re-set that variable below.  Something goes wrong with that, but entry still exists at that point, so it passes the seconds test but in that second block  entry is still pointing to the data it retrieved in the first use.

(You might find it useful to check out:
https://straightupcraft.com/articles/testing-if-something-exists-is-defined-length-is-not-null-is-not-empty

...which has a whole lot of stuff about testing variables too)


Typogrify Line Breaks (Chrome) I've moved from Wordsmith to Typogrify because of the additional config options, which are great. I am having an issue though with line breaks appearing in  tags in Chrome in very specific cases. I have hyphenation turned off.
Link here:
https://thecinematheque.ca/films/2021/film-about-a-father-who
Break added after "Film About a Father Who" when window is around 720px wide. No idea if this is a CSS issue but I cant see anything that would cause that.
I do see a &#8203; element added near by. Not sure where that is coming from.

They both use the same underlying library, so things like this should be identical in both of them. But there was a recent GH issue that might answer this for you: https://github.com/nystudio107/craft-typogrify/issues/33


How to output transforms for retina images from one upload? I have a slide show that shows logos of different dimensions working well in HTML/CSS - the image output looks like below. I'd like to only upload one retina/hdpi image once for the entry where the asset is. I'd like to use image transforms to output the retina images but need to preserve the width and height of the original as they vary in look and dimensions. I can't find an example. I have read this post
10 times but not really seeing if this holds a solution.

HTML code:

[image tag srcset01] srcset="
    /assets/images/logos-sponsors/company1_logo.png 1x,
    /assets/images/logos-sponsors/company1_logo@2x.png 2x,
    /assets/images/logos-sponsors/company1_logo@3x.png 3x" alt="company1_logo" width="130" height="12">

[image tag srcset01]
 src="/assets/images/logos-sponsors/company2_logo.png" srcset="
    /assets/images/logos-sponsors/company2_logo.png 1x,
    /assets/images/logos-sponsors/company2_logo@2x.png 2x,
    /assets/images/logos-sponsors/company2_logo@3x.png 3x"
alt="company2_logo" width="52" height="30">

[image tag srcset01]  src="/assets/images/logos-sponsors/company3_logo.png" srcset="
    /assets/images/logos-sponsors/company3_logo.png 1x,
    /assets/images/logos-sponsors/company3_logo@2x.png 2x,
    /assets/images/logos-sponsors/company3_logo@3x.png 3x"
    alt="company3_logo" width="130" height="11">

The goal is to have the image uploaded once and then

I'd like to use image transforms to output the retina images but need
  to preserve the width and height of the original as they vary in look
  and dimensions.

This statement kind of contradicts itself. :) You want to create different sizes, but keep the width and height of the original? My interpretation is that you'll always be uploading an image that's a number of times bigger that the @1x size? Let's say you always upload these images @3x, try something like this:

{% set myImage = entry.myImage() %}
{% set baseWidth = myImage.getWidth() / 3 %}
{% set baseHeight = myImage.getHeight() / 3 %}

<img
  src="{{ myImage.getUrl({ width: baseWidth, height: baseHeight }) }}"
  srcset="
    {{ myImage.getUrl({ width: baseWidth, height: baseHeight }) }} 1x,
    {{ myImage.getUrl({ width: baseWidth*2, height: baseHeight*2 }) }} 2x,
    {{ myImage.getUrl() }} 3x"
  alt="{{ myImage.title }}"
  width="{{ baseWidth }}"
  height="{{ baseheight }}">

Hope this helps.


Craft 2.5 option to embed image with transform missing I know Craft 2.5 uses Redactor II so I assume this problem relates to this, but it would be good to get this confirmed.

Setting aside the fact you need to update the configs, I have noticed the ability to embed an image (in a Rich Text field) with a transform is no longer an option.

In Craft 2.4 there was another button adjacent to the Select button to upload an image with a pre-defined transform. This is missing.

I have also noticed that the image select modal does not close once an image is selected either by double-clicking it or pressing the select button.

Is anyone else experiencing the same issues?

This is a bug that has been fixed in the next (post 2.5.2750) release.


Dynamic Entry URI's for pages This is probably very straight forward but unfortunately I can't seem to solve it.

We want to create a dynamic URI structure that allows us to easily create pages and link them with parent directories. So basically we have 4-5 pages that need to be added as "singles". Then we have around 40 pages (with around 3-4 total layouts) that we don't want to create a "Single" for each. So we've created a "Structure" called Pages and inside have 3-4 entry types. Grid list, plain template, big image and small image. We just want to create a bunch of "pages" and specify the parent URI.

For example, we have a single "Our Company", but then inside that parent we have multiple pages which we want to add in the "Pages" structure. But as our Entry URI for "pages" is set to {slug} this URL is www.website.com/slug. We need it to be www.website.com/our-company/slug. Of course we can simply update the Entry URI to have "our-company" but this won't work as all of the Entry URI's for all 40 pages will be our-company.

So basically, how can we manually or dynamically specify the segment 1 that page's URI should be?

Not sure I'm following 100%, but in Craft 2, a structured section has a "Nested Entries" text box in the "Entry URL Format" under a section's settings where you can dynamically access the URI of a parent element in a structure like so:

{parent.uri}/{slug}

In Craft 3, under a section's Settings, that has moved to "Site Settings" and you just have the "Entry URL Format" text box.  You could do something similar like so:

{parent.uri ?? ''}/{slug}

i.e. if there isn't a parent.uri, just use the slug, otherwise use prepend it.

You've got the full power of Twig in those text boxes, so you can adjust however you need.


Custom Pluging Entries FieldType I have 2 plugins I created that store similar data:

Plugin 1: id, name, panel_id, price

Plugin 2: id, name, test_id, price

I want to attach my plugin data to an entry, and I need to make sure they can only select one Panel or Test. I want to know if there is a way to add them as a source for Entries as a new field. Or can I create a similar custom fieldtype to be used for both plugins and have that kind of validation?

I'm using Craft V2.6

You can use a Relation Field for each of your element types and include a custom js rule so if one of them has a value, the other one can't be selected.

The more difficult way would be to extend the field and the ElementSelectModal and the ElementIndex to select multiple element types but this is going to be a little bit more tricky since you'll need a custom controller to fetch all elements and can't rely on the ElementsController


Deploying Craft on AWS I made my first Craft site with MAMP locally. I am trying to get my site running on AWS but I'm having a hard time with understanding the process.
Are there any good tutorials or suggestions about how to deploy it?

The trouble is, there's no one way to utilize AWS. You can set up a simple VPS, or get endlessly complicated with load-balancing multiple servers, adding CDN, utilizing cool caching options, and plenty more.

I've been fortunate enough to learn a lot from a siteops team that established all the infrastructure. It's a bit much for getting started, but the result was a combination of Route 53 for DNS, Elastic Beanstalk+Docker+EC2 for server instances, S3 for Asset sources, CloudFront for easy CDN, RDS for MySQL, and Elasticache for Redis session storage. Craft happily worked with all these things out of the box, after some trial and error. The goal wasn't to have a single server running, but discrete components that could be scaled for stability and demand.

But that's a horrendous place to get started. While I need to write a blog post about what I've learned AWS-wise, you can get started more simply by following a tutorial for another LAMP app like WordPress since most of the setup's going to be the same. If you're comfortable with Linux, or comfortable Googling your way through various tweaks, this should be a breeze. Just pretend the AWS control panel isn't hilariously daunting and you'll be fine.

If you're looking to be a Craft-AWS pro, you could experiment in steps:

Level 1: Get Craft running on a single EC2 instance

All the stuff on one box, conceptually identical to Digital Ocean or Linode or whatever. I like Ubuntu 14.04 because I'm most familiar with it, but you can pick a Linux distribution, make sure the requirements are in place, give Craft a poke, and triumphantly point a domain name to your EC2 IP.

Solspace have created a detailed guide for this.

Level 2: Sprinkle in AWS components

This will prove that adding AWS services needn't be hard. You can easily...

Add CDN with CloudFront
Move MySQL off of your VPS and use RDS instead
Use Elasticache for Redis, and store PHP's sessions there by installing an extension and adding two lines to php.ini (session.save_handler = redis and session.save_path = tcp://your-aws-cache-url:6379)
Use Route 53 for DNS, because why not

Level 3: Automate deployments and use multiple server instances

This is where I start to gloss over: set up Docker images and Elastic Beanstalk for automated deployments, and add multiple EC2 server instances with load balancers (and sticky sessions!) that spread out traffic. You've theoretically got many of your pieces in place after level 2, so if you can master level 3 you'll basically have your undergraduate degree in AWS.

Edit May 29, 2020

While it isn’t AWS-specific, there’s a Knowledge Base article with tips for configuring Craft for multi-server environments: https://craftcms.com/knowledge-base/configuring-load-balanced-environments


How to Make a Change to an Existing Page Go Live at a Particular Point in Time In Craft, is it possible to make an edit to an already existing (live) page but be able to set a particular point in time that you want to change to go live?

I know that you can set the post date and time for when you're implementing a new page but curious if there's a similar capability for implementing a change to that page after it's already live.

Thanks!

Currently, there is not. I've dealt with this before and I actually created 2 pages, one with the future post date, and one with an expiry date. And so the future page will become active over the page that will expire, simulating the requested functionality (although this is not the preferred method, I concur)


Is it possible to grab related entries that have been attached to a certain field? So,

I want to grab all entries that are related to an entry but with the following criteria:

Only from my section ($section)
Only the ones that have been added to a certain field ($fieldId)

I currently have this:

$criteria = craft()->elements->getCriteria(ElementType::Entry);
$criteria->section = $section;
$criteria->limit   = null;
$criteria->relatedTo = array(
    'targetElement' => $element,
);
$elements = craft()->elements->findElements($criteria);
return $elements;

But if I add two relationship fields to an entry, this will return ALL the associated entries from either field. I want to limit it to just the entries attached to the one field.

Is this possible? Does the question make sense? :-)

If you want to limit your relationships to a particular field, use this syntax:

$criteria->relatedTo = array(
    'targetElement' => $element,
    'field' => $field
);

I believe 'field' will take:

1) A single or array of $field instances

2) A single or array of field IDs or field handles.


How can I use an alias for a category? I have a category group called country, with each category being the name of a country.  I used the full name of the country.
I realize I might want to use each country's 2-digit code.  For example, AU for Australia.

How might I implement the abbreviations to associate with the category?

Put another way, how can I use the 2-digit code as an alias for the full country name?

You could use the category handle.

If that doesn't suit your requirements, you can associate custom fields with categories, same as you can with entries.


Merge two queries of entries ordered by publication date I got a section called news which contain 2 types of entries:
news and press.

Those entries are linked with 2 different categories :
news entries have category newsType
and press entries have category pressType.

In twig template I want to make 2 entries listing:

one from news entries and category newstype = A
the other from press entries and category presstype = X

Then merge those 2 lists to display them ordered by publication date?

You can probably use the relatedTo parameter with multiple relation criteria:

{% set entries = craft.entries.section(['news', 'press']).relatedTo('or',
    { targetElement: newsTypeCategory, field: 'newsTypeCategoryField' },
    { targetElement: pressTypeCategory, field: 'pressTypeCategoryField' }).order('postDate desc') %}

Note that newsTypeCategory and pressTypeCategory should be category IDs (or CategoryModels) so you might need to pull the relevant categories as well:

{% set newsTypeCategory = craft.categories.group('newstype').slug('someslug') %}
...

Also note that you'll obviously need to change the field values to the real handles for your Categories fields, in the example criteria above.

An alternative approach is to use the SuperSort plugin to sort two arrays of entries on the postDate attribute:

{% set newsEntries = craft.entries.section('news').relatedTo(newsTypeCategory) %}
{% set pressEntries = craft.entries.section('press').relatedTo(pressTypeCategory) %}
{% set allEntries = newsEntries|merge(pressEntries)|supersort('sortAs', '{ postDate }') %}


Eager loading with conditions I'm working on improving the performance of my website, and for some areas, I believe eager-loading will help. On each page of the site it's possible to bring out related entries at the bottom, but these can appear in different formats: some as just titles with links, others with images, titles.

This is the twig code for bringing out one of the more complex formats:

{% set entries = craft.entries({
                section: 'block.entryTypes',
                relatedTo: 'relatedTo',
                limit: 'limit',
                id: 'notValue',
                order: 'block.order',
                postDate: '">= " ~ now|date_modify{block.until)',
                with: [
                    'leadImage',
                    'type',
                    'indexHeading',
                    'externalRedirect',
                    'posterColor',
                    'noLink',
                    'articleCategory',
                    'price',
                    'addressTable',
                    'brief'
                ]
            }) %}

Is it possible to set the "with:" section depending on the format of the list I choose? So it's something like:

{% if displayType == "teaser" %}
{% set params = "'leadImage', 'type', 'indexHeading', ... 'brief'" %}
{% endif %}
...
with: [ params ]
...

Thanks

Yeah, but you need to make sure you pass an array to the with param and you can’t compose an array by injecting a string into the [ ] like you did in your example.

Try something like this.

{% set withParam = [] %}

{% if displayType == 'teaser' %}
    {% set withParam = ['leadImage', 'type', 'indexHeading', 'brief'] %}
{% endif %}

{% if someCondition %}
    {% set withParam = withParam|merge(['anotherField', 'andOneMore']) %}
{% endif %}

{% set entries = craft.entries({
    with: withParam
}) %}