Varnish 4.x and Craft Is there any vcl file to use with Craft? I saw here an amazing answer about Varnish and Craft and there is a 3.x configuration file but i need a newer one for Varnish 4 and i don’t know Varnish Configuration Language to port it myself

I'm by no means a Varnish pro, but I'm currently working on a project where we're running Varnish 4.0 in front of our nginx servers. I've uploaded an example of our VCL 4.0 file in this gist. It is based on the Varnish 4.0 template made by Mattias Geniar with some adjustments for Craft.

It is NOT an exact port of the 3.x file you're referencing, so it's important to understand what it does.

First of all, the 3.x file sets the ttl of cacheable requests in the VCL. Not sure if this is because it's harder to set the correct headers in ExpressionEngine, but I prefer to leave this to the backend server. If you don't set expire headers in your templates your pages won't be cached. To set a page to expire in 7 days you add this to your template:

{% set expiry = now|date_modify('+7 days') %}
{% header "Cache-Control: max-age=" ~ (expiry.timestamp - now.timestamp) %}
{% header "Pragma: cache" %}
{% header "Expires: " ~ expiry.rfc1123() %}

You can add all kinds of logic to this, setting different cache duration based on entry section, entry age, custom fields, or whatever.

In the 3.0 example file, all asset folders (like /scripts, /assets/, /files, etc) are excluded from caching. This is probably a good idea in most cases, see the comments from the original 4.0 template regarding this. But, in my project all content files are uploaded to Amazon S3, so the only assets served by nginx is css, js, font files, and some small assets. I've opted to just let Varnish handle everything for now.

I'm taking a heavy handed approach to cookies, because I don't need them, and I had some problems removing the Craft ones. I've left in some of the original stuff from the template, mostly for reference.

All requests to the Craft admin is passed on to the backend server. I had some issues with just excluding /admin, because the control panel sometimes add index.php to the url, so I'm excluding everything that contains /admin or p=admin.

All in all, this might not be a perfect VCL file, but it seems to work fine. Running Varnish on a DigitalOcean 1GB/1CPU droplet, I've cut the response time on my test page from ~1.5s (unoptimized/uncached template with a lot of matrix going on) to 40ms. Static tests with ApacheBench within the local network shows Varnish delivering ~900 requests/sec. Pretty awesome, me thinks.

But comments and fixes are greatly appreciated. :)

I'm also working on a Craft plugin for purging URLs when entries are changed, but it's not working very well at the moment.

UPDATE:
My Varnish Purge plugin is now available here. Also, check out Josh Angell's CacheMonster plugin here for a different take on the same problem.


How to get all available tax rates in a Commerce site? Is there a way to retrieve and loop through all the available tax rates that have been set up in Commerce 1?

I had thought I could loop through the adjusters like so;

{% for adjustment in cart.adjustments %}
    {{ adjustment.name }}
{% endfor %}

In fact, I'm doing this on one site with no problems but having just tried the same thing on another project I am running into errors. I'm guessing because no adjustments exist unless there is actually a cart object.

I am trying to retrieve its value in order to display the price including tax on my product page template. For this particular case I only have 1 tax rate, so there is no problem with regionality. I figured that I could loop through the adjuster, check the name and retrieve the value.

If there's another way to do this I'm all ears!

Commerce 2

{% set allTaxRates = craft.commerce.taxRates.allTaxRates() %}

{% for taxRate in allTaxRates %}
    {{ taxRate.name }}

{% endfor %}

taxRate will be an instance of craft\commerce\models\TaxRate

Commerce 1

If you're looking to get all of the tax rates setup in Commerce from a template, something like this should work:

{% set allTaxRates = craft.commerce.getTaxRates() %}

{% for taxRate in allTaxRates %}
    {{ taxRate.name }}

{% endfor %}

taxRate will be an instance of Commerce_TaxRateModel.


Import database backup when using docker I am trying to import a database backup into a craft instance running on Docker, but none of the fields or content from the latest backup are importing.

Here are the steps I took

I used these default.conf and docker-compose.yml files here  to create a local environment with Docker.
I made a site locally, and backed up the database several times (and so now have a series of backups - see image below)
I restarted Docker after updating to the latest version, then ran docker-compose up to relaunch.
Craft loaded with the initial DB, but none of the fields or content from the latest backup appear (localhost actually returns a Twig runtime err when it encounters the first field.)

Here is how my backup folder looks:

It seems the issue lies with my docker-compose.yml (below), but I don't see how to edit this to call the right DB backup.
Any help or advice much appreciated!

# docker-compose.yml
version: '2.1'

services:
  nginx:
    image: nginx:alpine
    ports:
      - 80:80
    depends_on:
      - craft
    volumes_from:
      - craft
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf # nginx configuration (see below)
      - ./assets:/var/www/html/web/assets # For static assets (media, js and css). We don't need PHP for them.

  craft:
    image: urbantrout/craftcms:mysql
    depends_on:
      - mariadb
    volumes:
      - ./backups:/var/www/html/storage/backups
      - ./templates:/var/www/html/templates # Craft CMS template files
      - ./modules:/var/www/html/modules # Craft modules directory
      - ./config/element-api.php:/var/www/html/config/element-api.php # Element API file - we require the plugin below
    environment:
      DEPENDENCIES: >- # additional composer packages (must be comma separated)
        yiisoft/yii2-redis,
        craftcms/redactor,
        craftcms/element-api,
        nystudio107/craft-seomatic

      CRAFTCMS_EMAIL: XXXXXXXXXXXXX
      CRAFTCMS_USERNAME: admin
      CRAFTCMS_PASSWORD: XXXXXXXXXXXXXX
      CRAFTCMS_SITENAME: Craft CMS Installation
      CRAFTCMS_LANGUAGE: en-US

      REDIS_HOST: redis
      SESSION_DRIVER: redis
      CACHE_DRIVER: redis

      DB_SERVER: mariadb
      DB_NAME: craft
      DB_USER: craft
      DB_PASSWORD: secret
      DB_DATABASE: craft
      DB_SCHEMA: public
      DB_DRIVER: mysql
      DB_PORT: 3306

  mariadb:
    image: mariadb:10.1
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_USER: craft
      MYSQL_PASSWORD: secret
      MYSQL_DATABASE: craft
    volumes:
      # Persistent data
      - dbdata:/var/lib/mysql

  redis:
    image: redis:4-alpine
    volumes:
      - redisdata:/data

volumes:
  dbdata:
  redisdata:

Partial solution - I removed all backups except the most recent from the backups folder.

It seems that changing the site name prevented the site from finding the correct sql file or adding new backups to .ignore.

If you want to change the name then be sure to remove other backups from the site directory.


Login Page Logo and Site Icon gives 404 in Craft 3 I have update the craft version from 3.0.2 to 3.0.3.1, after that Login Page Logo and Site Icon gives 404 path error. I have checked file permissions also but it is not creating link in cpresources folder while it is showing url in frontend. In local its working fine.

This has been fixed for the next release. Only affects environments where the web server is not sending missing resource requests (like /cpresources/XXXXXX/logo.svg) to index.php.


Building a website containing restaurant menus from multiple vendors -- need some advice on Section hierarchy of data Figure I'd query with the geniuses over on StackExchange as I think I've hit a roadblock in my project. I'm building a website containing menus from multiple restaurants with the vision that it could eventually grow to become a local online food ordering marketplace.

Taking into consideration the e-commerce plugins currently in development, I'm going to make an assumption that a single product would constitute as a single entry with these add-ons, so this makes the hierarchy of data a bit of a challenge.

Some requirements:

Menu items need to be associated with a restaurant.
Menu items need to be categorized, but categories are unique per
restaurant

I've played with various configurations thus far and haven't really found a method that I'd deem "ideal."

I've considered using Structure exclusively where parent items would be the restaurants and children would be the menu categories with the items nested beneath. What are your thoughts on this? Could use a few different entry types for indexes and one for menu items.

Right now, I'm using a combination of related entries, an Inverse related entries plugin for informational purposes where restaurants are also channels, but just doesn't seem like a sensible approach so far, so probably scrapping this method.

Thoughts, advice, any feedback really appreciated. Thank you so much!

Ok, just spitballing here, but this is where my brain is going...

Channel: Restaurants

Each restaurant is a unique entity, correct? So they wouldn't need to be in any specific order, nor nested. (Chain restaurants could be related by other means.) All of your broad restaurant-based fields would be here, including location, phone number, hours of operation, etc.

Channel: Menu

I feel the menu should be a separate channel from the parent restaurants for a couple of reasons:

Seasonal/specialty menus: One restaurant, many menus.
Chain restaurants would share a menu: Many restaurants, one menu.

Within your Restaurants channel, create an Entries field (with a limit of 1) called "Menu". So each restaurant could select its current menu.

Matrix: Menu Items

Within your Menu channel, you'd have a Menu Options matrix field. Each menu option would be its own matrix block.

If you want to use the built-in category system, you may be able to create Category Groups based on different restaurant genres (Mexican, Thai, etc). You could then simply use those very broadly. However, I'd be concerned that those broad categories don't properly address the needs of each individual restaurant.

Alternatively, you may end up needing to create faux categories... I'm not sure you could get the normal category system to work for you here. There would be such wide-ranging variations between the categories of different restaurants, it would be a nightmare to keep up with that using the standard categorization options.

Faux Categories

You could potentially create a dropdown menu to represent your "categories" for a particular restaurant. That faux categories menu could be driven by the amazingly powerful LJ Dynamic Fields plugin. Might take a little trial & error, but that plugin will allow you to build a dropdown menu to be exactly as you need it.

With this method, you could allow each Menu to have its own definition of categories. Create a table field called "Categories" in your Menu section, and allow LJ Dynamic Fields to take advantage of that.

eCommerce Options

I can see why you'd gravitate towards making each menu item into its own entry, but I don't believe that's necessary. Take a look at some of the more generic, non-Craft options for building your checkout process. Specifically Snipcart and Foxycart allow you to render a product however you want to, and don't restrict your back-end data to any particular architecture.

My instinct is telling me that your menu options would be much better suited as a matrix field (or even table field), rather than being their own entries.

Hope that helps, even if it just gives you some new ideas to kick around! :)


How do I get the number of days in the previous month? I am working on a calendar, and so far I know how to get the number of days in the current month.
{% set daysInMonth = time|date('t') %}

But how can I get the number of days in the previous month?

Thanks in advance.

I believe: {{ now | date_modify('-1 month') | date('t') }}


Is there a way to output more Matrix fields than one? I'm struggling to get an element criteria model of more matrix fields at once for entry related to tagField.

Example:
I have two matrixFields, where I want them in {% for block in entry.matrixFieldhandle %} loop.

I could do

{% for block in entry.matrixFieldhandle1 %} My stuff {% endfor %}

and

{% for block in entry.matrixFieldhandle2 %} My stuff {% endfor %}

but it's kind of silly to always set element model for each field. Anything simpler?

Couldn't find anything explanatory in documentation or here.

Not sure if this solves your problem, but you could try this:

{% set allMatrixBlocks = entry.matrixFieldhandle1.find | merge(entry.matrixFieldhandle2.find) %}

{% for block in allMatrixBlocks %} My stuff {% endfor %}


Is it possible to update multiple cart items? To be more specific I would like to add an "update cart" button so that the visitor can adjust the quantity of multiple cart items without having to click on "update" for each cart item.

Not at the moment, you can submit a feature request for the feature here: https://github.com/craftcms/commerce/issues


Is there a way to delete all entries within a section? I am currently using FeedMe to import json data every night but I need to delete all entries before doing so to make sure that any orphaned entries are removed.

What is the best way to remove all entries within a section?

I think you're looking for the Delete Duplication Handling option. From the documentation:

  Delete all existing entries in this section, adding only entries from
  this feed. Be careful. Use case: Events, or when only data from the
  current feed is required.

  "I want only the entries from this feed in this section."


How to display the last 4 digits of the credit card used for a Craft Commerce purchase I'd like to display the last 4 digits of the credit card used for a purchase in a front-end template. It appears the data is in the db in the craft_commerce_transactions table reference column in JSON format.

{
    "approvalCode":"PNRABL",
    "transId":"60007205645",
    "card": {
        "number":"1234",
        "expiry":"112318"
    }
}

Is there a method supported by Craft Commerce to display this data in a users account area?

I'm not sure whether you're referring to displaying this in the Control Panel somewhere or on the front-end of a site in a user account area.

Assuming it's on the front-end of a site and you've already got a reference to the order, it'd be something like:

{# Grab an order #}
{% set order = craft.commerce.orders.id(15).first() %}

{% if order %}
    {% Grab all of it's transactions %}
    {% set transactions = order.getTransactions() %}

    {# Loop through all of them looking for the one(s) you're interested in on this order.  Here, we just grab the first. #}
    {% set transaction = transactions[0] %}

    {# Output the reference #}
    {{ transaction.reference }}
{% endif %}

Keep in mind that the reference value is a response that comes back directly from the particular payment gateway, so it may or may not even be JSON, much less include the last 4 digits of a credit card number.  If it is JSON, XML, etc. then you'll need to parse that value looking for where they save the last 4 digits.


Is there a way to limit output of Tags related to an entry? I've checked it with documentation but, tag model doesn't have limit() property as entries have.

Wondering, If there is any way around to achieve it?

A limit doesn't make sense on a single element model. But all ElementCriteriaModels have a limit parameter and for craft.tags it is documented here.

To limit the tags related to an entry via a Tags field don't use the shortcut syntax:

{% set tags = entry.tagsFieldHandle %}

But modify the craft.tags ElementCriteriaModel instead:

{% set tags = craft.tags({
    relatedTo: { sourceElement: entry, field: "tagsFieldHandle" },
    order:     "sortOrder",
    limit:     null
}) %}


Include a PHP resource within a Plugin I'm trying to include a PHP file (BrowserDetection) within my plugin.

I've tried this:

Craft::import('plugins.myPlugin.resources.php.BrowserDetection');

Which doesn't return any errors, but also doesn't work. I've also tried:

require_once 'resources/php/BrowserDetection.php';

Which does pull in the file, but each time I tried to refer to it like: "$browser = new BrowserDetection();" I get something like this:

  Fatal error: Class 'Craft\BrowserDetection' not found in /Volumes/Mark
  Notton/Clients/The STC/Website/craft/plugins/myPlugin/MyPlugin.php on line
  33

Apologies for the very noob question. I just don't understand how to pull in additional PHP resources. Perhaps I'm overlooking some bespoke craft syntax?

The first one example should work as long as the last BrowserDetection segment maps to the actual BrowserDetection.php file on the file system.

  Fatal error: Class 'Craft\BrowserDetection' not found in /Volumes/Mark Notton/Clients/The STC/Website/craft/plugins/myPlugin/MyPlugin.php on line 33

You'd still even get that error on the first one because the BrowserDetection class is in PHP's global namespace.

You need to do:

$browser = new \BrowserDetection();


Order entries by category field I'm loading a set of entries related to 'category' and ordering them by the value of a Dropdown field in the entries. This work well using this code:

{% set entries = craft.entries.relatedTo(category).order('myDropdownField') %}

Now I need to change the Dropdown field to a Category field, but I am not able to sort my entries by this new category field by swapping the dropdown with the category field like this:

{% set entries = craft.entries.relatedTo(category).order('myNewCatField') %}

It gives me this error:

  CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'departmentCat' in 'order clause'.

I also tried to use the Craft group filter, but I could not make it work in my setting.

Any suggestions are appreciated!

Here's a solution using the group filter.

{% set entriesGrouped = craft.entries.relatedTo(category).order('title')|group('myNewCategoriesField.first().title') %}

{% for group in entriesGrouped %}
    {% for entry in group %}

        {# ... #}

    {% endfor %}
{% endfor %}


Show only products in stock - one variant only In Craft Commerce, how can I show only products that are in stock when not using variants?

For example, this query, but only show products with a stock with 1 or more:

{% set productQuery = craft.products()
        .relatedTo(block.relation)
        .availableForPurchase()
        .order('postDate desc')
        .limit(4) %}

    {% set products = productQuery.all() %}

    {% for product in products %}
      {% include "_components/product-blurb.html" %}
    {% endfor %}

You're always using variants. Just that if you have no 'other' variants commerce hides that stuff away. But your product has a defaultVariant behind the scenes.

Adding…

.hasVariant({ hasStock: true })

…to your query should (I think) return your products that have ([hidden] variants in) stock.


Route to Controller action (not in a plugin) Let's say i have a FooController extending Craft\BaseController located somewhere else (not in a plugin). The FooController is autoloaded via composer and the autoload.php is included in public/index.php

Would there be a way to route to this FooController? Is it not possible with Craft (or Yii) to just say something laravel like: Route::get('foo/bar', 'FooController@bar')?

Edit (follow up question):
If I have something like this in my registerSiteRoutes function:

 return [
     'foo/bar' => ['action' => 'plugin/foo/bar', 'additional' => 'acme'],
 ];

Would I be able to access the 'additional' information in the controller?

As it turns out it's not really possible to break out of the intended craft workflow. If you don't want to put additional business logic in plugins, you're only option is changing the index file. Which I did like this:

try
{
    $app->run();
}
catch(CHttpException $exception)
{
    // Implement custom route logic here
    // If nothing matches your own routes, just rethrow the $exception
    // like so:
    //throw $exception;
}

I'm more playing around here the learn how craft works, in the end the best solution is probably to just go with a plugin.


Error on homepage of local server no changes made since last working? I have just gone back to a site I am working on locally to continue working on it. 2 days ago it was working fine and I have made no changes. I now have this error when I load the homepage.

unserialize(): Error at offset 0 of 24 bytes

C:\Websites\website\craft\app\framework\caching\CCache.php(108)

Anyone have any idea why this has happened and how to fix it as I say nothing had changed with the files or with the MAMP install.

Cheers

Ok I have resolved this by deleting all the cache files in the craft|storage|runtime|cache folder. But whilst this has worked my question is now why did it happen. Not something I want to experience on a live site?


Display thumbnail using defineTableAttributes for a custom Element Type Hi,

I'm new to Craft and VERY new to plugin development.  I'd like to display a thumbnail image in my table list view and thought it would be possible to accomplish using a new Custom Element Type.  Does anybody know how to achieve this?

I have managed to output custom fields in the table using defineTableAttributes() but I can't output any related Assets - in particular their filenames. Do I need to define a relation in the ElementCriteriaModel using the defineCriteriaAttributes() function?  Can anyone explain how this is done?

Many thanks

Ok, so I've managed to get an answer to this courtesy of Brandon Kelly.  It's much more simple than I thought.  Firstly, you do not have to specify a relatedTo parameter the defineCriteriaAttributes(). Craft takes care of this automatically.  So in order to retrieve the details of an asset in a table list view you do the following in the getTableAttributeHtml() function in your custom Element Type class:

$relatedAsset = $element->myAssetsField->first();

This simple line of code gets a related myAssetsField of your element. I'm not sure why, but this object is placed in an array...  Maybe someone can tell me why this is the case?

I then took the fist element of the array and used a the getThumbUrl() function which is really handy for quickly outputting the url to a thumbnail.  I passed a size of 60 pixels.

case 'myAttribute>':
{
   if(count($relatedAsset) > 0) {
      return '<img src="'.$relatedAsset[0]->getThumbUrl(60).'">';
   }
   return '';
}

The result is a thumbnail in your table list!
Hope this helps others....


Why are variables persisting inside of my for loop? Is anyone able to tell me why variables which I've defined inside of a for loop are persisting and retaining their values on into consecutive iterations? In order to overcome this, I've had to set them back to null each time. I'm relatively new to Craft and Twig but this seems like a bug. Has anyone else experienced this?

    {% for entry in entries %}

      {# I shouldn't have to set these to null for each loop iteration, #}
      {# but they seem to be retaining their values #}

      {% set photo = null %}
      {% set width = null %}
      {% set height = null %}
      {% set orientation = null %}

      {% if entry.photo | length %}
        {% set photo = entry.photo.first() %}
        {% set width = photo.width %}
        {% set height = photo.height %}
        {% set orientation = '' %}

        {% if width > height %}
          {% set orientation = 'landscape' %}
        {% elseif height > width %}
          {% set orientation = 'portrait' %}
        {% elseif width == height %}
          {% set orientation = 'square' %}
        {% endif %}
      {% endif %}

        {% if entry.photo | length %}

        {% endif %}

    {% endfor %}

This is totally normal and expected behavior. In fact, it's critical for some looping situations, and pretty standard across programming languages. Wouldn't you expect to find this same behavior in PHP?

Think about situations where previous loops build on each other. Here's an example of a situation where loop values need to be retained...

{% set totalPets = 0 %}

{% for petOwner in craft.entries.section('petOwners').find %}

    {% set totalPets = totalPets + petOwner.numberOwned %}

{% endfor %}

This group of people owns {{ totalPets }} pets total.

Ultimately, this is a simple scope issue. Generally speaking, for loops don't exist in their own scope... they are a part of the scope created by the parent script.

If you want to ensure that your logic takes place in a separate scope, take a look into Twig macros... A macro would probably be very helpful in your situation.


How call PHP native function in Model/Service/Controller scope I need to make a SoapClient new SoapClient call from within one of my Models for a validation rule. When I create the new SoapClient instance class in my Model function I'm getting this error message:

Fatal error: Class 'Craft\SoapClient' not found in...

I get the same error message whatever file Model/Service/Controller i put it in.

public function validateVatNumber()
{
    $client = new SoapClient("http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl");
}

Could anyone let me know what I should do to be able to make these calls? I'm guessing I somehow need to "break free" from the Craft namespace.

Thank you

You need to backslash the class to tell it to look in the global namespace like so:

public function validateVatNumber()
{
    $client = new \SoapClient("http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl");
}

You can read on the basics of PHP namespacing here: http://php.net/manual/en/language.namespaces.basics.php


Check if title field has a string in ElementAPI I am trying to retrieve search suggestions for a search form. I sent the parameter entered by the user, but how do I do it in the criteria?
I tried this:

'criteria' => [
    'search' => 'title: *'.Craft::$app->request->getParam("key").'*'
],

but it does not return any results. What am I doing wrong?
this is my entire endpoint:

'suggests' =>function(){
        return [
            'elementType' => Product::class,
            'paginate' => false,
            'pretty' => true,
            'criteria' => [
                'limit' => 15,
                'search' => 'title: *'.Craft::$app->request->getParam("key").'*'
            ],
            'transformer' => function(Product $product)  {
                return [
                    'title' => $product->title,
                    'url' => $product->url
                ];
            },
        ];
    },

I got it.

'criteria' => [ 'title' => '*'.Craft::$app->request->getParam("key").'*' ]


Bilingual site page URL issues I'm trying to setup a bilingual site and I'm having some issues with setting up the URI.

'siteUrl' => array(
    'en' => 'http://localhost/mysite',
    'fr' => 'http://localhost/mysite/fr',
),
'environmentVariables' => array(
    'baseUrl'  => 'http://localhost/mysite/',
)

In my single settings:
URI for french: {baseUrl}fr/nouvelles
URI for english: {baseUrl}news

Not sure how to set this up to have it setup the way I want it.  Removing the baseURL part just doesn't print the mysite subfolder.

Thanks!

EDIT:  Here's the real problematic after investigation.

The URI should not include anything more than the name so:
In my single settings:
URI for french: nouvelles (http://localhost/mysite/fr/nouvelles)
URI for english: news (http://localhost/mysite/news)

Now, those 2 pages work like expected.

But, if I assign those pages to a Entries field, to create my menu, when I pull the url, it never inclues the /fr portion.  Even the default template doesn't render the correct link, dropping the /fr part in the url too:

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

{{ entry.title }}

{% endfor %}

Well... the answer was quite simple.

'siteUrl' => array(
    'en_ca' => 'http://localhost/mysite',
    'fr_ca' => 'http://localhost/mysite/fr',
),

The _ca part was what was missing.  Now my site works amazingly.

Sorry for the run around and I hope this can help someone.


How can I get Sprout Forms errors in current language using AJAX? I'm using a form using Sprout Forms plugin. This form is set for submitting via AJAX. The documentation explains how to translate error message, but this is not working via AJAX submissions.

Currently, the primary language of this website is French. While the site is browsed in English or Dutch, it still shows AJAX errors in French.

How can I get Sprout Forms errors in current language using AJAX?

The AJAX POST url variable (postUrl) should be set from the form template with this Twig code:

<script type="text/javascript">
    var postUrl;
    if ('{{ craft.i18n.getCurrentLocale() }}' == '{{ craft.i18n.getPrimarySiteLocale() }}') {
        postUrl = '/';
    } else {
        postUrl = '/{{ craft.i18n.getCurrentLocale() }}/';
    }
</script>

Furthermore, an hidden field should be added in order to call the Sprout Forms' controller on submit:

<input type="hidden" name="action" value="sproutForms/entries/saveEntry">

This submits the form in the current locale, and returns errors in this same locale.


Neo: children won't display or I get all() deprecation notice I have a Neo field set up like so:

-Row
--Column
-Body

Columns can also contain body.

With this:

{% set modules = entry.pageBuilder
        .with([
            'moduleBody',
            'moduleRow',
            'moduleColumn',
        ])
        .level(1)
        .all()
%}

{% for module in modules %}
    {% if module.type != 'moduleColumn' %}
        {% include '_partials/page-builder/_' ~ module.type %}
    {% endif %}
{% endfor %}

{% set moduleArray = [] %}

{# Remove duplicate module types from array #}
{% for moduleType in modules %}
    {% if moduleType.type not in moduleArray %}
        {% set moduleArray = moduleArray|merge([moduleType.type]) %}
    {% endif %}
{% endfor %}

_moduleBody.twig

  {% if module.heading %}
{{ module.heading }}
{% endif %}
  {{ module.body }}

I get body blocks output fine if they're not nested in a row/column.

_moduleRow.twig

    {% set columns = module.children %}
    {% for column in columns %}

    {% for item in column.children %}
        {% include '_partials/page-builder/_' ~ item.type %}
    {% endfor %}

    {% endfor %}

With the above, I get an error:

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

If I change set columns = module.children to set columns = module.children.all() I get the same thing. If I change it to

{% set columns = module.children
        .with(['moduleColumn'])
        .level(1)
        .all()
%}

there's no error, but no output either (other than the HTML for the row which is outside the code for the column contents).

What do I need to do to get the columns to output?

I guess I'm also going to have a problem with for item in column.children because inside moduleBody it's calling module.variable not item.variable but if the outer loop uses module, I can't use it for the inner loop too.

For anyone else having a similar problem, the solution was this:

    {% for module in entry.pageBuilder.all() %}
        {% do module.useMemoized(entry.pageBuilder) %}
    {% endfor %}

    {% for module in entry.pageBuilder.all() if module.level == 1 %}
        {% if module.type != 'moduleColumn' %}
            {% include '_partials/page-builder/_' ~ module.type %}
        {% endif %}
    {% endfor %}

and then inside _moduleRow.twig

        {% for module in module.children.all() %}
            {% if module.type == 'moduleColumn' %}

                {% for module in module.children.all() %}
                    {% include '_partials/page-builder/_' ~ module.type %}
                {% endfor %}

            {% else %}
                {% include '_partials/page-builder/_' ~ module.type %}
            {% endif %}
        {% endfor %}


Update 3.5.15.1 - Fixed a bug where the Updates utility wasn’t showing “Update” buttons The update button is missing, and the fix is available, but impossible to initiate from the CP.

Before I embark on a manual update, I wondered if there was a URL that I could use to trigger the update? (What URL does the button normally run?|)
Cheers
Matt

Not a URL, but you can do it from the command line by running either:
php craft update craft

Or
composer update craftcms/cms

You can see the issue for this here: https://github.com/craftcms/cms/issues/7091


Mcrypt not recognized I have nginx and PHP up and running.  phpinfo() shows that mcrypt is installed and enabled.  I was sure to sudo php5enmod mcrypt.  However, Craft is still complaining the mcrypt isn't installed.  What else can I troubleshoot?

Nevermind.  Must have been caching or something.  I'm up and running.  Computer voodoo.


Load an asset at random each page load I have a single that has 5 banner images. I would like to load a different image each time the page loads. I want to do this with twig not JS, is this possible if so could somone point me in the right direction.

Thanks in advance

Simply using 'RAND()' in the order parameter does the trick.

{% for image in entry.banner.limit(1).order('RAND()') %}
  {{ image.url }}
{% endfor %}


Plugins get removed after publishing to Heroku I'm using Heroku and every time I push changes to Heroku, the plugins installed from the plugin store get removed. Do I need to add them to my composer file manually?

This is the way Heroku works with its ephemeral file system. Anything written by the webapp (which includes plugins installed via Composer) after the fact can be wiped out at any time.

If you must ship it on Heroku, you probably should check all of vendor/ into the repo, so that it's part of the actual deployment, and not added post facto.


How could I load content from one Craft install into a template of another We are working on a help guide solution for Craft and our hope is to have all the guide content live in a single master Craft setup and then our client's sites could read and display this content in their admins through a custom plugin.

We have the rough outlines of a proof of concept for it, the missing piece is sharing the content.  We are thinking of using RSS or JSON to do this but wanted to see if there was any other ways we should consider?

I think your idea of RSS or JSON would work fine.

The only reason I can think of to use RSS over JSON would be if there was a possibility you wanted RSS readers to be able to consume the content as well.  Otherwise, I'd just stick with JSON and expose it over a web accessible API.


Can't Access Image URL on Single Page I have the 404 page setup as a single in sections under page404.

I have a postImage field that pulls images from assets.  It is assigned to the page404 field layout and it is assigned in the entry.

I tried the this template approach:

{% set notFound = craft.entries.section('page404') %}
<img src="{{ notFound.postImage.first().url }}" width="800" height="800" alt="">

but I keep getting the following error:

  Impossible to access an attribute ("url") on a null variable

What am I doing wrong, and how should it be template?

You left off the .first().

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

Without that, the Element Criteria Model will default to .find().

first - Returns a single Entry Model.
find - Returns an array of Entry Models.

It doesn't matter this this is a Single section! All Element Criteria Models have the same behavior, whether they're fetching data from a Single, Channel, or Structure.


Craft suddenly no longer works on Heroku I’ve suddenly started having problems with Craft on Heroku. It worked fine for a while but if I composer install anything later than Craft 3.2 I get the same error back from Heroku:

2020-02-21T01:22:32.775659+00:00 heroku[router]: at=info method=GET path="/" host=connor-heroku-test.herokuapp.com request_id=7df849c1-4f9b-46f3-aaba-2bf88e0f0b1e fwd="151.226.158.115" dyno=web.1 connect=0ms service=52ms status=500 bytes=182 protocol=https
2020-02-21T01:22:32.775695+00:00 app[web.1]: [21-Feb-2020 01:22:32 UTC] PHP Fatal error:  Uncaught Error: Call to undefined function mb_regex_encoding() in /app/vendor/voku/portable-utf8/src/voku/helper/UTF8.php:490
2020-02-21T01:22:32.775707+00:00 app[web.1]: Stack trace:
2020-02-21T01:22:32.775896+00:00 app[web.1]: #0 /app/vendor/voku/portable-utf8/bootstrap.php(7): voku\helper\UTF8::checkForSupport()
2020-02-21T01:22:32.776075+00:00 app[web.1]: #1 /app/vendor/composer/autoload_real.php(66): require('/app/vendor/vok...')
2020-02-21T01:22:32.776292+00:00 app[web.1]: #2 /app/vendor/composer/autoload_real.php(56): composerRequiredcd24579acb46ca3092f278cf90a0024()
2020-02-21T01:22:32.776510+00:00 app[web.1]: #3 /app/vendor/autoload.php(7): ComposerAutoloaderInitdcd24579acb46ca3092f278cf90a0024::getLoader()
2020-02-21T01:22:32.776658+00:00 app[web.1]: #4 /app/web/index.php(11): require_once('/app/vendor/aut...')
2020-02-21T01:22:32.776702+00:00 app[web.1]: #5 {main}
2020-02-21T01:22:32.776885+00:00 app[web.1]: thrown in /app/vendor/voku/portable-utf8/src/voku/helper/UTF8.php on line 490
2020-02-21T01:22:32.777446+00:00 app[web.1]: 10.32.124.137 - - [21/Feb/2020:01:22:32 +0000] "GET / HTTP/1.1" 500 5 "https://dashboard.heroku.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.4 Safari/605.1.15

Every version I’ve tried works fine on local.

Any ideas about what I can do to sort this?

Thanks!

This bit us a few days ago, as well.

As far as I could tell from the build log, the cause was that Heroku bumping their PHP version from 7.3.x to 7.4.x, and exposing an incompatibility with one of Craft's dependencies.

To lock your PHP version to a 7.3.x release on the Heroku stack, just add this to your composer.json:

{
  // ...
  "require": {
    "php": "~7.3.0"
    // ...
  }
  // ...
}


Feed Me - Importing CSV Fails I am trying to import a few reasonably straightforward fields to populate some entries from a CSV. It seems to run ok but nothing comes through and when I look a the logs I get the error below - anyone know what this means?

The shell command "mysqldump --defaults-extra-file="C:\Users\Malcolm\Google Drive\CRAFT-SITES\marshall-bridge\storage\runtime\temp\my.cnf" --add-drop-table --comments --create-options --dump-date --no-autocommit --routines --set-charset --triggers --single-transaction --no-data --result-file="C:\Users\Malcolm\Google Drive\CRAFT-SITES\marshall-bridge\storage\backups/feedme-190524_100041_cdm7gla482.sql" marshall-bridge && mysqldump --defaults-extra-file="C:\Users\Malcolm\Google Drive\CRAFT-SITES\marshall-bridge\storage\runtime\temp\my.cnf" --add-drop-table --comments --create-options --dump-date --no-autocommit --routines --set-charset --triggers --no-create-info --ignore-table=marshall-bridge.assetindexdata --ignore-table=marshall-bridge.assettransformindex --ignore-table=marshall-bridge.sessions --ignore-table=marshall-bridge.templatecaches --ignore-table=marshall-bridge.templatecachequeries --ignore-table=marshall-bridge.templatecacheelements --ignore-table=marshall-bridge.cache --ignore-table=marshall-bridge.templatecachecriteria marshall-bridge >> "C:\Users\Malcolm\Google Drive\CRAFT-SITES\marshall-bridge\storage\backups/feedme-190524_100041_cdm7gla482.sql"" failed with exit code 1. - Connection.php: 58

Take a manual back up of your database and then disable Database back up on the feed settings.

If you're using MAMP, this could be your issue.


Working with multiple categories Does anyone know if you can work with releatedTo between categories? I’d like to get all the categories in a categories.groups that are related to a single category

I have some entries in a channel, lets call it parts. The parts have two categories from two separate groups.

Group 1 is partType which has the categories engine interior and transmission
Group 2 is manufacturer which has the categories ford and chrysler.

On the category-page for ford, i’d like to list all the parts in the ford category, grouped by partType

But I don’t wand to show the partType categories that have no parts by the current manufacturer

I figured it out!

If anyone is stuck at the same place here’s my solution:

{# category is 'ford' #}
{% set entries = craft.entries.section('support').relatedTo(category).find() %}
{% set partsCategories = craft.categories.group('partsGroup').relatedTo(entries) %}

{# Partslist #}
{% for partsCategory in partsCategories %}

    {{partsCategory.title}}
    {% for part in craft.entries.relatedTo([
      'and',
      { targetElement: partsCategory },
      { targetElement: category }
    ]) %}

      {{part.title}}

    {% endfor %}
{% endfor %}


UX issue with new email verification link I'm working on a profile management form for a site with public registration enabled. I'd like users to be able to change their email address. I've got it working as Craft intended -- they enter their email + current password, a "Verify new email address" email is triggered, and following the verification link updates their email.

The UX wall I'm hitting is that a) the user is logged out when click the verification link and b) they get no messaging around whether or not the email was actually changed.

I've reviewed the code and don't see any way to improve this experience. I found https://github.com/craftcms/cms/issues/1421 but the workaround in there seems heavy handed.

Has anyone come up with an elegant solution for this?

The only way I found to accomplish this was with a custom controller that essentially overrode actionVerifyEmail and _processTokenRequest from UsersController. (With a hook into email.onBeforeSendEmail to rewrite the verification {{link}} to use the custom controller action). It's fragile, but it works.

I've created a feature request to smooth out this experience:
https://github.com/craftcms/cms/issues/1228


Get entries based on custom field lightswitch in custom plugin in Craft 2 I am trying to get the entries in my custom plugin template ( CP )

Each entry has a lightswitch I want to fetch only those where lightswitch is enabled.

In controller file:

$criteria = craft()->elements->getCriteria(ElementType::Entry);
$criteria->section('articles');
$criteria->relatedTo(array(
    'field' => 'lightswitchFieldHandle'
));
$criteria->limit = 20;
$products['entries'] = $criteria->find();
$this->renderTemplate('sponsoredentries/_index', $products);

But I am getting 20 entries (as per limit but not as per field)

You need to set the value of your Lightswitch field directly instead of using the relatedTo parameter

$criteria->lightswitchFieldHandle = '1';


Multiple Environments Multiple S3 Hi is there a way that we can manage the S3 bucket and configuration from craft general default config per envirenmont?

We are doing automated deployments to different envirenmonts which migrate the databases but are still manually changing the s3 bucket.

Thanks,

Ian

Currently not, but there probably should be.

There is already a somewhat related, similar feature request here.


Does Craft work with PHP 7? I'm attempting to run Craft (2.4.2696) on a server with PHP 7 RC, and I'm seeing the following PHP warning:

Declaration of Craft\DbCommand::addForeignKey($table, $columns, $refTable, $refColumns, $delete = NULL, $update = NULL) should be compatible with CDbCommand::addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete = NULL, $update = NULL)

It's only a warning, and with devMode off, the site seems to function well. I'm not going to put anything that throws warnings into production, though.

My question(s): What is the cause for this warning, and is it something I can fix myself? Does Craft officially support PHP 7?

As @mmikkel pointed out, as of Craft 2.4.2697, Craft is PHP 7 compatible.


404 Error showing for Asset Images In the backend, I could upload an image. I see it loads fine in the backend admin CP.

But it goes to a 404 error on the front end.

File System Path:
/home/devserv1/colorcomputergames.com/assets/clones/

The URL to your folder:
http://www.colorcomputergames.com/assets/clones/

The direct URL to the image is:
www.colorcomputergames.com/assets/clones/lunar_lander.png

But it brings up a 404 Error. I read here to look into the server settings. I'm running Apache.

Thanks

Figured it out. I assumed that my assets folder needed 744 just as the install instructions mentioned for the Craft CMS folders. But, I need to change the permissions to the standard 755. Once I did, I could view the images.


Adding class based on length I'm using Neo to allow my client to be able to create a content grid with child blocks. Now I'm wondering, is there a way that I can change the class of the output based on the number of items?  For example, if there are two items I'd like to have the class grid-one-half and if there are three grid-one-third etc. to give my client more flexibility in making grids.

Thanks!

I figured it out by modifying the code from this answer on image transforms. Here's the basics of my markup.

<div class="{% if loop.length == 2 %}grid-one-half{% elseif loop.length == 3 %}grid-one-third{% elseif loop.length == 4 %}grid-one-quarter{% endif %} grid-item">
</div>


How do you query for Asset Folders? I'm building a customer portal for work, and we are storing customer-facing files on the site in an Amazon S3 bucket. I currently have it all set up as a Structure section with an Asset field. I query for each entry using its uri, and for Folder Entry Types I pull and output its children.

My hope is that I can instead query for Asset folders and files directly, and then add a few fields to Assets (through the usual methods). Querying for files is fine, but I can't see any variables to pull folders. Would I need to write a plugin for this?

Writing a plugin would be your best shot. You can use AssetsService to get all the information you need (http://buildwithcraft.com/classreference/services/AssetsService)

This might change with a future release, but the need to query Assets folders directly from a template is so rare, that I'm not entirely convinced it will make it's way into a future release at this point.


How to structurize a multi-project documentation site? I'm currently working on our new Docs website. This site should hold the documentation for all our projects.

I thought I could structurize the content like this:

Project 1 (<-- Section)
    Project section header 1 (<-- Structure)
        Menu item 1.1
        Menu item 1.2
        Menu item 1.3
        Menu item 1.4
        Menu item 1.5
    Project section header 2
        Menu item 2.1
        Menu item 2.2
        Menu item 2.3

Project 2 (<-- Section)
    Project section header 1 (<-- Structure for Project 2)
        Menu item 1.1
        Menu item 1.2
        Menu item 1.3
        Menu item 1.4
        Menu item 1.5
    Project section header 2
        Menu item 2.1
        Menu item 2.2
        Menu item 2.3

I'd also like to have a dropdown which should list all available projects (Project 1, Project 2, ... from the above sample). If the visitor selects his desired project, a menu tree should be rendered in the sidebar with the corresponding structure.

Is this the right way?

Welcome to the Craft community. You try to create a new section for each project - right? In my opinion this is only necessary if you need different view and edit rights on each project. If you'r creating a "open for all" project documentation tool (open means for only one user group), than i would go with a single section. It's much easier to manage and starting with a new project. I would use two entry types in the section (https://craftcms.com/docs/sections-and-entries#entry-types). One entry type is for the project and one is for your chapters and the content.

    Example:
    1x Section called "projects"
        1x entry type called "project" with following fields (example)
            - name
            - project description (rich text field)
            - project team (user field)
            - release date (table field with date and description)
            - ...

        1x entry type called "chapter" with following fields (example)
            - name/title
            - content (richt text field)
            - images (file field)
            - documents (file field)
            - ...

    Finaly you "project" section would be like this:
    Project 1 (entry type "project")
        - Chapter 1 (entry type "chapter")
           - Chapter 1.1 (entry type "chapter")
           - Chapter 1.2 (entry type "chapter")
        - Chapter 2 (entry type "chapter")
           - Chapter 2.1 (entry type "chapter")
           - ...
        - Chapter ...

    Project 2 (entry type "project")
        - Chapter 1 (entry type "chapter")
           - ...

For creating the dropdown-navigation, you can simple use the nav tag (https://craftcms.com/docs/templating/nav). Instead of a use option tags for output:

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

<select id="nav" onchange="if (this.value) window.location.href=this.value">
    {% nav entry in entries %}
        <option value="{{ entry.url }}">{{ entry.title }}</option>
    {% endnav %}
</select>

For the subnavigation you could take a look on this Craft recipe -> https://craftcookbook.net/recipes/fully-dynamic-hierarchical-nav-menu-template.

Other solutions:
Depending on how many content is used in each chapter, you could also make use of a matrix fields for your content...

Doe's this make sense for you?


Is there a guide for using Craft Commerce headless? I’m trying to figure out the work involved in using Craft Commerce in a headless setup. Is it possible? I think so. How do I expose the Commerce functionality via an API, instead of through Twig templates? I don’t know.

I’ve done a general Google search, skimmed the Commerce docs, checked NY 17, and checked CraftQuest. I may have missed something. Can anyone point me in the right direction?

After looking at the Commerce docs further, I see I can use the GraphQL API to get information from Commerce. That is, at least for products. Craft 3.5 will allow GraphQL mutations so perhaps that’ll encompass some sort of write API to commerce. If not, I’ll have to create custom endpoints in the Craft app to do the following:

Create customer account
Edit customer account
Edit subscription info
Edit cart
Checkout


Use twig Var in for loop the var menutype is set to {{ menutype }}

{% for block in menutype.menuGlobal %}

I'm trying to pass the result of {{ menutype }} into the for loop to return a dynamic menu, but the loop doesn't run. Hardcoding the string works, so the loop is fine, just appears not to recognise the variable output in the for statement.

Please try the following code:

{% set dynamicMenu = menutype~".menuGlobal" %}

{% for block in dynamicMenu %}
.
.
.
{% endfor %}


Social Login plugin question I am using the Social Login plugin from Dukt. It mentions in the configuration instructions to add things to a social.php file that you place in craft>config.

I've done that, but I assume I'm doing something wrong with the PHP file, as it just shows up in the CP on the social login settings page, rather than actually performing the additional functions I'm looking for.

I'm not super well-versed in PHP, so I'm sure its user error. Can anyone help? Here's the contents of my PHP file:

'lockDomains' => [
'awebaddress.net']

And here is what is showing up in the control panel:

Your /craft/config/social.php file should probably look like this:

<?php

return [
    'lockDomains' => [
        'awebaddress.net',
    ],
];

If you wanted to add more config settings, that would look like this:

<?php

return [
    'lockDomains' => [
        'awebaddress.net',
    ],
    'allowEmailMatch' => false,
];


How to use better loop for my product images I have a main product image and 4 thumbnails. Main product image is a lightswitch which is named productMainImage.

Here below i first iterate for the main image (which lightswitch is on) and than i make a second for loop for 4 thumbnails.

My problem is i don't like this code and it seems inefficient. I have to go out and go in for the loop because of my html stucture.

Can anyone help me to write this better?

    {% for image in product.productImages %}
      {% if image.productMainImage %}

        {% endif %}
    {% endfor %}

        {% for image in product.productImages %}

        {% endfor %}

One way to do this is to query for the images once, and sort them into two different arrays. This uses twig's merge filter, which is the way to add things to an array in twig.

{% set mainImages = [] %}
{% set otherImages = [] %}

{% for image in product.productImages %}
  {% if image.productMainImage %}
    {% set mainImages = mainImages | merge([image]) %}
  {% else %}
    {% set otherImages = otherImages | merge([image]) %}
  {% endif %}
{% endfor %}

Then you can loop over the mainImages array to get the images with the lightswitch on, and the otherImages array to get the other images.

You will have three for loops, but only one database query.


Contact Form - Missing submissions Good Evening and Merry Christmas.
We are having an issue with some contact form submissions are not submitting emails and the database entry, however they continue through to the redirect page.
The affected submissions seem to be ipad related so far.
I have updated cms and all plugins to latest versions.
submissions are sent via SMTP using Sendgrid.
Can you suggest a way to diagnose the issue?

I would first check any form submission/validation code you might have - it sounds like the redirect is firing before the form actually submits. It may be allowing blanks through, or you could be running into an order of operations issue.


Craft CMS with Google Cloud SQL as backend database Did anybody successfully install Craft on Google Cloud SQL? Or on any MySQL engine with activated replication and active GTID mode?

Craft currently won't operate properly if you have GTID enabled because GTID enforces that every table involved in a SQL statements in one transaction have to utilize the same storage engine.

While virtually all of Craft's tables use InnoDB as the storage engine, the craft_searchindex table is still on MyISAM, because InnoDB didn't add full-text support until MySQL 5.6 and Craft still supports back to MySQL 5.1.

If you're running MySQL 5.6+ (which you should be because I don't believe GTID was introduced until 5.6), then you can manually change the storage engine of the craft_searchindex table from MyISAM to InnoDB and you shouldn't run into any issues.


Download craft error When I download the Craft CMS and try to unpack it. I get the error: "Unexpected end of archive". It seems the download pakage is not complete. When I browse in the .zip file I only see a craft folder (and no public).

Anyone can give me a good download link?

Thanks in advanced

It is probably to do with your connection. I have the same problem here, and I had to use something that can resume downloads to get the complete zip.

For example Chrono Download Manager addon for Chrome might work for that.


Impossible to access an attribute ("url") on a null variable in search results I have a search results page set up like this:

{% set searchResults = craft.entries(queryParams) %}
{% paginate searchResults as pageInfo, pageEntries %}

{% if pageEntries|length %}
  {% for yacht in pageEntries %}
    {% set prevEntry = item.prev %}
    {% set nextEntry = item.next %}
    Link
  {% endfor %}
{% endif %}

That works fine except that it outputs the entry title of the next and previous entries. If I do nextEntry.url or prevEntry.url (or slug) I get:

  Impossible to access an attribute ("url") on a null variable.

Why is that?

You should check if there is a next and previous element. Most likely you reach the end or the beginning of your list and there is no element thus these variables are null so you receive an exception when you try to grab attributes from null


How to do advanced routing to a Craft channel For a project I have, I am unable to use the standard Craft routing for a channel. For example,

/events/{slug}  <- this is how Craft wants to do it
/{slug}         <- this is how the client wants it done

I have tried to do this using routes, and can easily route to the correct template, however the entry is not defined.

Is there any easy way to not have to use Craft's routing that requires the events portion of the url? And have the entry variable available in the template?

Added to this is the fact I need to do URLs like

/{slug}/blog/{article-slug}
/{slug}/faqs/{question-slug}
etc etc

The homepage is a static template, but as there is no content to exist under /events, and being that events is the root of all other content (which is filtered by the event slug) I can't see a way so far to not have to use the full path the 'Craft' way.

Bonus Question:

Is there any way to prevent /events/{slug} from responding to requests also? Is it just using the exit 404 tag in templating?

I'm not sure I understand your question, but to try:

There actually isn't a "standard Craft routing", for channel Sections or anything else.

In your channel's Section settings (available via Settings -> Sections -> [your event section]), there's a field called Entry URL format. Simply add {slug} to that field (and nothing else), and you should be good to go. You can even use the same URL format for different sections.

In regards to your "bonus question", if you set the Entry URL format to simply {slug} for the events section, Craft will probably throw 404 for any /events/{slug} URLs, out of the box.

As for dynamic routes, you're correct that Craft won't populate your template with the entry variable – it will however, populate the template with variables matching the tokens that you add to your route. So, if you e.g. create a dynamic route that uses the <slug> token, you can pull the entry in the template like this:

{# At the top of your template: #}

{% set entry = craft.entries.section('events').slug(slug).first() %}
{% if not entry %}
   {% exit 404 %}
{% endif %}

{# ...the rest of your template #}

Beyond the above – if you're still unsure how to set things up properly, I'd suggest taking a look at the official docs on routing, which explains in detail how Craft evaluates requests and what your different routing options are. Particularly important if you figure that you do need to do some custom routing beyond what the URL format setting can do.


Order Assets by date field I have a page which lists assets by source. I've added a date field to the asset.

How can I order the assets by this field so that the most recent is first?

Here is my markup:

{% set assets = craft.assets.find({sourceId: 2}) %}

{% for asset in assets %}
    {{ asset.date | date('M Y') }}
{% endfor %}

Looking at the cheat sheet for Assets it seems that these are my only options for order:      title, id, sourceId, folderId, filename, kind, width, height, size desc'.

Ideally I could do something like this:

{% set assets = craft.assets.find({sourceId: 2, order: '{{ asset.date }}'}) %}

You're so close it's maddening—you should be able to order by a custom field as well:

{% set assets = craft.assets.find({sourceId: 2, order: 'date desc'}) %}

Where date is the name of your custom field.

From the Craft docs (emphasis added):

  Possible values include 'title', 'id', 'sourceId', 'folderId', 'filename', 'kind', 'width', 'height', 'size', 'dateCreated', and 'dateUpdated', as well as any textual custom field handles.


Making a navigation out of a matrix? I have a matrix with only one block type. and it only has videos ID's it (videoID).

I would like to have this videoID in the url and then fetch the corresponding Matrix Row.

http://www.example.com/segment-1/segment-2/videoID

That said: I know I could get the matrix row ID like this:

{% set test = craft.myMatrixField.id(craft.request.lastSegment()) %}
Video Id: {{ test.videoID }}

But as the ID will change when reordering the matrix, I would like something more Permalink like and use the videoID in the URL.

Anybody knows how to achieve something like this?

Take a look at Craft's advanced routing. You'll need to define a regex pattern in order to create the named subpattern that you want, but once you've done that you can access the variable directly in your template.

In the following example {{ year }} and {{ month }} become available as variables in the news/_archive template

'news/(?P<year>\d{4})/(?P<month>\d{2})' => 'news/_archive',


Redactor source plugin working on Text field but not on a Text field in Matrix I'm on 2.6.2988, I have a text-block in my entry with standard Redactor settings enabled showing the source-button in the menu.

In the same entry I have a Matrix field with text-block with standard Redactor settings but the source-button is not showing.

Is Matrix using a different config?

in german settings look carefully at the Redactor-Konfiguration , if you select Standardwert it uses Simple.json and not Standard.json.


Can User Groups be ordered? I have a site where users move through different groups based on their progress through an eLearning course. On the CP Users page the groups are listed alphabetically down the left. To get them in a meaningful order I have prefixed their names with 1, 2 etc however it would be nice not to have to do this as I re-use these names and in some places the prefix is meaningless.

Is it possible to do something like asset sources where they are 'orderable'?

Not currently, but not a bad idea.  I'll add it to the list.


Most related articles I am using the normal relatedTo property to find related articles, but I have an issue which is:

craft.entries.section('section').relatedTo("tags").id('not ' ~ entry.id).limit(3)

Lets say THIS article has 2 tags: "cat" and "animal",
then I use the normal relatedTo property to get related articles.
Lets say i want three articles

Sometimes I get these three:

article 1 (tags: "dog" and "animal")
article 2 (tags: "cat" and "food")
article 3 (tags: "mouse" and "animal")

But not this one:

article 4 (tags: "cat" and "animal")

How can i get the MOST related articles always? I want the one that has the most matching tags, not just random ones that has at least 1 tag.

If you're only trying to find related articles based on elements (ie tags, categories, entries, etc), you can use my Similar plugin.

Here's a basic example, more info in the repo:

{% set similarEntriesByTags = craft.similar.find({ element: entry, context: entry.tags }) %}

    {% for similarEntry in similarEntriesByTags %}

{{ similarEntry.title }} ({{ similarEntry.count }} tags in common)

    {% endfor %}


How do I access the category of an entry with Element API? The category count is only ever 1 and I need to output the name of the category the entry belongs to.

Would there need to be a cross-over between the EntryModel and CategoryModel?

'transformer' => function(EntryModel $entry) {
                return [
                    'title' => $entry->title,
                    'url' => $entry->url,
                    'jsonUrl' => UrlHelper::getUrl("jobs/{$entry->id}.json"),
                    'postDate' => $entry->postDate->getTimestamp() * 1000,
                    'id' => $entry->id,
                    'jobOverview' => (string) $entry->jobOverview,
                    'category' => $entry->jobCategory[0],
                ];
            },

Same as you would access it from a Twig template.  If you're positive there will always be one category selected, then this would work:

'transformer' => function(EntryModel $entry) {
    return [
        'category' => (string)$entry->categoryHandle[0],
    ];
},


How do I create a plugin to create and save multiple entries from one front-end form? I need to create several entries in different channels from a single front-end form. I realise that to do this I will need to create a plugin to handle the request.

Can I just to iterate over the post values in my controller action, validate them and build the entry models for each new entry, then loop around Craft's EntryService saveEntry() service for each entry I want to save?

Or do I need to write my own saveEntry() service to handle saving multiple entries?

I'd go with your first option.

Grab the $_POST values via craft()->request->getPost(), assemble them in your multiple EntryModels, validate each model, then pass them off to craft()->entry->saveEntry().


Title Format - Object Label instead of Value I am trying to get the label from an object instead of its value to use as the automatic title for my entries.
For example: I have an entry that contains a dropdown with the handle exampleOne with values Item One, Item Two, etc. In the title format field I enter {{object.exampleOne}} and it outputs itemOne. It appears craft is outputting the "value" of that dropdown but I instead want it to output the "Label". Is this possible? I looked through the docs and did some googling but to no avail. I also tried {{ object.exampleOne|label }} but it failed to rename the entries.
Thanks in advance for any assistance!

Here's the documentation you're looking for: Working with Dropdown Field Data
You can get the label by adding .label, so you'll end up with {{object.exampleOne.label}}
The dropdown field contains a few properties:

label
selected
value (default)
valid


For loop that can accept array and element query without throwing .all deprecation error I have a component that accepts both hardcoded objects and entry queries. This allows us to have components that can be used independent of the database.

Hardcode include:

{% include '_components/callToAction' with {
    headline: 'Hardcode call to CTA Headline',
    body: 'Hardcode call to CTA',
    items: [
      { name: 'item1'},
      { name: 'item2'}
    ]
} %}

db include:

{% include '_components/callToAction' with {
    entry: entry.callToAction
} %}

Component:

{% set component = {
  headline: headline ?? entry.headline ?? null,
  body: body ?? entry.body ?? null,
  items: items ?? entry.items ?? null
} %}

{{ component.headline }}

{{ component.body }}

{% for item in component.items %}
  {{ item.name }}
{% endfor %}

Both those work fine, but with Craft 3 we're getting deprecation errors for not using .all() when it is an element query which is drastically increasing our db queries on the pages that use several of these components.

Instead of trying to loop through an object (your Query) you could just execute it

{% set component = {
    headline: headline ?? entry.headline ?? null,
    body: body ?? entry.body ?? null,
    items: items ?? entry.items.all() ?? null
} %}

{{ component.headline }}

{{ component.body }}

{% for item in component.items %}
    {{ item.name }}
{% endfor %}

or if that doesn't fit your case, you can do it before

{% set relatedEntry = entry.callToAction.one() %}
{% include '_components/callToAction' with {
    entry: relatedEntry,
    items: relatedEntry.items.all()
} %}

You could as well check if your variable is an object of type EntryQuery

{% if className(entry) == 'craft\elements\db\EntryQuery' %}
    {% set entry = entry.one() %}
{% endif %}

Note: since you had multiple of these deprecated errors I wasn't exactly sure which one you wanted to "solve" and which one is "intended"


How do I check for the presence of an asset before accessing an empty asset field? I have a single asset field that handles two kinds of images:

1) Big Banner image
2) Small featured image

The problem is I want to check for the presence of the second image before I output it on the page. I am doing it like so:

   {% if entry.igBanner[1] | length %}
      {% set asset = entry.igBanner[1] %}
      <img src={{ asset.url }} class="img-responsive" alt={{entry.title}}>
    {% endif %}

But when I try to check the length of an empty index (where the image is not ), my template crashes saying I am trying to pull a method on a null variable. How do I check the presence of an image asset at index[1]?

You could just check the length of the whole asset array first, to make sure there are two images. Something like this:

{% if (entry.igBanner | length) > 1 %}
    {% set asset = entry.igBanner[1] %}
    <img src={{ asset.url }} class="img-responsive" alt={{entry.title}}>
{% endif %}


Anonymous likes for elements Can anyone help direct me to a plugin or way of anonymously liking articles?

I have used the Like plugin by Duct (https://dukt.net/craft/like) but unfortunately it must be associated to a user account to save the entry.

There's "Upvote" by Lindsey DiLoreto, which allows anonymous voting. Not sure though, if it makes use of cookies and/or logging of IP addresses to forbid people (read: make it harder for them) to vote multiple times.


Is it possible to view 'Expired' entrys on the front end? I have a site with 10000 events which need to expire once they have happened, the main reason for this is to keep things tidy in the CP.

We need users to view events that they have completed after they have expired.

Is there an easy way to render these entries on the front end, without creating a custom route and changing the URL??

Getting the listing is easy enough:

done: user.eventsDoing.date('<'~ now|date('Y-m-d') ).order('date desc').status('expired')

I don't think you can enable the default Entry Routing for expired entries. So you need to add a custom route.

To keep your current URLs, try to rebuild the default Entry Route with a custom one:

news/{slug}  →  news/_entry

Expired entries shouldn't return 404 now any more and load your entry template. You now have to get the Entry Model manually though:

{% set entry = craft.entries.section('news').slug(slug).status('live, expired').first() %}


Add Anchor in WYSIWYG editor How can I add an anchor element in my content. Both the id tag and name attribute are removed from the a tag by the WYSIWYG editor.

For example:

My anchor with a name attribute

My anchor with an id attribute

is replaced by:

My anchor with a name attribute

My anchor with an id attribute

There is a purify and a Clean-up option on a WYSIWYG field.

Clean up HTML? – Whether Craft should run through some HTML cleanup routines when the field is saved, including removing all  tags, empty tags, and most style attributes.

Purify HTML? – Whether the field should run submitted data through HTML Purifier before getting saved to the database, removing any potentially malicious code. Note that this is meant to be be used when accepting input in a Rich Text field from un-trusted sources.

Turning the purify off, let's you output HTML. That being said, I'm not sure of what you are trying to achieve but inserting raw HTML into a WYSYWIG field isn't really the way to go about things. Maybe if you share the bigger scope of the issue, we can look into a better approach of your problem.

source: https://craftcms.com/docs/rich-text-fields


Paginate with category filter? Below is my paginate code and it's working fine.

{% paginate craft.entries.section('products').limit(9) as entriesOnPage %}

{% for entry in entriesOnPage %}

                {{ entry.category.first().title }}

{% endfor %}

{% if paginate.nextUrl %}
    Next
{% endif %}

{% endpaginate %}

Below is my code to display specific category data with pagination. and it's not working.

{% set requestCategory = craft.request.getLastSegment() %}

{% paginate craft.entries.section('products').find({
    search: 'categories:' ~ requestCategory,
  }).limit(9) as entriesOnPage %}

{% for entry in entriesOnPage %}

                {{ entry.category.first().title }}

{% endfor %}

{% if paginate.nextUrl %}
    Next
{% endif %}

{% endpaginate %}

i want to add category filter on that but not working how can i add a category filter?

Try using the relatedTo() filter as explained here:

http://buildwithcraft.com/help/entries-related-to-category

{% paginate craft.entries.section('products').relatedTo(requestCategory).limit(9) as entriesOnPage %}


Craft 3 : What are the advantages to use PostgreSQL and when should I use it instead of MySQL? Craft 3 now supports PostgreSQL.

I know this a very general question, but:

I have absolutely no experience with PostgreSQL
I don't know when should I use it instead of MySQL

To quote Bob Olde Hampsink:

  PostgreSQL is the most innovative and hot database engine at the
  moment. It has better UTF-8 support and better overall performance.

  Also, for example, on Heroku it is much cheaper to host with Postgres
  than with MySQL. Thus it becomes more attractive for people to pick a
  CMS/framework with Postgres support.

Is there another good reasons to know, to choose one instead of the other when starting a new project? For example, in general what would be the gains in terms of performance, compared to MySQL?

This isn't actual first-hand experience talking, but from what I've read, Postgres will start to see gains when we're talking about very large data sets, either in terms of the size of the columns, or the number of rows in a particular table.

As mentioned in the quote above, Postgres also has some other nicities as well. The downside is that there is less tooling around Postgres than there is MySQL, so while you'll be able to find GUI clients, they aren't there in quantity or quality compared to MySQL.

I have had devMode.fm up and running with Craft 3 and Postgres since day 1, in part to get Craft-Scripts working with it (which it does) since it's a supported database type by Craft now, and then also in part just to kick the tires.

What I can tell you is that everything "just works" from a Craft POV. I haven't had any issues at all with the Craft APIs, and since I do the database syncing with Craft-Scripts, the tooling hasn't matter either (but the editor I user is PhpStorm, which can connect to Postgres databases anyway).

You will most likely have to learn a bit about about Postgres handles access permissions, because it's quite different from MySQL, but that's not so bad really.

After using it for a while, my conclusion is that it works fine; but on a small site like devMode.fm, it probably makes absolutely no difference. Because it doesn't have any large db columns or massive numbers of rows of the like. You'd never notice the difference from a frontend/AdminCP POV in terms of which db driver you're using, which is a testament to the work that P&T and the Yiisoft folks have done.


Orderby writing sequence I have this supersimple navigation:

   {% for entry in craft.entries.section('homepage, arbeiten, info, kontakt, shop') %}

         {{ entry.title }}

    {% endfor %}

Is it possible to add an order filter which orders the entry by the order I wrote the entry handles? I tried to apply .fixedOrder but that does nothing.

The fixedOrder parameter makes your entries to be returned in the same order as the IDs you pass to the id parameter. So a simple solution would be to look up the entry IDs of your single section entries and get your entries via their IDs instead of the section handles.

{% set entryIds = [3, 14, 15, 9, 26] %}

{% for entry in craft.entries.id(entryIds).fixedOrder(true) %}

{{ entry.title }}

{% endfor %}

You can eighter look up the IDs in the database, or probably faster: add {{ entry.id }} to your current nav loop!

Update: If you have a good reason to get them via their handles, use this snippet to get the entry IDs.

{% set sectionHandles = ['arbeiten', 'info', 'kontakt', 'shop'] %}

{% cache globally for 3 years %}
    {% set entryIds = [3] %}
    {% for handle in sectionHandles %}
        {% set entryIds = entryIds|merge([ craft.entries.section(handle).first().id ]) %}
    {% endfor %}
{% endcache %}


Add AVG, SUM to an element field I want to use AVG/SUM mysql and add it to the results of a criteria.
Trying to strategize the best way to achieve this.

I'm looking at elements.onBuildElementsQuery, where it seems I could do something like...$query->addSelect('AVG(field_reviewRating) as reviewRatingAverage');

Or do I need to make this a field type (read only)?

I'm going to be dealing with several thousands of entries, so I don't want to have to query everything and loop through.

I could also just call a service from Twig e.g. (craft.custom.getReviewStats(entryModel)), but I wanted to avoid having to add another query for each returned element.

In this case, since I happen to be dealing with reviews, The Star Reviews plugin calculates averages when new ratings are posted: https://www.doublesecretagency.com/plugins/star-ratings


Craft Assets on S3 bucket Is there a way to use a local url when my assets are stored in an S3 bucket?

I have a bucket I'm pointing to and in there I have a folder called backgroundImg with a background.png

I'm trying to access this from my CSS like

background-image: url('backgroundImg/background.png');

But it cannot find this url. It's building the url localhost/assets/backgroundImg/background.png

Is there any way to use the local path instead of an insanely long s3 url that is hardcoded?

You would need to build the complete URL to your file in order for it to work in your CSS.

See this answer:
Do Remote Assets (ie. S3) have file paths?

If the background-image is handled by something like a single or an entry template you could handle it with an inline style tag:

Regular Loading:
{% set image = entry.backgroundImage.first()%}

Eager-loaded:
{% set image = entry.backgroundImage[0] ?? null%}

Template:
<main style="background-image: url({% if image %}{{image.url}}{% endif %});"></main>


PHP Error log in CP gives me 403 forbidden If I want to view the PHP Error logs from craft true utils/logs I get an 403 Forbidden error.

nginx/1.6.2

../admin/utils/logs/phperrors.log

What could be wrong?

Had the same problem. I my case, it was the following code in my nginx config file:

location ~* (?:\.(?:bak|config|sql|fla|ini|log|sh|inc|swp|dist)|~)$ {
    deny all;
}

After removing log| from the list, the problem was solved.


How to search by title field only? How do I change this template code to only return results from the title field of an entry?

The search result page url would look like this: /search-results?q=joe+blogs

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

Thanks for any help.

This seems to work:

{% set entries = craft.entries.section('not lakeDetails').search('title:' ~ query).order('score') %}


Adding reCAPTCHA to the admin login page Is there any plugin or relatively straightforward and accepted way to add a recaptcha to the login for the admin page?

My research so far has come up with nothing. I'm curious if others have looked into this with any result.

We do this at Transform Studios at the DNS level by using cloudflare’s Web Application Firewall. You can basically add a rule which targets any url that matches the control panel login page and secure it with a captcha challenge before giving access to the page. I’ve found this is best to handle security before visitors even hit your site and more importantly prevents any core code base changes or creation of addons.


How to cache a Guzzle Http request? In my module I have the following:

$client = new Client(['base_uri' => myBaseUri]);

$response = $client->request('GET', myQueryString, [
    'headers' => [
        'Accept'            => 'application/json',
        'Accept-Encoding'   => 'deflate,gzip'
    ],
    'connect_timeout' => 3,
    'verify' => false,
    'timeout' => 5,
    'http_errors' => false
]);

$json = $response->getBody();
$data = json_decode($json, true);

How can I cache this so it only does the request every 5 minutes?

You can either cache it globally or in the session

// your cache key
$key = 'akey';

$cache = Craft::$app->getCache();
$value = $cache->get($key);
// check if there is a valid value that is not older than 5 minutes
if ($value !== null && \is_array($value) && isset($value['time']) &&
    $value['time'] >= time() - 3600) {
    return $value['value'];
}

// make your request
$response = Craft::createGuzzleClient(['base_uri' => $myBaseUri])
    ->get('GET', myQueryString, [
    'headers' => [
        'Accept'            => 'application/json',
        'Accept-Encoding'   => 'deflate,gzip'
    ],
    'connect_timeout' => 3,
    'verify' => false,
    'timeout' => 5,
    'http_errors' => false
]);

$json = $response->getBody();
$data = Json::decode($json, true);

// cache it
$cache->set($key,
    'time'  => time(),
    'value' => $data
]);


Can you insert Craft variables into SCSS files and have a plugin generate CSS? I'm using SCSS to write all of my styles and am currently using Codekit for processing it. I want to be able to add some global variables to Craft so I can change color and font vars, which would then be re-compiled into CSS for the site.

Looking through the plugins, I've found the Sprockets port (https://github.com/rkingon/Craft-Plugin--Sprockets/) and AutoMin (https://github.com/aelvan/AutoMin-Craft/). They both look like they'll take a bit to get set up so I wanted to see if I could get some input before I dive in.

My questions are:

Is what I want to do possible? With either one or both, can I set vars in the CMS that are then pulled into a _config.scss file, which is in turn imported into my main.scss file, compiled, and then fed to the browser automatically? I've tried pulling a craft color var into the main css file but it did not replace the twig syntax with the hex color.
Would one of the plugins is better suited to my needs than the other?

I did the port of AutoMin to Craft, and I don't think what you want to do is possible with it. Maybe if you were somehow able to write a new file to disk, with the variables defined in it, and then feed that into the AutoMin, it could work. But seems like a pretty complicated solution.

I'm not sure exactly what you're trying to achieve, but in previous projects where I've let the user control colors and fonts on certain objects, I've just done it with pure CSS. If I wanted to let the client define the link color, I'd just do something like this in :

<style type="text/css">
    a { color: {{ myGlobal.linkColor }} }
</style>

And then not define the link color in my stylesheet.

But this is maybe too simplistic for what you're trying to do? :)


Singles or routes solution Most websites have three distinct types of page.
List of items
Item
Special layout of items / content

A list of entries require a list view. Craft lets us do this with singles - eg blog index page. But we can also just use a template and custom route.

What are the pros and cons of each?
The pros of single index style pages is that I can then build a navigation structure that has an entry link to the single.  Beyond that are there any other reasons why one over the other?

I would like to offer another solution: We always  have a structured section pages where our clients can insert all the pages they want to show. It's a structured section because the menu is generated by this structure and they have certain options in these entries if they should appear in the menu/footermenu and so on.

Different Entry Types in this section have different templates, sometimes when it's required we create special field types to choose different templates as well. When the client wants to insert an "overview" page to display news he/she creates a new entry in our pages section with the entry type news that has a special template that fetches all latest entries in the news section and renders them.

That way we don't need to create a special rule and we don't need to create a single page -> thus we don't need to offer a special menu plugin. From the feedback we got from our clients they prefer this method because they have everything they need in this structured section and they don't need to create a separate menu or something like that. Dragging/moving these entries causes the menu to change and due to Craft it's very intuitive.

When it's required, we restrict the number of times certain entry types can be used. For example we only need one news overview or one login page. It does not make sense to create 3-4 different login pages so as soon as our client selects this entry type it disappears from the list and he/she can only create another login page after the first was deleted.

If you are interested: this is our default template for entries in the pages section

{% extends [
    'pages/_custom/' ~ entry.slug ~ '.twig',
    'pages/_entrytypes/' ~ entry.type ~ '.twig',
    'pages/_generic.twig'
] %}

Craft/Twig takes the first template that is found. _generic is the default content template


ContactForm - Send a confirmation mail How can I send a confirmation Mail to the user who submits the form within the ContactForm Plugin ?

Make your own little plugin that listens to the plugin's contactForm.beforeSend event
and sends the confirmation mail.


Help needed for a simple form I am trying to learn Craft and since I don't know how to create a form with one text area and a button. On the button press, I want to redirect to another html found in the template directory, I am messing around with Craft's contact form to get the desired functionality. I had this code which was working fine:

{% macro errorList(errors) %}
    {% if errors %}

            {% for error in errors %}

{{ error }}

            {% endfor %}

    {% endif %}
{% endmacro %}

{% from _self import errorList %}

<form method="post" action="" accept-charset="UTF-8">
    {{ csrfInput() }}
    <input type="hidden" name="action" value="contact-form/send">
    {{ redirectInput('contact/thanks.html?from={fromName}') }}

Your Name

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

Your Email

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

Subject

    <input id="subject" type="text" name="subject" value="{{ message.subject ?? '' }}">
    {{ message is defined and message ? errorList(message.getErrors('subject')) }}

Message

    <textarea rows="10" cols="40" id="message" name="message">{{ message.message ?? '' }}</textarea>
    {{ message is defined and message ? errorList(message.getErrors('message')) }}

    <input type="submit" value="Send">
</form>

What I did to only have one textbox and a button, I removed a lot of code:

<form method="post" action="" accept-charset="UTF-8">
    {{ csrfInput() }}
    <input type="hidden" name="action" value="contact-form/send">
    {{ redirectInput('contact/thanks.html?from={fromName}') }}

From

    <input id="from-name" type="text" name="fromName" value="{{ message.fromName ?? '' }}">
    <input type="submit" value="Send">
</form>

My thanks.html has the following code:

Thank you {{ craft.app.request.getQueryParam('from') }} will contact you soon

Before changing the code, the redirect worked fine and I was getting the 'from' replaced after the 'Thank you'. After I changed the code, on pressing the button the page refreshes but nothing happens and it doesn't get redirected to the thanks.html page. Please help.

Also, kindly direct me to the documentation which tells in detail about front end development in Craft as the official documentation is very vague (or seems vague to me :( )

I recommend the tutorial https://craftquest.io/courses/how-to-create-craft-plugin Now, It is free after registration. After 1/2h you have your own plugin with settings and form with controller. Simple, straightforward, with craft form component. Your code is quite messy, try tutorial.


Image asset URI returning null I have entries that contain a single graphic asset. I'm trying to use the graphic as a background image in my template. However, I'm unable to output the URI for the asset. I'm using entry.graphic.first().url but I get an error that the property is null. I'm using the dbug plugin to look at the properties and can see that the asset is being returned, however the URI property is null.

I am looping through entries and am unable to return the URI for any of the graphics. Any ideas?

Thanks!

EDIT: Sorry for the lack of code, guys! Below is my whole content block for the page so far.

Video Archives

  {% for entry in craft.entries.section('watch').order('seriesStart desc').type('series') %}
    {% set thumb = entry.graphic.first() %}

  {% endfor %}

Thanks for the help!

Through Pixel and Tonic's support email, I figured out what the issue was. It turns out one of my entries didn't have a thumbnail and that was why the image was null. Stupid user error! I thought I had checked to make sure everything was good but I guess not. Thanks for the help @BradBell.


Store Hours (group days by hours) I'm using the Store Hours plugin to output store hours like this:

{% set days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] %}
{% set daysShort = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'] %}

  {% for dayHours in entry.hoursOfOperation %}

{{ days[loop.index0] }}

    {% if dayHours.open|length and dayHours.close|length %}

{{ dayHours.open|date('h:i a') }} - {{ dayHours.close|date('h:i a') }}

    {% else %}

Closed

    {% endif %}
  {% endfor %}

This works okay and outputs like this:

But what I really need is to be able to group the days if the hours are the same so that it looks like this:

It's also important that I can set an attribute tag on the
 of content="Mo,Tu,We, 10:00-17:00" So how do I group days of the week and output the hours the way my client wants it to look?

I think I have a solution to this problem, but it's kind of complicated. There may be a way to simplify this more.

The basic idea is to loop thru your Store Hours field (entry.hoursOfOperation) and build a new array (storeHours) where the days are combined if the current loop's open and close times match the previous loop's.

{% set days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] %}
{% set daysShort = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'] %}

{# Setup a new array storeHours to hold all you hashes
   and prev variables to compare things to in the loop
 #}
{% set storeHours, prevDays, prevDaysShort, prevOpen, prevClose = [],[],[],"","" %}

{# Loop thru your Store Hours field and build the storeHours array #}
{% for item in entry.hoursOfOperation %}

  {# in the first loop, setup the prevOpen and prevClose variables  #}
  {% if loop.first %}
    {% set prevOpen, prevClose = item.open, item.close %}
  {% endif %}

  {# If the prev hours match the current item's hours,
     add that day's name to the array of prev days, ["Monday","Tuesday"] etc.
   #}
  {% if prevOpen == item.open and prevClose == item.close %}
    {% set prevDays = prevDays|merge([days[loop.index0]]) %}
    {% set prevDaysShort = prevDaysShort|merge([daysShort[loop.index0]]) %}

  {# If it doesn’t match, add prev variables as a hash to the storeHours array,
     Then set all prev variables with current item
   #}
  {% else %}

    {% set storeHours = storeHours|merge([{
      "days" : prevDays,
      "daysShort" : prevDaysShort,
      "open" : prevOpen,
      "close" : prevClose
    }]) %}

    {% set prevDays = [days[loop.index0]] %}
    {% set prevDaysShort = [daysShort[loop.index0]] %}
    {% set prevOpen = item.open %}
    {% set prevClose = item.close %}

  {% endif %}

  {# If last loop, add prev variables as a hash to the storeHours array
     because there won’t be another loop to compare it to.
   #}
  {% if loop.last %}
    {% set storeHours = storeHours|merge([{
      "days" : prevDays,
      "daysShort" : prevDaysShort,
      "open" : prevOpen,
      "close" : prevClose
    }]) %}
  {% endif %}

{% endfor %}

The storeHours data format will be something like this:

[
  {
    "days" : ["Monday", "Tuesday", "Wednesday"],
    "daysShort" : ["Mo","Tu","We"],
    "open" : "2017-01-21 09:30:00.000000",
    "close" : "2017-01-21 21:00:00.000000"
  },
  {
    "days" : ["Thursday","Friday"],
    "daysShort" : ["Th","Fr"],
    "open" : "2017-01-21 09:00:00.000000",
    "close" : "2017-01-21 17:00:00.000000"
  }
]

Once you've created your storeHours array, you can use it to output your HTML code.

  {% for item in storeHours %}

      {{ item.days|first }}{% if item.days|length > 1 %} - {{ item.days|last }}{% endif %}

    {% if item.open|length and item.close|length %}

        {{ item.open|date('h:i a') }} - {{ item.close|date('h:i a') }}

    {% else %}

        Closed

    {% endif %}

  {% endfor %}

BONUS ROUND: if you want to make Monday the first day of the week, reorder the days and daysShort arrays at the top like this:

{% set days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] %}
{% set daysShort = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'] %}

Then add this line just below it:

{% set hoursMondayFirst = entry.hoursOfOperation|slice(1,entry.hoursOfOperation|length)|merge(entry.hoursOfOperation|slice(0,1)) %}

That makes a new variable using Twig's slice filter to take Monday - Saturday (slice(1|length)) and merge Sunday at the end (slice(0,1)).

Now just use this as the start of your loop:

{% for item in hoursMondayFirst %}


Saving big matrix fields problems I'm implementing a site with just one very big matrix field called 'blocks', and all my frontend is designed with BEM CSS with a lot of components.

But i'm facing problems with this big field.

1) If two block types have a field called 'cssClasses' of type 'Multi-select', it's not validating correctly and is saving just one of this fields. I've found a workaround, changing the name of second field, but frequently i lost a lot of field values with this problem. (i really don't know exactly why this problem is happening sometimes)

2) If i have too many fields on my block items, there are some implicit field limit that i don't know where is, that all block item fields after this limit are deleted when save... its a very big problem, because all my entries loose all the data for these fields. It's really a big problem for me... (maybe can be max_input_vars value and/or post_max_size)

3) It's very slow to page render this big field when testing on Amazon(rds large + 1000 IOPS SSD) or Heroku (clearbit database high io), compared to my localhost.

PS:
I'm using LinkIt plugin and SuperTable plugin for some fields...

In a previous project when I was in dev mode, the website was very slow. But when I shut this down it was fast again. Could this be a solution?


What's the best practice for upgrading a versioned Craft site? It's thrilling to click The Button and watch Craft update itself. I take advantage of multi-site configurations with every deploy, and my practice thus far is to...

Upgrade Craft in production.
Commit production file system changes via git.
Choose Settings → Backup Database and download the backup file.
Load the remote changes to my local environment via git.
Clear out and locally import the .sql backup I downloaded in step #3.

I specifically update in production because I like thrills, and because I had previously done the opposite (upgrade locally, push live) and ran into problems.

This has been working for me pretty reliably and Craft upgrades always go smoothly, but I doubt that system updates on the production server are the best idea.

Is there a better way?

I know your method works flawlessly, but it scares the crap out of me.

Luckily Craft's update setup is magical.

What I do is this.

Make sure my repo is clear of unstaged files, just so the update can be in a commit all by itself.
Run the update on my local dev environment (with a local database) (Test)
Commit the updated files and push
Backup live database just in case
Deploy the files on live. (I use Beanstalk, so it uploads the files for me, but you can also do a git pull if that's your method of deployment.) Craft detects that the database version doesn't match the files and puts up a maintenance message.
Visit /admin and click the update button
Drink.


Merging 2 Entries Array's I have these to arrays that I need to merge into one array, but can't figure it out.

Please advise

{% set entries = craft.entries.section('publications').search('nonMembers:0') %}

{% set entries = craft.entries.section('improveYourClub').search('membersExclusive:1') %}

Just a few side notes:

neither the first entries variable nor the second entries variable is an array - both are objects of kind craft\elements\db\EntryQuery (or craft\ElementCriteriaModel if it's Craft 2).
.search('nonMembers:0') can be shortened to nonMembers(0) (or "0" or "not 1" depending on the type) and search('membersExclusive:1') to membersExclusive(1) it will increase your performance as well

So far about that.. You can merge arrays in Twig via |merge filter

{% set values = [1, 2] %}

{% set values = values|merge(['apple', 'orange']) %}

{# values now contains [1, 2, 'apple', 'orange'] #}

EDIT:

To address your case specifically, you'll need something like this...

{% set entriesOne = craft.entries.section('publications').search('nonMembers:0').find() %}
{% set entriesTwo = craft.entries.section('improveYourClub').search('membersExclusive:1').find() %}

{% set allEntries = entriesOne|merge(entriesTwo) %}


.htaccess as a Craft template for 301 redirects? The Reroute plugin is great for a handful of 301 redirects, but we have hundreds of entries and each entry has a legacy URL. Dumping this into a template as normal works fine, but thinking about if it could work with the .htaccess file directly. Has anyone tried, or would be a dangerous path?

Thinking along the lines of NSM htaccess for EE.

If I understand what you're looking for, it's not so much dangerous as it is not possible. Apache looks at the filesystem and parses the .htaccess file directly, and this is done long before Apache starts to process any PHP.

A route you could take is writing the .htaccess file each time an entry is saved (or having a button that does it so you're not wasting resources). So long as PHP has the write access, this should be doable. Plus, you can still render the file via the template service.

$htaccess = craft()->templates->render('PluginHandle/path/to/template');


Error 500 on ttf and woff files I'm having trouble to load an ttf and a woff file in Craft 3. I'm getting an error 500. The files exists and when trying to access it via the browser it shows: Twig Syntax Error – Twig_Error_Syntax Unexpected character "" for both of the files. Any suggestions ?

My issue was that the assets files were in the same folder as the twig template files. Moving the files to the web folder solved the issue.