slugs in asset picker not working until page is published I have setup a page that has image asset pickers on it and image asset pickers in a matrix field.

I have setup the fields to allow a single directory and a { slug } for the normal field pickers and { owner.slug } for the matrix field destinations.

So far so good, if I work with a saved page it all works beautifully, the images get saved in the folder with the name of the page :)

But it doesn't seem to work for a new page, when I pick an image the dialog that comes up does not show the { slug } folder and when upload and select an image it shows a broken image in live preview mode. Once I save the page and go back in it all comes good.

Ok my description was poor, I am certain this is a bug, here are the details...

I have an asset repository called property-images
I have a section template with 2 image fields mainImage, searchImage and another image inside a matrix field
mainImage and searchImage are set to use a single source (property-images) with the location set to {slug}
the matrix image is the same with the location set to {owner.slug}

I create a new page and save it (so the page is created and has a slug)
I go back into the page and select mainImage, it works beautifully, and loads images into a sub folder correctly.
If i create a new matrix block and select an image, I don't get the asset in my sub folder display but some sort of tmpassets folder. OK I kind if get this, because the block isn't created yet, I don't like it but I can live with it.
Now when I look at live preview the image doesn't preview, the image url it renders doesn't exist.

So I save my page and come back in...

Now the image I picked in the block has been moved to the correct assets folder but still doesn't render anything, the transformed images aren't there

If I remove the image from the matrix block and re-pick it now it all works fine.

So it seems to explain to the content editor how to use this I need to tell them whenever they create a new matrix block they need to publish the page and come back in and then pick the image and then it's good. I can tell you that is not going to fly with this client!

I've also experimented with a page in draft but a different set of weird things results.

Oh one more thing! I'm using transforms in code, so something like:

  {% set lrg = {
                            mode: 'crop',
                            width: 1400,
                            height: 866,
                            quality: 75,
                            position: 'center-center'           }       %}
  img src='{{ image.getUrl(lrg) }}'

I wonder if predefined transforms are better?

This is expected behaviour. By dynamically creating asset folders based off the entry slug, the entry itself has to first be saved. This is so when assets are uploaded, Craft can look at the slug of your entry, create an asset folder with the same name and put the assets there.

By uploading assets to an unsaved entry, the slug doesn't really exist yet, so Craft won't know where to put your files.

As you say, the only way round this is to save your entry first, so Craft knows what to name your folders, and then on the second save add in your assets.

Correct me if I am wrong but that is my understanding of it all.


How to build a language switcher that covers entries with custom routes? I have a site with a structure and various channels, that live inside that structure.

I started with the language switcher from https://craftcms.stackexchange.com/a/26347/8325; but that will only work for the structure, because I need to build the URLs for some entries that use custom routes manually.

Now I need to build that more complex language switcher.

Here's how I did it with a macro and some custom entry IDs.

In the basic template

{# Set PIDs for important pages #}
{% set pidNews = 214 %}
{% set pidPressReleases = 208 %}
{% set pidAgenda = 224 %}
{% set pidJobs = 227 %}

{# Section Ids #}

{% set sectionIdPages = 1 %}
{% set sectionIdNews = 2 %}
{% set sectionIdEvents = 3 %}
{% set sectionIdJobs = 6 %}

{# Type Ids #}

{% set typeIdNews = 2 %}
{% set typeIdPressReleases = 14 %}

In the Langswitcher partial

{# Detail views with special routes (news,jobs,events): generate the path by hand #}
{% macro getTranslatedLink(parentPageId, entry, site, currentSite, otherUrl, loop) %}
  {% set otherEntry = craft.entries.id(entry.id).site(site).one() %}
    {% if otherEntry %}
      {% set otherSlug = otherEntry.uri %}
        {% if parentPageId %}
        {% set otherParentPageUrl = craft.entries.section('pages').site(site).id(parentPageId).one().getUrl() %}
        {% set otherUrl = otherParentPageUrl ~ '/' ~ otherSlug %}
        {% else %}
          {% set otherUrl = otherEntry.getUrl() %}
        {% endif %}
    {% endif %}
    {# return the link #}
    {{ site.name }}{{ loop.last ? '' : '|'}}
{% endmacro %}

  {% for site in currentSite.group.sites %}

      {# Set fallback value #}
      {% set otherUrl = alias(site.baseUrl) %}
      {% if entry is defined %}
        {% switch entry.sectionId %}
        {# Construct the URLs for news/mm, events, jobs detail pages #}
        {# News #}
        {% case sectionIdNews %}
          {# Press Releases #}
          {% if entry.typeId == typeIdPressReleases %}
          {{ _self.getTranslatedLink(pidPressReleases, entry, site, currentSite, otherUrl, loop) }}
          {# News #}
          {% else %}
            {{ _self.getTranslatedLink(pidNews, entry, site, currentSite, otherUrl, loop) }}
          {% endif %}
        {% case sectionIdEvents %}
          {{ _self.getTranslatedLink(pidNews, entry, site, currentSite, otherUrl, loop) }}
        {% case sectionIdJobs %}
          {{ _self.getTranslatedLink( pidJobs,entry, site, currentSite, otherUrl, loop) }}
        {# Pages #}
        {% default %}
          {{ _self.getTranslatedLink(null, entry, site, currentSite, otherUrl, loop) }}
      {% endswitch %}
      {% endif %} {# end: if entry is defined #}

  {% endfor %}

It's not extremely elegant, but it's flexible and it apparently works. So I thought I'd share it.


Craft CMS Structure: How can I display parent and child items on an active parent page? I'm currently setting up a Structure nav and am trying to set it up so that child pages only display if;

1) The child page itself (or it's sibling) is currently active
2) The parent page of that child is currently active

At the moment all I can get working is having the child pages display regardless of what page is active. Even if a page has no children, the child pages are still being shown beneath another parent page, whereas ideally those child pages would not be seen until those pages are become active.

{% set pages = craft.entries.section('about').level('1') %}

{% for page in pages %}
{% set activePage = (entry.slug == craft.request.segment(2)) %}

  {{ page.title }}&nbsp;
  {% if activePage %}
    {% set subPage = craft.entries.descendantOf(page) %}

      {% for child in subPage %}

{{child.title}}

      {% endfor %}

   {% endif %}

{% endfor %}

Is there any solution out there for this as I feel like I maybe close to getting it working. Can anybody shed any light on this?

I hope I have understand your problem..

Let's look at your code:

One sidenote: It might be good to limit your pages-selection only to active pages:

{% set pages = craft.entries.section('about').level(1).status('live') %}

First of all, store the elements of the slug in an array:

{% set slugs = craft.request.segments %}

Here is the first for-loop for the first-level elements:

{% for page in pages %}
    {% set activePage = (page.slug in slugs) %}

        {{ page.title }}&nbsp;

{% endfor %}

The important part here is to check whether the slug of the page in the for-loop is active. In your code, you checked the slug of the entry (of the currently active page, not the page in the loop) with the slug of the request. This will always yield a true result, which is what you experienced.

Using the code above you will by now receive a list of all first-level pages, the active one with labelled with class="active".

Now let's look into the second loop for the subpages.

{% set activeSubPage = (entry.level == 2 and entry.getParent().slug == page.slug) %}
{% if activePage or activeSubPage %}
    {% set subPage = craft.entries.descendantOf(page) %}

        {% for child in subPage %}

{{child.title}}

        {% endfor %}

{% endif %}

This time it is not enough to check whether the slug of the active page in the loop matches the slug of the actual page (this will show children only if the parent page is selected), we also need to check whether the parent's slug matches the active page (to show children even if the active page is one of the children itself and not the parent).

With activeSubPage we check at first, whether the page is level 2 (therefore it has a parent and we won't run into an error for an undefined attribute on pages that are level 1 and do not have a parent) and if so, whether the parent's slug is equal to the slug of the current page in the loop.

We enclose the second for-loop with an if-clause that checks both of the results, whether the current item in the loop is either  activePage or activeSubPage. The remaining code is identical to your code.

You could now check again, whether the sub-item is active, by using the same principle: {% if  (child.slug in slugs) %}active{% endif %}

Here is the complete updated code:

{% set pages = craft.entries.section('about').level(1).status('live') %}
{% set slugs = craft.request.segments %}

{% for page in pages %}
    {% set activePage = (page.slug in slugs) %}

        {{ page.title }}&nbsp;
        {% set activeSubPage = (entry.level == 2 and entry.getParent().slug == page.slug) %}
        {% if activePage or activeSubPage %}
            {% set subPage = craft.entries.descendantOf(page) %}

                {% for child in subPage %}

{{child.title}}

                {% endfor %}

        {% endif %}

{% endfor %}

I hope this helps and solves your problem. If you have any questions or if you do not understand my explanation (sorry for my bad English, I'm not a native speaker): Don't hesitate to ask!

Further improvements:

With some small improvements you could put this code into a file and use it recursively for navigations with more than two levels. In your template, you would then be able to include it like this

{% include "_includes/nav_links_withchildren" with { 'slug' : 'about' } %}

and would then include itself again to list sub-pages.


defineAttributes and rules Using this fantastic article on validation, I have written a custom validator class. Everything is working, but I'm curious about the rules and defineAttributes method(s). Most likely I'm just misunderstanding how it all works.

MyModel.php

    public function defineAttributes()
    {
        return array(
            'firstName' => array(
                'type' => AttributeType::Name,
                'required' => true
            ),
            'lastName' => array(
                'type' => AttributeType::Name,
                'required' => true
            ),
            'email' => array(
                'type' => AttributeType::Email,
                'required' => true
            ),
            'phone' => array(
                'type' => AttributeType::ClassName,
                'maxLength' => 14
            )
        );
    }

    public function rules()
    {
        $rules = parent::rules();

        $rules[] = ['email', 'Craft\MyPlugin_EmailValidator'];

        return $rules;
    }

Do I really need both? I (thought) that defineAttributes was the rules method. Everything is working properly; I'm doing a check to make sure the email is unique. I have a unique key defined on the record as well.

Thank you!

You need both because there is no way to define custom validation rules from defineAttributes().

Ultimately things like 'maxLength' => 14 in defineAttributes() automagically get normalized down to the $rules array that gets returned from the rules method, so you're just appending your custom rule onto that when you call:

$rules = parent::rules();
$rules[] = ['email', 'Craft\MyPlugin_EmailValidator'];


Class 'Craft\stdClass' not found Is there any way to initialize a stdClass?
Code is simple

    $productOrCategory  =   new stdClass();
    $productOrCategory->stockFutureDays = 0;
    $productOrCategory->stockFutureDate = date('ymd');

but im getting Fatal error:  Class 'Craft\stdClass' not found in Controller.php on line 63 and line 63 is the first line i added as code.

Solution was to call

$productOrCategory  =   new \stdClass();


List Only Available Times/Dates in Solspace Calendar I have the following code that will output the UNAVAILABLE (previously booked) times of a Target Date. How would i edit this to output (in 30 minute increments) only the AVAILABLE times with Solspace Calendar?

{% set targetDate = "2016/09/27" %}
{% set calendarHandle = "default" %}
{% set day = craft.calendar.day({
     date: targetDate,
     calendar: calendarHandle
}) %}

{% for event in day.events %}
    {{ event.startDate.format('g:i a') }} - {{ event.endDate.format('g:i a') }}
{% endfor %}

Edited to provide a cleaner solution:

This code will display different contents for available times and unavailable times in 30 min increments, and makes no assumption on how long your events are.

{% set targetDate = "today" %}

{% set events = craft.calendar.events({
    dateRangeStart: targetDate,
    dateRangeEnd: targetDate
}) %}

{% for hour in craft.calendar.day({date: targetDate}) %}
    {% set dateFirstHalfHour = hour.date.copy.addMinutes(30) %}
    {% set dateSecondHalfHour = hour.date.copy.addMinutes(60) %}

    {% set hasEventsInFirstHalf = false %}
    {% set hasEventsInSecondHalf = false %}
    {% for event in events %}
        {% if hour.date >= event.startDate and hour.date < event.endDate %}
            {% set hasEventsInFirstHalf = true %}
        {% endif %}

        {% if dateFirstHalfHour >= event.startDate and dateFirstHalfHour < event.endDate %}
            {% set hasEventsInSecondHalf = true %}
        {% endif %}
    {% endfor %}

        {{ hour.date.format("H:i") }} - {{ hasEventsInFirstHalf ? "unavailable" : "available" }}

        {{ dateFirstHalfHour.format("H:i") }} - {{ hasEventsInSecondHalf ? "unavailable" : "available" }}

{% endfor %}


Base table or view already exists Getting the following error on production environment when trying to add a new Field.

  CDbCommand failed to execute the SQL statement: SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'redacted' already exists

Anyone have any idea what could be causing this?

This turned out to be an issue with the mysql server itself, not a Craft CMS issue at all.

It appears that during a previous field addition, the database server crashed and left hanging temporary files that didn't match with the database itself.

Spun up a new database, copied the DB over and everything worked as expected.


Update cart lineItems through ajax How do I update the lineItems after I submit the form through ajax? right now it adds the item, but it doesn't show up in the cart, it only shows up when I reload the page.

I am adding an item to the cart through ajax with this code:

$('.form-products').on('submit', function(e) {

    e.preventDefault();

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

    $.ajax({
        type: 'POST',
        data: data,
        url: '/',
        success: function(response) {
            var cartCount = '(' + response.cart.totalQty + ')';
            $('.cart-count').text(cartCount);

            $('#cart').removeClass('close');
        },
        error: function(response) {
            console.log(response);
        }
    });

});

Then under the  div#cart I have this code:

{% for item in cart.lineItems %}
   <li>
     cart information goes here
     this shows the product images, price and other info.
   </li>
{% endfor %}

There are two major approaches.

The easier approach is to create a partial template that displays the cart lineItems, and simply ajax load that template in to a div that is your cart display after you've done the lineItem update.  However, this has the disadvantage of making the whole cart section update in a visible way, which look a lot less finessed than the second approach.
In  short, you'll need to use the cart object in the json response to re-draw just the appropriate parts of your cart display.

Here's an example of approach 2, (don't focus on the specifics below which are from a live site - but rather this should be enough to give you the idea) - if the user e.g. adjusts line item quantities, we grab the appropriate parts of response.cart and then do some local calculations and update the appropriate parts of the page:

            $.post('/actions/' + $('input[name=action]').val(), form.serialize(), function(response) {

            // Change in qty successful
            if (response.success) {
                if (response.cart.lineItems[id]) {
                    var subtotalNew = parseFloat(response.cart.lineItems[id].price * response.cart.lineItems[id].qty);
                    utilities.replacePrice($subtotal, subtotalNew);
                }

                navCart.update(response.cart);
                cart.update(response.cart, true);
            }

...where, for example, utilities.replacePrice is:

replacePrice: function($obj, price, discount) {
    var text = module.exports.currency(price);

    // Handle discounts
    if (discount) {
        // Supplied as negative number - because we want it formatted differently, we make it positive
        var discountPrice = module.exports.currency(price * -1);
        text = '- (' + discountPrice + ')';
    }

    $obj.fadeOut("fast", function(){
        $obj.text( text );
        $obj.fadeIn("fast");
    });
},

...and the cart.update functions are similar and take care of updating the nav bar cart and the totals and shipping sections.

I will warn you that implementing in full a completley ajax updating cart page is a fair bit of work and complexity to get right, and the actual implementation will depend greatly on your checkout flow, which you should have thoroughly worked out BEFORE you implement this, or you can quickly tie yourself in JS knots.

If you want to see a fairly completely ajaxed Commerce cart in action, add this to your cart and then visit your cart and muck about changing quantities and removing things etc:
https://imagescience.com.au/products/inkjet-print-retouching-kit


How to pull the first block of its kind from a Matrix? This is a news feed with a title, image and short blurb beneath. The entry content is built with the Matrix. An entry can be made up of a single 'textEditorBlock' or multiple 'textEditorBlock'.

I just want to return the first 'textEditorBlock' from Matrix. Currently, all existing 'textEditorBlock' blocks get returned.

{# Count the number of Matrix Blocks; type: textEditorBlock  #}
{% set blocks = post.buildStory.type('textEditorBlock') %}
{{ blocks | length }}

{% for block in post.buildStory.all() %}
   {# the text #}
   {% set paragraphs = block.textEditor %}
   {% set teaser = paragraphs | length > 75 ? paragraphs | slice(0, 250) ~ '...' :  paragraphs %}
   <p>{{  teaser  | striptags | raw | typogrify  }}</p>
{% endfor %}

Note: the {{ blocks | length }} tells me the number of 'textEditorBlock' that exist for each entry (1, 4, 4, 2 and 2).

You could try something like this:

{% set block = post.buildStory.type('textEditorBlock').first() %}
    {{block.textEditor}}


Moved server (centOS7) "Please ensure that $craftPath is set correctly" I previously ran Vesta CP on Ubuntu and wanted to run something a little faster so chose centOS7 minimal. Installed Vesta CP and restored my backup. All my sites are running fine. Except for the ones running Craft CMS.
I would like to stress that the backup worked perfectly before
I get the error "Please ensure that $craftPath is set correctly"
Now I'v been (honestly) trying for the past 6 hours to fix this on my own but I can't figure it out.
PHP runs as adminBOB (determent using: )
And checking my chmod the user and group are adminBOB:adminBOB (same as if I make a new folder or upload a new file)
Apache/httpd runs as "apache:apache" changing the owner of all my files for this site doesn't make the error go away either.
I'm also my http.conf (and tried php.ini) configured to have:

php_admin_flag safe_mode off
php_admin_value open_basedir none

So I'm almost certain those two are not on.
Everything (folder/files) wise is the same. Same control panel (that installs all services)
I have no idea what to do next to try and get CraftCMS working again.
Please assist! Thank you!!

So as it turns out Vesta has a funny way of handing httpd config files.
There was another one tucked away somewhere where "open_basedir"
They are kept in "/home/admin(username)/conf/web/httpd.conf"

Removing that fixed it.

Such a pain, tooks me hours to figure out something so simple.
I had already removed it from the httpd.conf in the default location.

Something to keep in mind if anyone has the error and is running VESTA CP!


Where to call hook modifyImportRow? I'm using this Import plugin https://github.com/boboldehampsink/import.
 It has a hook called modifyImportRow, which would let me process single .csv rows with my custom logic.

In this case I have to process a Matrix field.

I'm not sure where and how to call hooks in general. In the plugin? In another plugin like businessLogic? Is there a specific file?

You'd do it from another plugin, just as if you were latching onto any of Craft's native hooks.

https://craftcms.com/docs/plugins/hooks-and-events

You can use the businessLogic plugin as a starting point or use https://pluginfactory.io to generate boilerplate plugin code.


Getting errors back to a template whilst in an event I have a plugin which is trying to create a user whilst inside the Charge plugin's onBeforeCharge event.

Here's the relevant code in MyPlugin.php:

craft()->on('charge.onBeforeCharge', function(Event $event){
    $newUser = new UserModel;

    $newUser->firstName = craft()->request->getPost('firstName');
    $newUser->lastName  = craft()->request->getPost('lastName');
    $newUser->username  = craft()->request->getPost('username');
    $newUser->email     = craft()->request->getPost('email');
    $newUser->password  = craft()->request->getPost('password');

    if ($newUser->validate()) {
        // create user
    } else {
        MyPlugin::log('User supplied details were invalid, attempting to redirect with errors.', LogLevel::Error);

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

        $route = craft()->urlManager->parseUrl(craft()->request);
        craft()->runController($route);
        craft()->end();
    }
}

My problem: this logs my message to the MyPlugin log, and it redirects the page back to the calling template: but "myErrors" is blank. Nothing available.

What am I doing wrong?

Rather than ending the request in your plugin, you should probably set $event->performAction = false, add your errors to the charge model and return control to Charge to add it's own error message and return to the calling template template.

So your code should look more like this:

craft()->on('charge.onBeforeCharge', function(Event $event){
    $newUser = new UserModel;

    $newUser->firstName = craft()->request->getPost('firstName');
    $newUser->lastName  = craft()->request->getPost('lastName');
    $newUser->username  = craft()->request->getPost('username');
    $newUser->email     = craft()->request->getPost('email');
    $newUser->password  = craft()->request->getPost('password');

    if ($newUser->validate()) {
        // create user
    } else {
        MyPlugin::log('User supplied details were invalid, attempting to redirect with errors.', LogLevel::Error);

        // Add our error message to the charge object
        $chargeModel = $event->params['charge'];
        $chargeModel->addError('myErrors', 'Invalid user details supplied');

        // Stop the payment from proceeding
        $event->performAction = false;
    }
}

In your template you should be able to access the errors by calling charge->getErrors().

If you supply a parameter to the getErrors() function you will only get those errors back. So if, as above, we add a custom key to the error, we can query for that in the template like this:

{% set myErrors = charge.getErrors('myErrors') %}
{% if myErrors | length %}
    {# Oops! Something went wrong, let's handle that… #}
{% endif %}


Allow registered end-user to update entry, but limited only to specific fields (Craft 3) I want to allow end-users (registered as users in Craft) to update only specific fields of an entry. I know that only those fields included in the form are being updated; but this isn't secure enough.

I'm looking for a way to manipulate the form POST request sent to the 'entries/save-entry' controller so that only specific fields will be updated. I know how to access the onBeforeSave event so that I can manipulate the entry object that will be saved to the database. I already use this to make sure that the user can only update one specific entry (because including the entryId in a hidden form field isn't secure enough).

However, I don't find a clever way to include only certain fields. The only way that comes into my mind is to overwrite all fields in the entry object that the user is not allowed to update with the current values from the database. This way is cumbersome because that entry type has so many fields.

Any idea how to filter the element so that I can supply an array with field names that will be included in the save process?

Best regards,
Mischa

You can include a custom Behavior like the ContentBehavior/ FieldLayoutBehavior in Craft 3 and handle those by yourself. This way you'll be able to handle permissions by yourself. There are certain Control Panel Hooks to include custom HTML.

Create a custom Behavior that's kind of a wrapper for the usual ContentBehavior
Store "special/extra" fields for those Elements in a custom table
Render those extra fields in a custom panel/tab
store those new values in your custom Table in beforeSave and afterSave funktions

But in general creating a custom Element Type would be easier to achieve, since you'll have more possibilities and more freedom to do what you want


Get email address from registration form I have a user registration form setup to redirect to another template on submit. That template then includes the following:

{% set email = craft.app.request.getBodyParam('email') -%}
<p>Thank you for registering. An email has been sent to {{ email }}…

Why does getBodyParam('email') always return empty here? getBodyParams() also returns an empty array.

Why does getBodyParam('email') always return empty here?

Because that method is looking for data in POST, and after the redirect has happened, it's a new request, and POST data is lost.

If you want to do what you're looking for, the easiest way is to pass the email address along as a query string param (i.e. ?email=foo@bar.com), then the template can do craft.app.request.getQueryParam('email').


How do I get started with Element API plugin? I'd like to use the Element API plugin.
I've follow the instructions mentioned here: ElementAPI - Can I use javascript/ajax to load json

Here is my config/elementapi.php file :

<?php
namespace Craft;

return [
    'endpoints' => [
        'news.json' => [
            'elementType' => 'Entry',
            'criteria' => ['section' => 'news'],
            'transformer' => function (EntryModel $entry) {
                return [
                    'title' => $entry->title,
                    'url' => $entry->url,
                    'jsonUrl' => UrlHelper::getUrl("news/{$entry->id}.json"),
                ];
            },
        ]
    ]
];

and here my ajax request:

    $(function () {
        var data = {
            'CSRF': $('input[name="CRAFT_CSRF_TOKEN"]').val(),
        };

        $.ajax({
            'type': 'post',
            'contentType': 'application/x-www-form-urlencoded; charset=UTF-8',
            'cache': false,
            'data': data,
            'url': 'news.json',
            'dataType': 'json',
            'timeout': 50000
        }).done(function (response) {
           console.log(response);
        }).fail(function (error) {
                console.log('totalfail')
            });
        });

But it always returns a 400 error (as the JSON file looks like it doesn't exist).

What have I missed? Could someone provide a working example?

Thanks!

There was a mistake in the ajax request. I was using POST instead of GET.

1) After installing the plugin :

Add elementapi.php to your /craft/config/ directory

<?php
namespace Craft;

return [
    'endpoints' => [
        'news.json' => [
            'elementType' => 'Entry',
            'criteria' => ['section' => 'news'],
            'transformer' => function (EntryModel $entry) {
                return [
                    'title' => $entry->title,
                    'url' => $entry->url,
                    'jsonUrl' => UrlHelper::getUrl("news/{$entry->id}.json")
                ];
            },
        ]
    ]
];

2) Enabling CSRF Protection
add 'enableCsrfProtection' => true to your /craft/config/general.php file.

3) getting entries with ajax :

_layout.html

<head>
...
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js">  </script>
<script>
    $(function () {
        var data = {
            'CSRF': $('input[name="CRAFT_CSRF_TOKEN"]').val(),
        };

        $.ajax({
            'type': 'get',
            'contentType': 'application/x-www-form-urlencoded; charset=UTF-8',
            'cache': false,
            'data': data,
            'url': 'news.json',
            'dataType': 'json',
            'timeout': 50000
        }).done(function (response) {
            console.log(response);
        }).fail(function (error) {
                // Total fail.
            });
        });
    </script>
</head>

<body>
<div id="container">
    {{ getCsrfInput() }}
...


Craft admin twig templates broken somehow I am a front end designer building my site locally. This is the first time I've built in Craft and things have been coming along fine but now I'm getting the following error on every craft admin page and I'm not sure what's happened or how to fix it.

  Twig\Error\SyntaxError: The block 'content' has already been defined
  line 256. in
  /Users/jinora/sites/janahoffmann/_repo/v4/vendor/craftcms/cms/src/templates/_layouts/cp.html:274

The front end of the site seems fine and still loads all the templates and entries.

I had just changed an asset field to use a different folder and they weren't loading on the front end so I went into utilities and tried clearing the database cache and that's when the admin stopped working.

I had recently named a block in my templates 'content' but it had been working fine for a little while and I tried renaming the block but that didn't fix anything.

I had noticed that there was a new craft update but hadn't got to it before so I tried using terminal to update it as per this docs page (since I can't get to the control panel update) https://docs.craftcms.com/v3/updating.html#updating-from-the-control-panel. Weirdly it says the following...

Craft isn’t installed yet!

  Fetching available updates ... done You’re all up-to-date!

I took back ups and then tried clearing the storage/runtime/cache and compiled_templates folders, I restarted mamp and closed the browser but still nothing. I haven't messed around with anything outside the web or templates folder before this so I'm completely stumped as to what's happened and how to fix it.

Can anyone point me in the right direction?

Sorted YAY!

In case this is helpful to anyone, I tried deleting and reinstalling via composer then replacing the config and .env files but no luck there so I downloaded the latest version and updated just the vendor folder. It needed to update the database which it couldn't do for me so I took a manual backup and let it do it's thing and now it's all working again!


Nested category navigation I am trying to achieve the following markup for my categories navigation:

Top Category One

Sub Category One A

Sub Category One B

Sub Category One C

Top Category Two

Sub Category Two A

Sub Category Two B

Sub Category Two C

If have the following code which is nearly working:

{% set categories = craft.categories.group('projectType').all() %}
{% for category in categories %}
  {% if category.level == 1 %}

{{ category.title }}

  {% endif %}
  {% if category.level == 2 %}

{{ category.title }}

  {% endif %}
{% endfor %}

I am just missing the wrapping
 tags around the subcategory list items. Is there a way I can achieve this? The category group is limited to 2 levels so I can use the category.level if statements without a problem.

Thanks for any pointers!

You'll need to use the {% nav %} tag to output nested
s as documented here:
https://craftcms.com/guides/displaying-a-navigation-for-a-structure-section

{% set categories = craft.categories.group('projectType').all() %}
{% nav category in categories %}
  {% if category.level == 1 %}

{{ category.title }}

  {% else %}

{{ category.title }}

  {% endif %}
  {% ifchildren %}

      {% children %}

  {% endifchildren %}
{% endnav %}

This answer should help too:
https://craftcms.stackexchange.com/a/4453


Exclude certain entry types from Entry URL format? I’m trying to find a way to ‘group’ pages in a structure, where that group page has no function other than to visually organise the entries in the structure, and does not need to be part of the url structure.. eg:

- Major Campaigns
   type: landingPageGroup
   slug: major-campaigns

    - Moving Office
       type: landingPage
       slug: moving-office
       uri: /moving-office

        - Your Moving Checklist
           type: landingPage
           slug: your-moving-checklist
           uri: /moving-office/your-moving-checklist

- Major Events
   type: landingPageGroup
   slug: major-events

    - Conference 2016
       type: landingPage
       slug: conference-2016
       uri: /conference-2016

        - Agenda
           type: landingPage
           slug: agenda
           uri: /conference-2016/agenda

If I set the Entry URL Format to:

Top level: {% if entry.type != 'landingPageGroup' %}{slug}{% endif %}

Nested: {% if object.parent.type != 'landingPageGroup' %}{parent.uri}{% endif %}/{slug}

...the URLs look correct in the entries listing, but it will throw a 404 when you try to access them... is there anyway I can get around this with some custom routing maybe?

I don't know of good, non-hacky way to do what you're doing.  Every entry in a structure should have some meaning otherwise you're going to fight the system.

Is there a reason why those top level landingPageGroups are just "vestigial" and serve no purpose? That would make them good candidates to break into separate sections. So Major Campaigns would be a new structure section, Major Events would be another new structure section, etc.

You could probably hack your web server to rewrite slugs so that /major-campaigns/moving-office becomes /moving-office but for every section you add, that becomes a nightmare.

Even if you think you'll use one template across the board, it's inevitable that at some point you'll be using different templates for each "section" as well. I don't know your content strategy but if you only use one section, your entry types will likely multiply too.


How can I grant front-end access to an entry that belongs to the current user? How would one go about showing a link on the front end if this entry belongs to the current user? I was thinking it had something to do with the UserModel's can(), but I don't see any documentation of it.

Right now I'm showing an "Edit Page" link once someone is logged in, but I don't want to show a that link on a page that the current user doesn't have access to edit.

Any thoughts on this?

Edit

I was hoping something like this would work but it doesn't :( :

{% if entry.author == currentUser %}
    Edit Page
{% endif %}

You can check if the current user can edit an entry by using this  as your conditional:

{% if entry.isEditable() %}
    Edit Page
{% endif %}


How can I build a combined search without making all fields required? I'm trying to build a form where users can search for events based on a date range, location and price range. I've got the form working, but having a bit of trouble when some fields/ selects are left blank.

The desired functionality should be that none of the fields should be required.

For example: If I select a location, I would like to see all events at that location even if the dates and price ranges are left blank. Or if all fields are left blank, I should see all events.

This is a stripped down version of my form:

`<form action="{{ url('results') }}">

<input type="text" name="dateFrom"> //this is a datepicker
<input type="text" name="dateUntil"> //this is a datepicker

<select name="country">
  <option></option>
  <option value="france">france</option>
  <option value="belgium">belgium</option>
</select>

<input type="text" name="priceMin">
<input type="text" name="priceMax">

<input type="submit" value="Go">
</form>`

And here's what i've got on my results page

`{% set country = craft.request.getParam('country') %}
{% set dateFrom = craft.request.getParam('dateFrom')|date("Y-m-d") %}
{% set dateUntil = craft.request.getParam('dateUntil')|date_modify("+1 day")|date("Y-m-d") %}
{% set priceMin = craft.request.getParam('priceMin')  %}
{% set priceMax = craft.request.getParam('priceMax') %}

{% set results = craft.entries({
  section: 'events',
  order: 'score',
  start: '>=' ~ dateFrom,
  end: '<=' ~ dateUntil,
  country: country,
  price: [
    'and',
    '>=' ~ priceMin,
    '<=' ~ priceMax,
    ]
}) %}

{% if results|length %}

{{ results|length }} results:

  {% for entry in results %}

{{ entry.title }} - {{ entry. price }}

  {% endfor %}

{% else %}

Your search didn’t return any results.

{% endif %}`

Anyone have any suggestions?
Thank you!

When you submit the form you have above, it's already going to have those parameters in the URL even if they have no form values selected.

http://example.com/?dateFrom=&dateUntil=&country=&priceMin=&priceMax=

But you may have the need to directly link to http://example.com/?country=France, or empty parameters may cause errors in your template. If that's the case you probably need to define default values for missing and empty parameters. The easiest way to do this is with the Twig default filter.

{% set country = craft.request.getParam('country') | default(null) %}

The null value should work as a default for some parameters. If there are other parameters you can't easily create a default for or you only want to use parameters if they're defined, you could create an array of your default options, and then use the Twig merge filter to add more options based on conditions.

{% set options = {
  section: 'events',
  order: 'score'
} %}

{% if dateFrom %}
  {% set options = options | merge({ start: '>=' ~ dateFrom }) %}
{% endif %}

{% set results = craft.entries(options) %}

Optionally, you can use the ternary operator shorthand syntax instead of {% if dateFrom %}. Whichever is easier.

`{% set options = dateFrom ? options | merge({ start: '>=' ~ dateFrom }) : options %}`


Grabbing an asset field from Page A to display on Page B I'm trying to display an asset that the client has selected to show up on the main page, and have it display on a totally different page. This sounds simple but I keep getting errors (and im learning).

Main page asset:

{% for asset in entry.donateHeaderImage %}
   <img src="{{ asset.url }}">
{% endfor %}

Not sure how to display that asset on a different page in Craft.

First you need to get the entry for the main page. There are a number of ways you might do that (check the craft.entries documentation). One would be to fetch it by section handle, so assuming the main page has section handle of mainPage, you can do this:

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

And then you can get the from the main page asset as before:

{% for asset in mainPage.donateHeaderImage %}

{% endfor %}

To be safe, you should always handle the possibility that craft.entries won't return anything (maybe the mainPage section handle changed).

So either test it:

{% set mainPage = craft.entries.section('mainPage').first %}
{% if mainPage %}
  {% for asset in mainPage.donateHeaderImage %}

  {% endfor %}
{% endif %}

Or use the powerful null-coalescing operator:

{% for asset in craft.entries.section('mainPage').first.donateHeaderImage ?? [] %}
  ...


Additions to extraAllowedFileExtensions not showing up in the checkbox list When adding 'extraAllowedFileExtensions' => 'css' to /craft/config/general.php it doesn't show up in the list below Restrict allowed file types?. Am I missing something? Is it just not "restrictable" to an added filetype?

It's not "restrictable", because you just added it. Why would you then go back and restrict it?

Using extraAllowedFileExtensions doesn't change the checkbox list at all. It simply allows you to upload files in addition to what is available on that list.


Retour Regex to insert a new directory I'm building out a new site and have moved all the existing client asset upload directories into one parent directory.

old site:

/hero/

/books/

/slider/

new site:

/uploads/hero/

/uploads/books/

/uploads/slider/

When adding a redirect in retour how can I set up a regex to catch all images/files in the various directories and point them at the new structure.

Unless absolutely everything has been moved to /uploads/ (which is unlikely), the easiest way to do it is with 3 regex's:

/hero/(.*) -> /uploads/hero/$1

/books/(.*) -> /uploads/books/$1

/slider/(.*) -> /uploads/slider/$1

vide: regexr.com


Ordering Structure Sections with Structure Handles I am using the code below to output a group of sections that have entries along with their section handle. How would I order the sections (ideally by structureId)? I'm not opposed to using supersort but I haven't been able to achieve the desired result.

{% set sections = craft.sections.getAllSections() %}
{% set entries = craft.entries.section(['first', 'second', 'third']) %}
{% set grouped = entries|group('section') %}

{% for sectionHandle, sectionEntries in grouped %}
    {% set groupSection = false %}
    {% for section in sections %}
        {% if section.name == sectionHandle %}
            {% set groupSection = section %}
        {% endif %}
    {% endfor %}

    {% if groupSection %}
        <h1>{{ groupSection.name }} - {{ groupSection.handle }}</h1>
    {% endif %}
{% endfor %}

Use SuperSort or write your own Twig filter for it. Craft/Twig don't come with a sort filter to sort by key and replicating the functionality  (storing array keys, nested loops) is possible but kind of messy and also not performing as well.

I can understand the desire to not be reliant on too many plugin, but the functionality you need from SuperSort is simply a wrapper for a PHP function, so you can easily swap it out for another plugin if ever necessary.

It is also a great opportunity to start looking into plugin dev, write your first Twig extension or a simple Template Variable might just do it.


Redactor deleting   and other inline markup I'm running the latest version of Craft
Craft Pro 2.5.2760
I've tried this on a vanilla install and on a current site where the issue was highlighted initially.

If I copy and paste "this is some text" into a richtext field, regardless of "Clean up HTML" and "Purify HTML" options being checked or not, when I press save or switch into and out of HTML mode I'm left with

 "this is" where the text within the  and  tags have been stripped out.

If the markup looks like

this is some text

everything is fine, nothing gets stripped out.

There is clearly an issue with

 and  and possibly other tags.

A work around I've found is using in a custom .json in the redactor folder in config.

pasteInlineTags: ['b', 'i']

which instantly removes the b and i tags on paste, however this removes the formatting that the user is trying to copy and paste in which kind of defeats the point of being able to copy and paste.

So I need a solution that will allow the copy and paste of content from word, or pages or another system where the b and i tags are not stripped out immediately.

Just to cover myself I have also tried removing all plugins to see if any of them were causing an issue but again this had no impact.

Thanks in advance for your help you lovely people.

Imperavi fixed this in Redactor II 1.2.2, and we included that update in Craft 2.5.2763.


How can I update custom order fields in the frontend I am struggling with using additional custom order fields. (Added in the Craft Commerce settings at "order fields", in the field layout manager)

I try to update them like this in the checkout process:

<form method="POST">
    <input type="hidden" name="action" value="commerce/cart/updateCart">
    <input type="text" name="myCustomField" value="Test123">
    ...
    <input type="submit" value="Update Custom Field">
</form>

But in the Order in the CP, the field stays empty. Do I have to use another name for the field, like fields[myCustomField] or whatever?

I can update them in the CP, but not from the front-end...

Correct, you need to use fields[customFieldName] as the input name.

The following form should do it:

<form method="POST">
    <input type="hidden" name="action" value="commerce/cart/updateCart">
    <input type="text" name="fields[myCustomField]" value="Test123">
    ...
    <input type="submit" value="Update Custom Field">
</form>


DeleteStaleTemplateCaches/tasks error I've got the ol’ DeleteStaleTemplateCaches issue breaking the Craft task manager/process. I've tried switching the offending task over to error from running but is still stuck.

Any thoughts on debugging/resolving? Can I just clear out the tasks table?

You can use this to help debug why tasks sometimes get "stuck": https://craftcms.com/help/stuck-tasks


How to create a category filter for a portfolio site? I want to create a category filter similar to this website http://www.mypoorbrain.com/ (just a random website i found with the desired effect). Basically I want the categories to be displayed somewhere (All | Design | Web | Illustration) with the projects below. When a category is clicked, the projects shuffle to display just the projects with that category (not going to a new page).

I've looked through other category questions on here, and can't seem to find exactly how to do it (although I'm still pretty new to Craft, so I might not know what to look for with this).

Here is the code I have for the category loop (the filter)

Note: I have all of the categories I want (except for "All", not sure how to handle that) in the category group "Projects".

{# Create a category query with the 'group' parameter #}
{% set myCategoryQuery = craft.categories()
    .group('projects') %}

{# Fetch the categories #}
{% set categories = myCategoryQuery.all() %}

   {# Display the navigation #}
   {% nav category in categories %}

{{ category.title }}

   {% endnav %}

And here is my current code for the project loop:

{% set projects = craft.entries.section('projects').all() %}
{% for entry in projects %}

      {% set projectImg = entry.featuredImage.one() %}

{{ entry.title }}

 Category

{%endfor%}

So how can I accomplish this?

The site you linked to is using Isotope to achieve this effect. Isotope is simply a JavaScript filtering library - it's all front-end so really this has nothing to do with Craft, unless you want to load entries dynamically via AJAX.

(Most Isotope implementations I've seen simply load everything and then hide/show the relevant ones when clicking on filters... It depends how many items you have as to whether it's worth loading them in dynamically, but it's a lot simpler to load everything in one go).


Element API using the entries field to display related content from a separate section I've seen similar questions but none seem to help.
I have two sections named jobs and jobDescriptions. I'm using the entries field to pull in a description field from the jobDescriptions section to the jobs entry. I need to output the related description field to the element api but I'm stuck. No idea where to go from here.
The other issue is that I also have a field in the jobs section that is named descriptionOverride. I want to show the descriptionOverride field if it has a value instead of the related field.
<?php

use craft\elements\Entry;
use craft\helpers\UrlHelper;
use craft\elements\Tag;
return [
    'endpoints' => [
        'jobs.json' => function() {

            return array(
                'serializer' => 'jsonFeed',
                'elementType' => Entry::class,
                'criteria' => array('section' => 'jobs'),
                'transformer' => function(Entry $entry) {

                    return array(
                        'title' => $entry->title,

                        {# pulling the description field from the jobDescriptions section using the entries field relatedJobDescriptions in the jobs section. I'm obviously
way off base. #}
                        'description' => $entry->relatedJobDescription->description,
                    );
                },
                'meta' => array(
                    'description' => '',
                ),
                'pretty' => true,
            );
        },

        'jobs2.json' => function() {

            return [
                'serializer' => 'jsonFeed',
                'elementType' => Entry::class,
                'criteria' => ['section' => 'jobs'],
                'transformer' => function(Entry $entry) {

                    return [
                        'title' => $entry->title,
                    ];
                },
                'meta' => [
                    'description' => 'Recent news from Happy Lager',
                ],
                'pretty' => true,
            ];
        },
    ],
];

If relatedJobDescription is an Entries field, accessing the field from your jobs entry will not return the selected jobDescriptions entry directly. Instead, you will get an EntryQuery which you can use to get the selected jobDescriptions from the database. See Working with Entries Field Data and Querying Entries.
To get the jobDescriptions entry, you can use ElementQuery::one() (if your field allowed for multiple related jobDescriptions entries, you could use ElementQuery::all() instead).
Regarding the descriptionOverride, that's just a matter of checking if the override field contains some text and if it does, return it instead of the related job description.
Something like this should work:
// get the entry holding the related job description
$relatedJobDescriptionEntry = $entry->relatedJobDescription->one();
// handle an empty relatedJobDescriptions field gracefully
$relatedJobDescription = $relatedJobDescriptionEntry ? $relatedJobDescriptionEntry->description : '';
// get the description override from the current entry
$descriptionOverride = $entry->descriptionOverride;
return array(
    'title' => $entry->title,
    // return either the overridden description or the related job description
    'description' => ((string) $descriptionOverride) ?: $relatedJobDescription,
);

You can optimize this further to only retrieve the related job description if the override is not set.


Select entries starting with same letter from alphabet list I have a list of all my games using pagination. It works great:
http://www.colorcomputergames.com/games

However, I'd like to add links at the top of the page like:
A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z

And so I want to be able to click on any letter and display only entries starting with that letter.

I was was going to make a template for every page but that seems inefficient.

How should I tackle this?

First, you should create a dynamic route (something like "games/glossary/<slug>") and point it to a template. A dynamic route means you won't have to create a template for every letter. Note the use of the <slug> token, which – although not entirely semantic – should do nicely in this case.

In your template, you'll need to pull the letter from the URL. Note that it's also a good idea to test if the variable is a single character, and in the a-z range (i.e. a valid letter, and not some other entity).

{% set letter = slug is defined and slug|length == 1 and slug matches '/^[a-z]/i' ? slug %}

If there is no valid letter in the slug variable, it's a good idea to throw a 404:

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

Next, you can actually use search syntax for the title parameter (specifically, a wildcard *), in order to pull all entries with a title starting with the relevant letter:

{% set entries = craft.entries.section('games').title(letter~'*').limit(null).order('title asc') %}

If you want to throw a 404 whenever there aren't any entries for any given letter, it's simply a matter of testing the length property for entries:

{% if not entries|length %}
    {% exit 404 %}
{% endif %}

If you need pagination in your template, it'll work out of the box as usual:

{% paginate craft.entries.section('games').title(letter~'*').limit(10).order('title asc') as pageInfo, pageEntries %}

{% if not pageEntries|length %}
    {% exit 404 %}
{% endif %}

{% for entry in pageEntries %}
    ...


Sorting entries A-Z, ignoring 'The' and grouping by first letter Probably going to be an easy win for someone here, but being able to do this is currently eluding me. So:

I'm trying to output a list of Artist names grouped by first letter but need to ignore 'The ' when it appears at the start of an Artist name.

To do this, I've added a 'Sort Title' field to the Artist entry (as I figured there might be other occasions where this could be useful) - and using Brad's answer here this works fine when outputting a standard alphabetical list.

However, there's also a page that needs to display the Artists grouped by first letter. Code for that currently is:

{% for letter, artists in craft.entries.section('lineup').order('title') | group('title|upper|slice(0, 1)') %}

How best could I adapt that to use my sortTitle field (when it isn't empty) to group the Artist entries? I get 'Expected name or number' if I try to use Brad's code in place of 'title'.

That SQL code snippet Brad posted only works with the order parameter.
The group filter doesn't allow SQL, but you could try to replicate the logic using Twig's ternary operator.

{% set artists = craft.entries.section('lineup').order('(CASE WHEN field_sortTitle IS NULL OR field_sortTitle = "" THEN title ELSE field_sortTitle END)') %}
{% set artistsGrouped = artists|group('{ object.sortTitle ? object.sortTitle[:1]|upper : object.title[:1]|upper }') %}

{% for letter, artistsInGroup in artistsGrouped %}
    {{ letter }}
    {% for artist in artistsInGroup %}
        {{ artist.title }}
    {% endfor %}
{% endfor %}

To shorten the expression a bit I used the slice filter's short syntax [:1] instead of |slice(0, 1).


How to block direct access to templates (hiding templates) How can I prevent people accessing templates directly that are only used as includes for instance?

I read that I could add an underscore ie _example.html,but then the include stops working.

If your template is _example.html, you include like this:

{% include '_example.html' %}

It also works to have a template in a directory that starts with an underscore. So you could name the directory _includes, name the template in there example.html and include it like this:

{% include '_includes/example.html' %}

Either way, the template can't be accessed directly.


Pagination / Custom Routes (Based on Entry Existing) I've created a custom route for my entries based on week like so:

'events/(?P<year>\d{4})/(?P<week>\d{2})' => 'events/_weekindex',

I know i can group entries by week like this:

{% set allEntriesByWeek = allEntries|group('postDate|date('Y-W')') %}

What i'm not quite sure how to do is how to show navigation ONLY for weeks that have entries present, and then of course output the entries in my template when those navigation items are clicked.

For generating the nav, this should work.

{% set allEntriesByWeek = allEntries|group("postDate|date('Y-W')") %}
{% for week, entry in allEntriesByWeek %}

{{ week }}

{% endfor %}

For grabbing entries (using the 'week' and 'year' variables passed via the route).

{% set startDate = now.setISODate(year, week) %}
{% set endDate = startDate|date_modify("+7 days") %}
{% set entries = craft.entries.section('events').postDate('and', '>= ' ~ startDate, '< ' ~ endDate ) %}
{% for entry in entries %}
    {{ entry.title }}
{% endfor %}

For pagination.

Next Week
Previous Week


Adjust item stock accordingly to checkout carts So in Craft Commerce, we have stock items. What I want is to display items in stock, but adjust it to active checkout charts containing those items.

(only when an active had a checkout or being disband stock must correct itself)

How would it be possible to implement such a thing?

Well I made a workaround, I'm going to use Custom Order Status to manage "in stock" and "pending in cart" and get both the values and make a calculation that will be put in the "stock" value displaying in the front.


Craft CMS on LEMP Stack (mcrypt not detected) I have a LEMP droplet on digitalocean that I am trying to get working with Craft CMS.
Strangely it does not seem to play nice with NGINX. Or maybe it's just me.

After installation I am receiving the below message;

I do have php5-mcrypt installed and it appears in phpinfo()

Can anyone help? Thanks.

-- NGINX config for craft (craft.conf)

server {
  listen   80;

  root /var/www/public;
  index index.php index.html index.htm;

  server_name ger1-riverrun.mydomain.com;

  location / {
    try_files $uri $uri/ @rewrites;
  }

  location @rewrites {
    rewrite ^(.*) /index.php?p=$1 last;
  }

  location ~ \.php$ {
    try_files $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
  }

  error_page 404 /index.php;

}

RitterKnights solution worked! I hadnt restarted php5-fpm.


How can I specify what happens when someone calls my fieldtype without any further dot chains? So, I'm in the process of building a fieldtype, and I'd like to output an HTML element and some javascript when a developer calls my plugin like this:

{{ entry.fieldtypeHandle }}

The field returns an object with other methods/properties on it, but I'd like to specifically provide something different when a developer calls my fieldtype without any other chaining.

I've tried pass a class with a __toString() method, but it just returns a string. (I don't know what I expected, honestly.) I also know that coupling the HTML output with the class seems a bit dirty, even if that did work.

Is this possible?

entry.myFieldHandle will return whatever the field type’s prepValue() function returns.

If you always want that to be HTML, then prepValue() can just return the HTML as a string or \Twig_Markup object via TemplateHelper::getRaw() so devs don't have to type |raw when outputting the value.

If you want it to be an object that supports sub-properties and methods, then have prepValue() return the object. Give the class a __toString() method, which defines the string that should be returned when the object is treated like a string. Behind the scenes, __toString() is what will be called when a template has {{ entry.myFieldHandle }}. But note that this is a PHP construct and PHP mandates that the method returns an actual string, so you can’t return a \Twig_Markup object here. Devs will have to type {{ entry.myFieldHandle|raw }} to prevent Twig from escaping the HTML.


Template error on local development when checking entry variable I'm working on a english/spanish site that includes a language switcher link in the site footer.

The code for the switcher grabs the currently displayed entry, checks whether a corresponding entry exists in the other locale. If it does exist, the clicking the switcher will link to the corresponding entry. If not, you'll land on the other locale's homepage. If we're already on the homepage, just redirect to the homepage.

The code, simplified, looks like this:

{% if entry.sectionId == 1 %} // The homepage

  // Redirect to homepage

{% else %}

  // Do some checking into whether there's a corresponding entry, etc.

{% endif %}

The problem:

I have some pages on my site that aren't entries, and on these pages, I get a template error telling me that Variable "entry" does not exist

I tried rewriting this code so I'd check if that variable exists first:

{% if entry|length %}

 // Do the previous code

{% endif %}

But this gives me the same error. How can I write this logic so I don't have to rely on the entry variable existing or not, which should presumably avoid the error.

Thanks!

You are close, instead of checking entry|length, you can do {% if entry is defined %}

{% if entry is defined and entry.sectionId == 1 %}

So if I am understanding correctly, the full code will be:

{% if entry is defined and entry.sectionId == 1 %}

    //  Redirect to homepage

{% else %}

    // Do some checking into whether there's a corresponding entry, etc.

{% endif %}


Clarification how staging site works We have a single installation of Craft that is live and with lots of users and lead generation going. Now the client would like to have a staging environment where we can prepare new pages, or add scripts and test them before going live.

I know about staging in PHP, where you modify a file(s) and when it works on the test server, you copy it over and overwrite the file(s) in production.

But can this be done in a cms like craft where the database is also affected?
Like we create in staging a new template, in the craft admin backend we create the article, with the form (we use Formbuilder). Then when the client is happy can I just 'push a button' and have it live in production?

I guess i have to copy template, and affected database tables over to the production server, but how to know what DB tables have been modified ?

Thank you

Peter

I am new to craftcms and webdev. Therefore I am unable to tell you an exact route, but this can definitely be solved, I already read about it. This guy has excellent tutorials about craftcms and development and these two topics could solve your question. Just give it a spin and read through:

https://nystudio107.com/blog/database-asset-syncing-between-environments-in-craft-cms

https://nystudio107.com/blog/multi-environment-config-for-craft-cms


Locale gives wrong output Got the following issue:
Building a site in 3 languages, Dutch, French & English

All working fine, except the siteurl for building the href link that's going wrong.
EN & NL ok, FR won't output.
If I call craft.locale, it says nl_be instead of fr.

Any ideas? I must be missing something...

Question can be deleted, just found my mistake...

Apparently I've forgot to create the 'fr' folder and the index.php etc..

Working like a charm now!

Post, can be deleted as it won't be helping others


Choose custom email template for Contact Form plugin I could've sworn I've read somewhere on here that the contact form plugin should use the same template as defined in the site's email settings, but it's not working for me.

Does anyone know if the Contact Form plugin supports this (and has it working)?

The first part of the answer in the post you linked to is wrong in the context of the Contact Form plugin.

Craft only takes the custom "HTML Template Path" email setting into account when EmailService's sendEmailByKey is called, which is used for pre-defined Craft emails.

The Contact Form uses EmailService's sendEmail, which won't take it into account.

It hasn't been released as part of an official Contact Form plugin release yet so there's no documentation, but thanks to this pull request, you've got an onBeforeMessageCompile event that will give a plugin a chance to modify the contents of the email.


How to move sidebar menu to top in CP I've seen some Craft CPs that display the sidebar menu horizontally in the top of the browser as a header.  Does anyone know how this is done? Is there a plugin? I think this would be useful for clients using a smaller monitor, particularly when using live preview.

Thanks!

Maybe you could pull it off with some CSS/JS hackery, but it'd be pretty sketchy.

The navigation bar used to be at the top of the Control Panel up until Craft 2.5 came out.  The screenshots you're seeing are probably of the older versions of Craft.


Explanation of Deprecation Warnings Why is this depreciated? Is there an example of the preferred method?

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

Thanks.

It means you've got a loop on an element query somewhere in your templates.  For example:

{% for entry in craft.entries.section('mySection') %}
    {{ entry.title }}
{% endfor %}

You should update it to use .all() like so:

{% for entry in craft.entries.section('mySection').all() %}
    {{ entry.title }}
{% endfor %}


Craft-Multi-Environment-Config redirects to dev url on admin login I'm using the Barrel Stength Craft-Multi-Environment-Config to have a dev and live site configuration.

On my local dev install, under Settings > General I've changed to Site URL to {siteURL}. On logging into the admin, I'm redirected to the dev url.

I've also changed the Assets path and URL in the admin to

Path: {basePath}../public/my_assets_folder
URL: {siteUrl}my_assets_folder/

Images on the live frontend aren't displaying - they're served by HTTPS. Dev site is fine.

DB settings are working as expected. I just can't login to the live admin and the images aren't displaying on the dev frontend. What am I missing?

If the environment that you are working in is behaving like the settings that you have set for another environment, it's likely that the settings from that other environment are the ones that are being read by Craft.

The most common situation where I've seen this take place is based on the way that the Craft multi-environment config matches patterns for each environment you are in.

Let's say you have three environments:

website.com
dev.website.com
localwebsite.dev

Unless you are overriding the CRAFT_ENVIRONMENT variable in your index.php file, you may have a situation the keys of the multi-environment settings array match the pattern of the URL from the environment you are in.

Here's an abbreviated example multi-env settings array:

array(
    '*' => array(
        'environmentVariables' => array(
            'siteUrl'  => 'website.com',
        ),
    ),
    'dev' => array(
        'environmentVariables' => array(
            'siteUrl'  => 'dev.website.com',
        ),
    ),
);

// The Barrel Strength Multi-env config checks for an
// additional local config here.  In our example, that
// would be for the environment `localwebsite.dev`

In this example, 2 of your 3 environments are going to trigger the configuration for your dev site, and none are going to trigger the configuration for your local setup.

Both dev.website.com and localwebsite.dev will trigger the settings in the dev configuration in the array as Craft takes the first configuration that matches the pattern in the URL, and the word dev will match both of those environment URLs.

As the other comments have noted on the primary post, this is really just guesswork until we see the specific config settings you are using. I've tried to approach my answer as one that at least applies to a similar situation to the issue described even if it turns out that it doesn't help resolve the immediate question.


Check user is in User Group / Custom User Permissions I'm trying to restrict access to items in a channel using some form of custom user permissions however I don't appear to be able to create or set custom read permissions for a channel using crafts permissions as they currently are, I'm therefore trying to do something using either user groups or custom fields on the user and validate if a user has access that way.

I'm hoping this is along the right lines, although it doesn't seem ideal, so is it possible to check if a user is in a certain user group elegantly using twig?

I can do {{ if currentUser.admin }} and I'm guessing I could therefore do something like {{if 'groupnamewithaccess' in currentUser.groups }}

I believe what you're looking for is 'isInGroup'

{% if currentUser.isInGroup('groupHandle') %}

It will also accept an actual group object or a group ID as well.

There is also getGroups:

{{ currentUser.getGroups() }}

Will return an array of UserGroupModels all of the groups the user belongs to.

And finally, can:

{{ currentUser.can('permissionName') }}

Will check if the current user has the given permissions, whether that was indirectly assigned to them in a group, or directly assigned to them as a user.


How do variables, services and models fit together? I am new to Craft and have been attempting to write  a plugin but keep getting stuck on how to read and write to the database. I have been working through cocktailrecipesPlugin and am attemting to use it to better understand how to do database CRUD. In this attempt I am replacing coctailrecipes with projectmanager, ingredients with staff, and ingredient with staffMember. The Cocktail Recipe plugin is confusing because it uses objects and properties with the same name and I am unsure if this is the required. I am having difficulty understanding how services and variable and models interact. It appears that services is where the property ingredient is defined, but I am puzzled. I wish there was better documentation explaining the interaction of the various components. I have been banging my head against the wall trying to understand the Craft api and how the pieces work together. The documenation seem sparse and the code sample in the documenation are snippets which make it difficult to understand how everything fits together. I wish the cocktailRecipiesPlugin was better explained.

Cocktail Recipes <=> Project Manager

ingredients <=> staff

ingredient <=> staffmember

For starters, I believe the Cocktail Recipes plugin is grossly out of date. It was originally built when Craft was in beta, and hasn't really been updated much since. There's a rumor that someone has forked & updated it, but I don't have the full story there.

Regarding your actual question...

Models - Think of a Model as a "jar" of related data, about one specific thing. This parallels pretty closely to most other programming languages and design patterns. As for Craft specifically, the Model is really the right way to pass a related group of data between components (Controllers, Services, etc).

Variables - A plugin Variable is simply a way to make your data easily available to front-end Twig templates. A large majority of the time, a Variable is simply a wrapper for some other method (like a Service call).

Services - Services can be anything and everything. It's a complete blank slate, and really the best place for your plugin to do any heavy lifting. If you ever have to interact with the database directly (via Records), it's virtually required that you run that DB interaction through a Service method.

Here are two resources which may help shed a little more light on how it all ties together...

Check out the Business Logic plugin template... Originally intended as a quick way to insert business logic into your site via PHP, it's become a useful learning resource as well. It focuses mainly on Variables, Services, and Controllers, and is completely documented in the code comments.

Lastly, here's a diagram which I put together as I was learning plugin development. Keep in mind, this is not a 100% 1:1 representation of every-plugin-ever. Any given plugin can contain more or less of these components... this is simply a basic illustration of how the components tie together.


Omit index.php from URL on IIS Is there a way to omit index.php from the URL when using IIS server? Adding

'omitScriptNameInUrls' => true,

seems to break the site (except for the front page). index.php is removed from the menu links, but when called the sub-pages result in a 404.

This is my first Craft site on IIS, and I have no experience with IIS. It is the client choice unfortunately.

I'm running the latest IIS 10 on Windows 10 and "pretty URLs" (i.e. craft.dev/admin/dashboard worked out-of-the-box using Craft's stock web.config file in the public HTML folder with no modifications.

I'd double check you've got that file in place and haven't made any modifications to it.


Moving from Rackspace cloud files to Amazon S3 Recently moved server from Rackspace to AWS. A lot of media in our entries is hosted by rackspace cloud servers. How intensive would it be to move these all to Amazon S3 in regards to linking media to entries?

I would recommend not drag-n-dropping inside Craft. It might end up being very intense indeed, and break down in multiple ways.

A better way would be to download the media locally, replicating the folder structure and files in the S3 bucket, and then manually changing the source id of the Asset / Folders in question in the database.

For concurrent uploading, take a look at s4cmd.


Why is Craft hanging every time I try to save an entry? I just upgraded to the latest version of Craft.  I can login and create a new entry, but then it hangs when I try to save it.  I can't even stop and go back to the entries panel.  I have to exit out of Safari or Chrome and go back in.  Sometimes it has saved the entry and other times it has not.  There are no error or pop of notification of any sort.

And by hang - I mean seizes up and freezes for about 5-10 minutes ...and sometimes creates a duplicate entry.

The problem appears to be Intego anti-virus software on my one machine.  The problem does not appear on computers that lack Intego.


getPath() does not return subfolder for S3 asset source I'm reading through the Craft docs in relation to the AssetFileModel.

Looking at the getPath() method, this reads in theory that it should return the full path to the asset relative to the root, with any sub directories etc.

https://docs.craftcms.com/api/v2/models/AssetFileModel.html#getPath-detail

Yet this doesn't to appear to be the case, I seem to be getting /filename.ext

If however I was to use folderPath() this then provides the subfolder name configured in the relevant S3 asset source.

https://github.com/craftcms/cms/blob/master-v2/src/models/AssetFileModel.php#L384

Is this correct? Is getPath() meant to behave this way with S3 asset sources?

Seems to be working as expected for me.  I've got an Asset Source setup with an S3 bucket.

At the root of the bucket, there is a test1 folder and in it is a test2 folder... i.e. root/test1/test2/.  From there, I put a test.jpg file inside of test2.

When I do this from a template (where ID is the Asset ID for test.jpg:

{% set image = craft.assets.id(13).first() %}

{{ image.getPath() }}

I get the expected:

test1/test2/test.jpg


Dynamically specify the 'To' email/recipient using Contact Form plugin I'm trying to leverage the Contact Form plugin so I can dynamically specify the To email/recipient (via a text input, not as a hidden field).

I've tried via my own plugin to tap into the beforeSend event and also via config (eg https://gist.github.com/cole007/e65f028cc58140ed3b0f6910fc9615d6).

However, the sent message always defaults to send to the recipient specified in the plugin settings. Any thoughts on how to resolve, or if this is indeed possible?

Reading the documentation it sounds like you should be able to specify toEmail using a text input. I'm guessing that it is using the default email because you aren't validating the email address first.

<input type="text" name="toEmail">

The plugin will get toEmail from the post request and validate it for use.

$toEmail = craft()->request->getPost('toEmail');
$toEmail = craft()->security->validateData($toEmail);


Resend Activation Link not sending I am having an issue where the activation link sent to a user has expired and when they click the 'resend activation link' on the warning message a new activation link is never sent.

I have added logging into the userservice->sendActivationEmail method to see if it's called and it never gets called.

Any help would be appreciated.

Definitely a bug and just fixed it for the next release.


How can I set the postDate and expiryDate from a front-end date picker via plugin? I am working on a plugin that has a date picker only (no time). I am attempting to set the postDate to the value of whatever date was chosen on the front-end. I realize I need to save in this format: Y-m-d H:i:s

$start = craft()->request->getPost('startDate'); // 09/27/2015

// I'm not doing this right as it returns nothing.
$post = DateTime::createFromString($start);

// Returns a datetime object, but doesn't save.
$post = new \DateTime($start);

DateTime Object (
    [date] => 2015-09-27 00:00:00.000000  // trim the last decimal?
    [timezone_type] => 3
    [timezone] => UTC
)

I don't really care what the time is. It could always be midnight, or get the current time from the server. What is the best way to "assemble" the datetime?

I believe I have figured it out, please correct me so I can update the answer if I am too far off.

TL;DR:

I am using a date picker (no time) on a front-end form. The user chooses a date and it comes across as 09/27/2015. Here is how I converted that string to a dateTime object that I could set as post & expiry date for a newly created entry.

NOTE: I have not included any validation at this point which should be carefully considered.

MyPlugin.php

// Get the current time zone from the system.
date_default_timezone_set(craft()->timezone);

// Get the current time
$time = date('H:i:s');

// Create the post dateTime
$postDate = date('Y-m-d', strtotime(craft()->request->getPost('postDate')));
$postDateTime = $postDate . ' ' . $time;

// Create the expiry dateTime.
$expireDate = date('Y-m-d', strtotime(craft()->request->getPost('expiryDate')));
$expireDateTime = $expireDate . ' ' . $time;

// Create the DateTime object to send to Craft.
$postDate = new \DateTime($postDateTime);
$expiryDate = new \DateTime($expireDateTime);

// Put it all together.
$entry = new EntryModel();

$entry->sectionId = 3;
$entry->typeId = 1;
$entry->enabled = true;
$entry->postDate = $postDate;
$entry->expiryDate = $expiryDate;

...

if(craft()->entries->saveEntry($entry)) {
    // Success
} else {
    // Fail
}


Client License Transition to Solo/Pro I have a Craft site with a Client license. After the recent license transition to Solo/Pro, a red banner appears along the top that reads "You’re running Craft Client with a Craft Pro license. [Resolve]." Hitting "resolve" displays the following:

So, if I reinstall as pro, is that a new $299 charge (plus the annual $59)? Will "reinstalling" result in system downtime and/or data loss?

Disregard -- this was directly addressed by the 2.6.3015 update that was just released. The message no longer appears.


Templating repeatable blocks in a matrix field I have a matrix field that has two different block types. The matrix field is on an entry that lists a number of benefits for a given product on a corporate website. The two different blocks are firstly an "intro" block that has a couple of text fields for a headline and description and then secondly a "benefits" to create a list of benefits. I then output the items in the template as follows:

{% for intro in entry.benefits %}
    {% for image in intro.leadImage %}

    {% endfor %}

{{ intro.introTitle }}

{{ intro.introParagraph }}

{% endfor %}

    {% for benefitsItem in entry.benefits %}

{{ benefitsItem.benefit }} - {{ benefitsItem.description }}

    {% endfor %}

There are two different for loops, one that lists the "intro" block and one that lists the "benefitsItem" block. The problem I have is that I want to be able to separate lists of benefits into sections by inserting another "intro" block in the CMS content but of course no matter where I order my "intro" blocks in the admin they will always appear above all the benefits where the for loop puts them out. Does anyone know how I would go about creating a matrix field or changing my template so that I can order things as follows:

Intro
Benefit
Benefit
Intro
Benefit
Benefit

Any ideas greatly appreciated. Thanks.

It might be worth checking the types of the matrix block like:

{% for block in entry.benefits.all() %}
    {% switch block.type %}
        {% case "intro" %} {# <=== ASSUMING BLOCK TYPE HANDLE #}
            {% for image in block.leadImage.all() %}

            {% endfor %}

{{ block.introTitle }}

{{ block.introParagraph }}

        {% case "details" %} {# <=== ASSUMING BLOCK TYPE HANDLE #}

{{ block.benefit }} - {{ block.description }}

    {% endswitch %}
{% endfor %}

If you're wanting a list inside of a matrix (matrix in a matrix for the Benefits), I'd suggest killing the Benefits block type and adding a SuperTable or Neo field to the Intro block type then you'll be able to list the benefits below each intro in a for loop.


Getting fatal error when installing new plugin by hitting memory_limit I am trying to locally install Craft Typed Link Field from the plugin store and I'm getting this PHP error.

I have already upped my memory_limit to 256M within my php.ini file, yet this is claiming to need 400M to run these updates.

I'd rather try to deal with the root cause instead of upping my memory_limit to 410M.

Trace is following:

A fatal error has occurred:

Status: Internal Server Error

Response:
PHP Fatal Error &#039;yii\base\ErrorException&#039; with message &#039;Allowed memory size of 268435456 bytes exhausted (tried to allocate 4096 bytes)&#039;

in /Users/name/project/build/vendor/composer/composer/src/Composer/DependencyResolver/Solver.php:220

Stack trace:
#0 [internal function]: yii\base\ErrorHandler-&gt;handleFatalError()
#1 {main}

This is more of a Composer than a Craft issue. Depending on your project dependencies, Composer could easily need 1GB of memory.

I assume you got the 410M from the 4039 bytes in the error. That's only what Composer can't allocate for what it's doing, you might need more later in the process.

I would start by upping my memory_limit to 512M and see where it gets you.


How do I create a link to an entry using entry's id? This is a beginner question:

How do I create a link to an entry using entry's id?

I tried several combinations, such as {{ entry.getUrl(my_id) }}, {{ entry.url.id(my_id) }}, etc. but failed to found the correct syntax.

The reason why your example fail is that you are using the entry variable. You are trying to call the function getUrl on the model entry, but the function (or model) doesn't exist yet, and has to be created (fetched).

Example:

You can use craft.entries to fetch the EntryModel, and than output its url:

{% set my_id = 5 %}
{% set entry = craft.entries.id(my_id).first() %}
{{ entry.url }}

If you are in an entry loop, it works the same way:

{% for entry in craft.entries.section('blog') %}
    {{ entry.url }}
{% endfor %}


group Matrix blocks and also order by Matrix field for a given block I'm wondering if I might have a little too much inception madness in my thinking with this problem.

Enhancing a site we built for a conference last year. As there's an annual conference each year and some of the speakers are the same, we decided to reevaluate the approach.

What we have now is 2 channels, Speaker and Conference. Speaker contains all the speakers that could ever make an appearance at the conference and Conference contains the specific details about that conference.

Within conference, we have a Matrix field called Talks with a workshop, general and special event block.

I want to be able to group talk blocks by their block type, is that possible?

Going a step further, in the case of a workshop - that block has a workshopRound select field of 1, 2 or 3 - I'd love to be able to then group entries with those blocks by their round number.

Any thoughts on how this could be achieved?

This is a great chance to use the group filter.

First, get all your matrix blocks as an array:

{% set talkBlocks = entry.talks.find() %}

Then group them by type:

{% set talksByCategories = talkBlocks|group('type') %}

At this point, you have an associative array where the keys are the block types, and the values are arrays of the blocks with that type. So talksByCategories.workshop or talksByCategories['workshop'] will be the workshops.

You can group the workshops by round:

{% set workshopsByRound = talksByCategories.workshop|group('workshopRound.value') %}

You should check that there were any workshops first (twig's defined test):

{% if talksByCategories['workshop'] is defined %} ...


Error: 2006 MySQL server has gone away Several visitors, over the course of weeks, have mentioned receiving the following error when viewing the site:

CDbCommand failed to execute the SQL statement: SQLSTATE[HY000]: General error: 2006 MySQL server has gone away

The log file shows the error (below). Not just once, but multiple times within a short time span.

Has anyone seen this error?

Any insight as to what's going on here is appreciated.

2014/12/24 13:57:46 [warning] [application] The request to freegeoip.net failed: Server error response
[status code] 502
[reason phrase] Bad Gateway
[url] http://freegeoip.net/json/182.171.233.223
2014/12/24 13:57:46 [error] [system.db.CDbCommand] CDbCommand::fetch() failed: SQLSTATE[HY000]: General error: 2006 MySQL server has gone away. The SQL statement executed was: SELECT  'elements'.'id', 'elements'.'type'
FROM 'craft_elements' 'elements'
JOIN 'craft_elements_i18n' 'elements_i18n' ON elements_i18n.elementId = elements.id
WHERE (elements_i18n.uri = :uri) AND (elements_i18n.locale = :locale) AND (elements_i18n.enabled = 1) AND (elements.enabled = 1) AND (elements.archived = 0).
2014/12/24 13:57:46 [error] [exception.CDbException] exception 'CDbException' with message 'CDbCommand failed to execute the SQL statement: SQLSTATE[HY000]: General error: 2006 MySQL server has gone away' in /nfs/c06/h06/mnt/187742/domains/obozfootwear.com/craft/app/framework/db/CDbCommand.php:543
Stack trace:

#0 /nfs/c06/h06/mnt/187742/domains/obozfootwear.com/craft/app/framework/db/CDbCommand.php(415): CDbCommand->queryInternal('fetch', Array, Array)
#1 /nfs/c06/h06/mnt/187742/domains/obozfootwear.com/craft/app/services/ElementsService.php(147): CDbCommand->queryRow()
#2 /nfs/c06/h06/mnt/187742/domains/obozfootwear.com/craft/app/etc/web/UrlManager.php(278): Craft\ElementsService->getElementByUri('', 'en_us', true)
#3 /nfs/c06/h06/mnt/187742/domains/obozfootwear.com/craft/app/etc/web/UrlManager.php(137): Craft\UrlManager->_getMatchedElementRoute('')
#4 /nfs/c06/h06/mnt/187742/domains/obozfootwear.com/craft/app/framework/web/CWebApplication.php(140): Craft\UrlManager->parseUrl(Object(Craft\HttpRequestService))
#5 /nfs/c06/h06/mnt/187742/domains/obozfootwear.com/craft/app/etc/web/WebApp.php(264): CWebApplication->processRequest()
#6 /nfs/c06/h06/mnt/187742/domains/obozfootwear.com/craft/app/framework/base/CApplication.php(180): Craft\WebApp->processRequest()
#7 /nfs/c06/h06/mnt/187742/domains/obozfootwear.com/craft/app/index.php(62): CApplication->run()
#8 /nfs/c06/h06/mnt/187742/domains/obozfootwear.com/html/index.php(14): require_once('/nfs/c06/h06/mn...')
#9 {main}

REQUEST_URI=/HTTP_REFERER=http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CCAQFjAA&url=http%3A%2F%2Fobozfootwear.com%2F&ei=8MWaVKfVBtGE8gWz-oKIBg&usg=AFQjCNGF_NGGtGdApatcXOoA3BYgIYOnZg&sig2=mmDpzpWjXopxNLsBnUTj6g&bvm=bv.82001339,d.dGc

2014/12/24 13:57:46 [error] [application] CDbCommand failed to execute the SQL statement: SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
2014/12/24 13:57:46 [error] [system.db.CDbCommand] CDbCommand::fetchAll() failed: SQLSTATE[HY000]: General error: 2006 MySQL server has gone away. The SQL statement executed was: SELECT `id`, `groupId`, `name`, `handle`, `context`, `instructions`, `translatable`, `type`, `settings`
FROM `craft_fields`
WHERE context = :context
ORDER BY `name`.

It looks like you might have the Smart Maps plugin installed.  There was a bug with earlier versions of it that had a similar error message.  Update to the latest version and it should be resolved.


Pass variable into include I have a snippet within a template which I want to pass a variable into:

page.twig

{% set lightswitchTest = entry.aktivesProjekt('1').find() %}

{% include '_snippets/thingy' %}

thingy.twig

<div class="panel{% if lightswitchTest == null %} notActive{% endif %}">
   {# bla bla #}
</div>

I tried to add pass in the variable with the with keyword but I guess my syntax is wrong?

{% include '_snippets/thingy' with lightswitchTest %}

If i use the varibale now in the snippet there is just the Array to string conversion error.

What am I missing? Is there a better way?

You can leave the with lightswitchTest part off altogether, and all the variables from the parent template will be available inside the include too.

with expects an array, where the keys correspond to the variable names and their values, so if you did want to explicitly pass that in (say as a different variable) you could use:

page.twig

{% include "_snippets/thingy" with { active: lightswitchTest } %}

thingy.twig

<div class="panel{% if not active %} notActive{% endif %}">
    {# bla bla #}
</div>


“Request missing required body param” error when creating entry on front end I get an Request missing required body param error when trying to create a new entry on the front end. All required fields are being filled. Nothing changed except the craft version. Craft version is 3.2.0-RC2.

Has that something to do with the way drafts are handled in 3.2?

Edit:
Looks like Craft wants a entry id:

/…/controllers/EntriesController.php(848): craft\web\Request->getRequiredBodyParam('entryId')

Which, of course, is not available when creating a new entry. What is to be done?

This was an unintentional breaking change. See https://github.com/craftcms/cms/issues/4693

Update: Fixed in 3.2.9, which is now (2019-08-06) available https://github.com/craftcms/cms/blob/develop/CHANGELOG-v3.md#329---2019-08-06


Front End Dropdown Field from Super Table I have a single static Super Table Field with some Dropdown Fields.
Is it possible to loop through the values instead of hardcoding each one?
My hardcoded version works without problems but i think a dynamic loop is better for the future.

Here is one example: ('static' is the value of the Super Table btw.)

    Visibility:
    <select name="fields[{{ fieldHandle }}][{{ block.id }}][fields][visibility]">
      <option value="privat"{% if entry.static.visibility.value == "privat" %} selected{% endif %}>Privat</option>
      <option value="public"{% if entry.static.visibility.value == "public" %} selected{% endif %}>Public</option>
    </select>

Would be great, if someone has a idea! Thanks

You should be able to do this in the same way as for a dropdown field in Craft as described in the docs.

Something like this should work if entry is populated:

    Visibility:
    <select name="fields[{{ fieldHandle }}][{{ block.id }}][fields][visibility]">
      {% for option in entry.static.visibility.options %}
         <option value="{{ option.value }}"{% if option.selected %} selected{% endif %}>{{ option.label }}</option>
      {% endfor %}
    </select>


Removing P tag's in rich text area's Before you think this has already been answered, yes it is but I can't manage to get that fix working so I'm looking for another one.

I have a "title" field in a couple of my matrix blocks but my client want's to add a Bold word every now and then. Now I tried that with a rich text field which works fine except that it keeps adding a <p> tag to my text which makes the Indexing go wrong etc plus it shouldn't be so hard to remove but apparently it is...

This is my custom json at the moment:

{
    buttons: ['bold', 'italic'],
    maxHeight: 50,
    paragraphize: false,
    replaceDivs: false,
    linebreaks: true,
    enterKey: false
}

In every fix I find here this should do it but somehow it wont..

Seems like a simple striptags filter would do nicely in this case:

{{ entry.titleField|striptags('
')|raw }}

If you're having issues with linebreaks, you might want to add the nl2br filter as well:

{{ entry.titleField|striptags('
')|raw|nl2br }}


How to reference controller action from hidden action? Correct path? I have seen a number of different paths, but, it is a bit confusing to me. What should be in my value in the HIDDEN input action below?

I have a twig page at my root:

<form method="post" action="" accept-charset="UTF-8">
    <input type="hidden" name="action" value="psychEmail/pubRequest">

    <!-- ...-->

    <input class="btn submit" type="submit" value="{{ 'Submit'|t }}">
</form>

and then I have a plugin PsychEmailPlugin.php class file with
class PsychEmailPlugin extends BasePlugin

and then I have a controllers subdirectory with a PsychEmailController.php file that contains an action:

class PsychEmailController extends BaseController
{
    public function actionPubRequest($emailAddress)
    {
        $email = new EmailModel();
        $email->fromEmail = $emailAddress;
        $email->toEmail = 'myemail@gmail.com';
        $email->subject = 'Publication Request';
        $email->body    = 'Your requested publication is attached.';

        craft()->email->sendEmail($email);
    }
}

After my changes, this worked:

value="psychEmail/publication/pubRequest"


craft.users.admin boolean parameter... to quote or not to quote? This may have been answered before but my searching has not come up with anything. I need clarification on when to quote and when not to quote the boolean in the admin criteria for craft.users in a Twig template.

I have a plugin that displays a table of users and the reason this came up is I needed to exclude the admins from the table. Easy you say, just use the admin parameter and set it to false. That's what I thought so I did this:

{% set users = craft.users.admin(false) %}

This however returned all the users. So I thought maybe it needs quoting and did this:

{% set users = craft.users.admin('false') %}

Hurray! This did exactly what I wanted. Then I thought what if I only wanted the admins and tried:

{% set users = craft.users.admin('true') %}

This however returned all users that are not admins, eh? Ok, what about:

{% set users = craft.users.admin(true) %}

Hurray again! Only admins.

So looking through the source I can see why the first unquoted false has no affect as it fails the if(criteria->admin){} and therefore does nothing. After that I got lost in parseParam() and arrayHelpers so if anyone could clarify to quote or not to quote (that is the question!) and if this is the expected behaviour. Seems a little strange you need to quote 'false' and not quote true to get the desired behaviour. I also tried passing the parameters as an object and the results were the same.

Let me try to make some sense of the behavior you’re seeing.

First, you should know that the admin param will query against the admin column in your craft_users table, which will either be set to 0 or 1 for each user.

Like most Craft params, the admin param is set to null by default, and will only have any affect on the DB query if it is set to a non-empty value. (Here’s a list of what PHP considers “empty”: http://php.net/manual/en/function.empty.php#refsect1-function.empty-returnvalues)

So, here’s what’s happening behind the scenes for each thing you passed in:

false – That’s an empty value, so it’s the same as not passing anything in.
'false' – Since the admin column is numeric, MySQL has to normalize this string into a number (sortof like using JavaScript’s parseInt() function). The result for 'false' is 0, since 'false' doesn’t begin with a number. The end result is that this awkwardly works as expected, but I wouldn’t recommend it.
'true' – Same effect as 'false'. Ends up being 0.
true – SQL doesn’t support PHP’s boolean datatypes (true/false), so PHP will convert this to 1 before passing it off to MySQL. (false likewise becomes 0, but since false is empty, Craft won’t let your value make it that far in the first place.)

In the future, I think this makes a good case for us allowing false, so we’ll probably start checking for that and allowing it. But that won’t help you today.

So the question is then, what is the best way to find users that are(n’t) admins today? Here’s what I would recommend:

Finding admins:

1 (int)
'1' (string)
true

Finding non-admins:

'not 1' (string)


php.ini crashes CP with "Craft requires the PDO extension to operate." I'm trying to use php.ini to increase memory_limit etc on my site. An empty php.ini causes the front end to crash throwing a "Service Unavailable" error and the CP to throw the error "Craft requires the PDO extension to operate."

The server allows for php.ini files to be used. There is no craft/storage/logs/phperrors.log file and the PHP and apache logs don't seem to show anything.

Another user had the similar issue here but there doesn't seem to be a fix posted that works: Adding php.ini file to root crashes site

Thanks!

I fixed this by adding the PDO extensions in to my php.ini which was overriding the server one.

extension = "pdo.so"
extension = "pdo_sqlite.so"
extension = "apc.so"
extension = "intl.so"
extension = "pdo_mysql.so"


Listening for Change at Entry Save I want to send an email if/when an entry is saved with a lightswitch switched on after previously being off.
I have the below code in my plugin's init file, but I don't know how to

check for the section uid and verify that it's the right section or

check the previous value and compare it to the value being saved.

    Craft::$app->elements->on(Elements::EVENT_AFTER_SAVE_ELEMENT, function(ElementEvent $e) {
            $element = $e->element;

        });

I'd appreciate any help, thanks.

I believe you're looking for this instead.
Event::on(
    Entry::class,
    Element::EVENT_AFTER_SAVE,
    static function (ModelEvent $event) {
        $entry = $event->sender;
        if ($entry->status === 'disabled'
            && $entry->propagating
            && $entry->resaving
            && ElementHelper::isDraftOrRevision($entry)) {
            return; // do nothing if disabled/draft/resaving...
        }
        if ($entry->section->handle === 'my-handle') { // check section handle
            // call your preferred msg client: slack, email, mailgun...
        }
    }
);