Show larger images in control panel entries Is there a way to show the images in the control panel entries (both in the detail of the entry and in the overview list using the new customisable columns in 2.5).  The standard preview of the images is so small it hardly is visible to control panel users.

Edit:
On the feedback site this feature request seems to have made it in one way or another to the 2.5 build.  Does anyone know how to use it?

http://feedback.buildwithcraft.com/forums/285221-feature-requests/suggestions/7192735-better-image-preview-and-edit-window-for-asset-fie

The Asset Preview plugin is what you need. This allows you to toggle previews of assets by clicking on them and tapping the space bar. You can also use the arrow keys to navigate through all of the assets on a page.


Iterate through Super Table field in plugin I have a Super Table field with two columns, one is a category field, the other an assets field (limit 1 on both). How can I iterate through it to get the category and asset selected for each row in the table?

$superTable = $entry->colors;
foreach ($superTable as $row) {
    // Category field handle is `color`
    // Asset field handle is `image`

    // I've tried various things here, but I don't understand how to get the fields
    // I'm looking for the category ID and asset ID in every row of the table
}

Assuming your Super Table field has a handle of colors, you should be able to do:

foreach ($entry->colors as $block) {
    // Color will return a category element query, so you can do:

    // Return a collection of all category ids
    Craft::dump($block->color->ids());

    // Get the first category
    Craft::dump($block->color->one());

    // Get all the categories in the field
    Craft::dump($block->color->all());
}


Craft Commerce starting order ids form a higher number? Is there a easy way to start Craft Commerce order ids form a higher number?
So the can follow on from an old system and not overlap?

autoincrement in the DB table maybe?

You can write a Craft plugin that listens to the onBeforeOrderComplete event and implement whatever sort of order number format your business requirements require.

Alternatively here's an existing plugin that uses that method that might already cover your needs: https://github.com/bossanova808/CommerceFriendlyOrderNumbers


Commerce - how to display order address in email to customer? I'm new to commerce but almost I've cracked all I need to my project but one piece still left.
I can't display order shipping address. I've tried
{{ order.shippingAddressId(shippingAddress) }}
but it giving me order referance number.

From documentation:
shippingAddressId #
The id of the linked shipping address. You can get the shipping address model with the shippingAddress attribute.
shippingAddress #
This returns the address model from the database for the current shippingAddressId OR the caches address if the order is complete.

Please help...

Sounds like order.shippingAddress is all you need!

{% set orderAddress = order.shippingAddress %}

{{ orderAddress.firstName }}
{{ orderAddress.lastName }}
{{ orderAddress.address1 }}
{# ...etc! #}


What is the table `templatecachequeries` for? What is the content of templatecachequeries table for in Craft 3? Especially the column query?

And is it normal to have a lot of entries (+5000) even on a smaller medium sized page?

Or it is because of badly used {{% cache %}} tag? How does it relate?

There's a great article here that goes in-depth on the {% cache %} template tag and the pros and cons of its usage I'd suggest reading:
https://nystudio107.com/blog/the-craft-cache-tag-in-depth

Template caching has pretty much remained identical to how it works in Craft 2 for Craft 3 so the article is still relevant.

Also worth linking to the official Craft docs on the subject: https://craftcms.com/docs/templating/cache


Tag relations not saving Hello kind helper folk,

I'm working with Simple Craft XML Import, which has a handful of older code in it. I've managed to get through most of it to the very end.

The last thing it does is saves tags. My tags are saved, but now it has to relate it back to the entry and Craft appears to be saving them but not relating them back correctly, and not throwing an error.

The saveRelations function appears to need:

an instance of Craft\FieldModel provided in arg 1

an instance of Craft\BaseElementModel provided in arg 2

.. the data in arg 3.

I have the following code:

                $tagFieldRecord = FieldRecord::model()->findByPk($tagFieldId);

                $tagFieldModel = FieldModel::populateModel($tagFieldRecord);

                $entryRecord = EntryRecord::model()->findById($entryRecord['elementId']);

                $entryModel = EntryModel::populateModel($entryRecord);

                craft()->relations->saveRelations($tagFieldModel, $entryModel, $tags);

Everything appears to have saved in the db tables - tags and the relations, but when I go to the entries in the back end, there are no tags.

Is there a good db value to look in on and change to get these to work?

Also, is there something in my code I can change to make this happen through the code and not hacking the db?

Please make sure the tag settings in CraftImportService.php are set properly.


How to use checkboxes to filter categories on the front end? i am trying to filter the various categories i have. Currently my url formats the following : www.site.com/news?cat=industry-news&cat=architecture-design

I understand that i have to change this to a comma separated list but how do i do that and how do i make the filtering works so it does not only shows the first selected filter only?
here is my code:

`
{% set queryCategory = craft.request.getParam('cat') ?? '' %}
{% set categoryId = craft.categories.group('news').slug(queryCategory).first().id %}

{% paginate craft.entries.section('news').relatedTo(categoryId).limit(10) as entriesOnPage %}

<form class="js-category">
{% set urlCategories = craft.request.getQueryString() %}
   {% for category in craft.categories.group('news') %}
     {{ category.title }}
   <input {{ category.slug in urlCategories ? 'checked="checked"' : '' }}   name="cat" type="checkbox" value="{{category.slug}}">

    {% endfor %}
</form>`

Here is how I did it at my end for the templating side of things:

Set the queries you need and merge them into arrays like below. Please be aware this was done for craft commerce 2 products but the same can be applied to entries too as it is the same logic.

        {% set types = craft.categories.group('flowerTypes') %}
        {% set sizes = craft.categories.group('size') %}
        {% set prices = craft.categories.group('priceRanges') %}

        {% set flowersQuery = craft.app.request.getParam('flowers') | join(',') %}
        {% set sizeQuery = craft.app.request.getParam('size') | join(',') %}
        {% set priceQuery = craft.app.request.getParam('price') | join(',') %}

        {% set relationParam = [] %}
        {% set sizeParam = [] %}
        {% set flowersValues = [] %}
        {% set collectionValues = [] %}
        {% set sizeValues = [] %}
        {% set priceValues = [] %}

        {% set relationParam = ['and',{targetElement: category}] %}

        {% if flowersQuery != '' %}

            {% for queryFlower in flowersQuery|split(',') %}
              {% set flowerCategory = craft.categories.slug(queryFlower).one() %}
              {% set relationParam = relationParam|merge([{targetElement: flowerCategory}]) %}
              {% set flowersValues = flowersValues|merge([flowerCategory.title]) %}
            {% endfor %}
        {% endif %}

        {% if sizeQuery != '' %}

            {% for querySize in sizeQuery|split(',') %}
              {% set sizeCategory = craft.categories.slug(querySize).one() %}
              {% set sizeParam = sizeParam|merge([{targetElement: sizeCategory}]) %}
              {% set sizeValues = sizeValues|merge([sizeCategory.title]) %}
            {% endfor %}
        {% endif %}

        {% if priceQuery != '' %}

            {% for queryPrice in priceQuery|split(',') %}
              {% set priceCategory = craft.categories.slug(queryPrice).one() %}
              {% set relationParam = relationParam|merge([{targetElement: priceCategory}]) %}
            {% endfor %}
        {% endif %}

## this is where we set the query to grab the relational values

        {% set products = craft.products({
            relatedTo: relationParam,
            hasVariant: {
                relatedTo: sizeParam
            }
        }).status('live') %}

Set the markup for the filters, replace with whatever you use to do the front-end stuff

All {{category.title}} Flowers

                    {% include "_partials/buttons/filter" %}
                    {% include "_partials/buttons/clear_filters" %}

                <form id="formTest" class="productFilter w-100 flex-ns flex-wrap flex-row justify-between items-start">

Filter by Price

                                <svg width="14" height="14" class="svg-blue v-mid db h-100">
                                    <use class="no-barba" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/icons.svg#arrow_down"></use>
                                </svg>

                            <fieldset class="pa0 ma0 bw0">

<input value="all-prices" class="input-reset checked-filters" type="checkbox" name="collections[]">All prices

                                {% for p in prices.all() %}

                                        <input value="{{ p.slug }}" data-value="{{p.title}}" class="absolute left-0 top-0 h-100 w-100 input-reset checked-filters ttc z-2" type="checkbox" name="price[]" {% if p.slug in priceQuery %}checked{% endif %}>{{p.title}}

                                {% endfor %}
                            </fieldset>

Filter by Size

                                <svg width="14" height="14" class="svg-blue v-mid db h-100">
                                    <use class="no-barba" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/icons.svg#arrow_down"></use>
                                </svg>

                            <fieldset class="pa0 ma0 bw0">

<input value="all-sizes" class="input-reset checked-filters" type="checkbox" name="collections[]">All sizes

                                {% for s in sizes.all() %}

                                        <input value="{{ s.slug }}" data-value="{{s.title}}" class="absolute left-0 top-0 h-100 w-100 input-reset checked-filters ttc z-2" type="checkbox" name="size[]" {% if s.slug in sizeQuery %}checked{% endif %}>{{s.title}}

                                {% endfor %}
                            </fieldset>

Filter by Flower type

                                <svg width="14" height="14" class="svg-blue v-mid db h-100">
                                    <use class="no-barba" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/icons.svg#arrow_down"></use>
                                </svg>

                                    <input value="all-types" class="absolute left-0 top-0 h-100 w-100 input-reset checked-filters ttc z-2" type="checkbox" name="flowers[]">
                                    All flowers

                                {% for t in types.all() %}

                                        <input value="{{ t.slug }}" data-value="{{t.title}}" class="absolute left-0 top-0 h-100 w-100 input-reset checked-filters ttc z-2" type="checkbox" name="flowers[]" {% if t.slug in flowersQuery %}checked{% endif %}>{{t.title}}

                                {% endfor %}

                </form>

Then with this it builds the url query for you to grab the products/entries you need from the url.

I then use a bit of js to manipulate the url to append the checked values to the url and do Ajax to get the entries:

site.getProducts = function(url) {

            const requestUrl = url;

                const productWrapper = document.getElementById('productWrapper')
                addClass(productWrapper, 'loading')

                $.ajax({
                    type: 'get',
                    url: requestUrl
                })
                  .fail(function( jqXHR, response ) {

                    const errorMsg = jqXHR.responseText

                  })
                  .done(function( response ) {

                    var parsedResponse = $.parseHTML(response);
                    var result = $(parsedResponse).find("#productWrapper .product-container"),
                        amount = $(parsedResponse).find("#filtered-area").data('product-count');

                    removeClass(productWrapper, 'loading')

                    loadedProductCount = amount;

                    if(!loadedProductCount > 0){
                        $('.product-count').parent().html('No products match your filters.');
                        $('#filtered-area').addClass('vh-100');
                    } else {
                        $('#open-filter').html('See '+loadedProductCount+' results');
                        $('#open-filter').css({
                            'borderColor': '',
                            'borderWidth': '',
                            'borderStyle': '',
                            'color': ''
                        });
                        $('#filtered-area').removeClass('vh-100');
                    }

                    $('#productWrapper').html(result);

                  });

};

site.addUrlQuery = function(event) {

        var collections = '',
            flowers = '',
            size = '',
            price = '',
            tempArray = [],
            mergedArray = [];

        var checkedFlowers, checkedSize, checkedCollections, checkedPrice;
        const node = document;
        checkedCollections = node.querySelectorAll('input[name="collections[]"]:checked');
        checkedFlowers = node.querySelectorAll('input[name="flowers[]"]:checked');
        checkedSize = node.querySelectorAll('input[name="size[]"]:checked');
        checkedPrice = node.querySelectorAll('input[name="price[]"]:checked');

        const arrCollections = Array.prototype.map.call(checkedCollections, function (e) {return e.value;}),
              arrFlowers = Array.prototype.map.call(checkedFlowers, function (e) {return e.value;}),
              arrPrice = Array.prototype.map.call(checkedPrice, function (e) {return e.value;}),
              arrSize = Array.prototype.map.call(checkedSize, function (e) {return e.value;});

        mergedArray.push(arrCollections+arrFlowers);

        tempArray.push(arrCollections);

        if(tempArray.length !== 0){
         collections+='collections='+tempArray.toString();
         tempArray = [];
        }

        tempArray.push(arrFlowers);

        if(tempArray.length !== 0){
         flowers+='flowers='+tempArray.toString();
         tempArray = [];
        }

        tempArray.push(arrPrice);

        if(tempArray.length !== 0){
         price+='price='+tempArray.toString();
         tempArray = [];
        }

        tempArray.push(arrSize);

        if(tempArray.length !== 0){
         size+='size='+tempArray.toString();
         tempArray = [];
        }

        // const url = '?'+collections+'&'+flowers,
        //    requestUrl = url;

        const url = '?'+collections+'&'+flowers+'&'+price+'&'+size,
                requestUrl = url;

        window.history.pushState('', '', url);

        if(url.indexOf('?') != -1){

            site.getProducts(url);

        }

};

var cboxArray = [];
let checkItems = '';

  function itemExistsChecker(cboxValue) {

    var len = cboxArray.length;

    if (len > 0) {
      for (var i = 0; i < len; i++) {
        if (cboxArray[i] == cboxValue) {
          return true;
        }
      }
    }

    cboxArray.push(cboxValue);

  }

  $(".checked-filters").each(function() {

    var cboxValue = $(this).data('value');
    if(window.location.href.indexOf('?') != -1){
        var cboxChecked = null;
    } else {
        var cboxChecked = localStorage.getItem(cboxValue) == 'true' ? true : false;
    }

   //On page load check if any of the checkboxes has previously been selected and mark it as "checked"
    if (cboxChecked) {

      $(this).prop('checked', true);
      itemExistsChecker(cboxValue);

    }

    // On checkbox change add/remove the value from the array based on the choice
    $(this).change(function() {

        site.addUrlQuery();

        localStorage.setItem(cboxValue, $(this).is(':checked'));

        if ($(this).is(':checked')) {

            itemExistsChecker(cboxValue);

        } else {

            // Delete the vehicle value from the array if its checkbox is unchecked
            var cboxValueIndex = cboxArray.indexOf(cboxValue);

            if (cboxValueIndex >= 0) {
              cboxArray.splice( cboxValueIndex, 1 );
            }

        }

        if(cboxArray.length > 1){
            checkItems = cboxArray.length +' filters selected'
        } else {
            checkItems = cboxArray.length +' filters selected'
        }

        $('.filtered p').html(cboxArray.join(", "));
        $('.filtered-amount').html( checkItems );

    });

  });

    if(cboxArray.length > 1){
        checkItems = cboxArray.length +' filters selected'
    } else {
        checkItems = cboxArray.length +' filters selected'
    }

    $('.filtered p').html(cboxArray.join(", "));
    $('.filtered-amount').html( checkItems );

    $('.product-count').html(loadedProductCount);

I really hope this gets you on your way here.

Any q's please mention me and ask.


How to detect the model type of an item in an array of query results When querying multiple model types (entries, Commerce products and Commerce variants) I want to be able to detect the model type of each item as I iterate over the results array.

Ideally to avoid this sort of error:

Craft\EntryModel and its behaviors do not have a method or closure named

There doesn't seem to be a clean way of doing this but I may be wrong!

Twig doesn't have a native "instanceof" check, but it'd be pretty trivial to create a simple plugin that added a Twig Extension where you can add an instanceof test.

public function getTests()
{
    return array(
        'instanceof' =>  new \Twig_Function_Method($this, 'isInstanceof')
    );
}

public function isInstanceof($var, $instance)
{
    return  $var instanceof $instance;
}

Then from your template, you'd do something like:

{% if value is instanceof('Commerce_ProductModel') %}


How to search for Entries that have a particular Category set within a Matrix field in the Control Panel? I have an arrangement like this:
Entry type 'people'
└ Matrix field 'offices'
  └ Block type 'office'
    └ Category field 'building'

On the Entries screen, how can I search for people that have a particular building Category assigned within the offices Matrix?
Note: the offices and building fields both have "Use this field’s values as search keywords" checked.

Very simple answer: you just type the category name (no matter whether it's being set within a Matrix field).
The reason this didn't work in the first place was that my search index hadn't been updated properly by the auto-running task that triggered after an XML import I did with the Feed Me plugin.
I simply had to rebuild the search indexes manually to fix the issue.


Importing content from EE with FeedMe leaves some data out I've posted an issue on the FeedMe repo, but I'm not sure whether that's the correct place for it. Also, there are quite a few issues on there with no reply for a few weeks.
The problem I'm having is I'm importing some data from an EE channel that contains a fluid field into a Craft section that has a matrix field and some of the data isn't being imported and the order of rows is wrong too. This is an example of what I'm trying to import:
<?xml version="1.0" encoding="UTF-8"?>
<entries>
  <entry>
    <count>1</count>
    <total_results>1</total_results>
    <unique>166</unique>
    <author>email@gmail.com</author>
    <title><![CDATA[Newsletter - October 2017]]></title>
    <url_title>newsletter-october-2017</url_title>
    <entry_id>166</entry_id>
    <entry_date>1506996780</entry_date>
    <status>1</status>
    <![CDATA[
October appears to be…
]]>
    <forumThread></forumThread>
    <coverImage></coverImage>
    <modularContent>
      <blockHeading><![CDATA[News 1]]></blockHeading>
      <blockContent><![CDATA[
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure rerum in tempore sit ducimus doloribus quod commodi eligendi ipsam porro non fugiat nisi eaque delectus harum aspernatur recusandae incidunt quasi.
]]></blockContent>
      <blockHeading><![CDATA[News 2]]></blockHeading>
      <blockContent><![CDATA[
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure rerum in tempore sit ducimus doloribus quod commodi eligendi ipsam porro non fugiat nisi eaque delectus harum aspernatur recusandae incidunt quasi.
]]></blockContent>
      <blockHeading><![CDATA[Modding News]]></blockHeading>
      <blockImage>https://www.domain.com/images/content/news/image1.jpg</blockImage>
      <blockContent><![CDATA[
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure rerum in tempore sit ducimus doloribus quod commodi eligendi ipsam porro non fugiat nisi eaque delectus harum aspernatur recusandae incidunt quasi.
]]></blockContent>
      <blockHeading><![CDATA[News 3]]></blockHeading>
      <blockContent><![CDATA[
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure rerum in tempore sit ducimus doloribus quod commodi eligendi ipsam porro non fugiat nisi eaque delectus harum aspernatur recusandae incidunt quasi.
]]></blockContent>
      <blockImage>https://www.domain.com/images/content/news/image2.jpg</blockImage>
      <blockContent><![CDATA[
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure rerum in tempore sit ducimus doloribus quod commodi eligendi ipsam porro non fugiat nisi eaque delectus harum aspernatur recusandae incidunt quasi.
]]></blockContent>
    </modularContent>
  </entry>
</entries>

With the above, the matrix field is being populated with all of the images first, then all of the text content, and none of the headings.
I'm pretty sure all the mapping is correct. The heading block shows up and I've assigned it to blockHeading.
I'm also getting the following error relating to the date:

News: Date parse error: 1506996780 - Could not parse '1506996780': DateTime::__construct(): Failed to parse time string (1506996780) at position 8 (8): Unexpected character.

In EE, that's being output by <entry_date>{entry_date}</entry_date> which is the same as a feed template I did for another channel that imports in Craft with no errors.

So the answer was that each of my blocks needed to be wrapped by another element, e.g.
<modularContent>
  <block><blockHeading><![CDATA[News 1]]></blockHeading></block>
  <block><blockContent><![CDATA[
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure rerum in tempore sit ducimus doloribus quod commodi eligendi ipsam porro non fugiat nisi eaque delectus harum aspernatur recusandae incidunt quasi.
]]></blockContent></block>
</modularContent>


Controller redirect not working in craft 3 I am working with Craft 3 and in my controller, I am trying to do this
$this->redirect('https://foobar.test');
But it is throwing me back to the root url of my craft site. I am confused, what else do I need to do?

Forgot to add the return keyword :(
return $this->redirect('https://foobar.test');


How can I handle the identical SEOmatic config for multi-sites? I'm using the amazing SEOmatic plugin in a multi-site config in craft 3.

I have a total of 18 sites and they share a lot of identical data. So I was wondering if it was possible to export the configuration I made for the main site and import it to the others.

Is there a way to avoid configuring 18x the same thing? It will save me a bunch of time.

Thanks !

So check out this issue for ways I'm thinking about tackling this problem; any input from you would be welcome: https://github.com/nystudio107/craft-seomatic/issues/227


What is causing Craft CP assets(JS/CSS) to appear in front-end pages? Perhaps in some way related to this, I've got a couple of front-end pages on our website that pull in the following files, which seem to all be CP files. These two pages each utilize plugins I've written, each one a different plugin, so there must be something I'm doing in my plugins that calls this stuff in. Any hints?

selectize.css
craft.css
charts.css
axios.min.js
d3.js
element-resize-detector.js
jquery.js
jquery.mobile-events.min.js
velocity.js
garnish.js
jquery-ui.min.js
jquery.payment.js
picturefill.js
selectize.js
jquery.fileupload.js
xregexp-all.js
fabric.js
Craft.min.js

EDIT: Here is the relevant asset-bundle:

class LivestreamAsset extends AssetBundle
{
    // Public Methods
    // =========================================================================

    /**
     * Initializes the bundle.
     */
    public function init()
    {
        // define the path that your publishable resources live
        $this->sourcePath = "@kr37/livestream/assetbundles/livestream/dist";

        // define the dependencies
        $this->depends = [
            CpAsset::class,
        ];

        // define the relative path to CSS/JS files that should be registered with the page
        // when this asset bundle is registered
        $this->js = [
            'js/Livestream.js',
        ];

        $this->css = [
            'css/Livestream.css',
        ];

        parent::init();
    }
}

those CP files are included by CpAsset asset bundle.

if your plugin asset bundle depends on CpAsset:

class YourPluginAsset extends AssetBundle
{
    public function init()
    {
        $this->sourcePath = __DIR__ . '/dist';
        $this->depends = [
         CpAsset::class,
        ]
     //....
    }
}

and if you register your plugin asset in frontend or backend template:

{% do view.registerAssetBundle("ns\\prefix\\YourPluginAsset") %}

or via controller:

 $this->view->registerAssetBundle(YourPluginAsset::class);

those file are added to that page automatically.


Single entry with 450 Matrix blocks throwing error on save A client has a Singles entry with a Matrix block defined that contains a few text fields, and one image field. They've created approximately 450 instances of this Matrix block, and can no longer update the page. Craft throws a 500 error. Craft logs just show a basic

exception 'Craft\HttpException' in /srv/[clientName]/releases/20170418025256/craft/app/controllers/TemplatesController.php:59

and nothing of use in the Apache error logs. Anyone have experience with this sort of error, or confidence that this would be a Craft bug?

Most likely you're bumping into php.ini limitations.  I'd bump the values of memory_limit, post_max_size and max_input_vars and see if that helps.

They are common culprits when POSTing large amounts of data (which is what 450 Matrix Blocks would be considered).


User registration: How do implement "Confirm password" and "Confirm email"? I've got a user registration form on my site, using the code from Craft's documentation. How can I get the form working so it asks the user to enter their email address and password twice? Can Craft take care of that or do I need to use client-side JS validation?

If anyone is interested in confirming passwords still, I have wrote a plugin which does just this, it doesn't rely on it's own controller either so there is no bypassing of Crafts own workings :)

https://github.com/alecritson/Craft-Password-Confirm

All you need to do is add a passwordConfirm field to your existing form:

<input type="password" name="passwordConfirm">
{% if account is defined %}
  {{ account.getErrors('passwordConfirm') }}
{% endif %}

It doesn't confirm emails though..sorry


Autologin destination A bit of an extension of my previous query at Auto-login on account activation

I want to a user to:

automatically login on account activation, and
be redirected to a predetermined page on account activation.

Thanks to @steverowling managed to do the former using his autologin plugin(1). However struggling with the latter. I can't see how to specify the redirect location and on activation/login the user is always redirected to the site homepage.

Any thoughts on how to specify a redirect destination in conjunction with the above functionality?

Cole

Okay - got to the bottom of this.
Was using the wrong setting. Should have been setPasswordSuccessPath not setPasswordSuccess!


Conditional to override a block I apologize in advance if I am just overthinking this and missing something obvious (feels like I am). I have a situation on a category page where I am wanting to override a block in the document this one is extending, but only if the category is equal to a specific value ('Smith' in this case). If I put the conditional outside the block definition, I keep getting an internal server error. But if I put it inside the block definition, then it will override the block on every category page, not just this one. I'm trying to avoid having multiple templates and instead just hide one nav section on one category page. Please let me know if you need any more information. Thanks in advance for any advice!!

Here are the two versions of the code that I have tried. First gives the Internal Server error, second overrides the block for all pages.

{% if category.title == 'Smith' %}
  {% block nav %} {% endblock %}
{% endif %}

{% block nav %}
  {% if category.title == 'Smith' %} {% endif %}
{% endblock %}

No super easy way around this one, I don't think. You might consider if using blocks is the most appropriate method in this case, or if a simple conditional in the extended template would do the trick:

_layout.html

<nav>
    {% if category is not defined or category.title != 'Smith'%}
       {# Your navigation code here #}
        ...
    {% endif %}
</nav>

If you want/need to use a block, I think your best option is to put the contents of the extended template's nav block (i.e. the default content for the nav block) in a partial template (e.g. _partials/nav.html), and include it like this in the layout and category templates, respectively:

_layout.html

{% block nav %}
    {% include '_partials/nav' %}
{% endblock %}

category.html

{% block nav %}
    {% if category.title != 'Smith' %}
        {% include '_partial/nav' %}
    {% endif %}
{% endblock %}

Yes, its one more template, but it's the most DRY solution I can think of.


FeedMe - Import to multi language sites, linking entries How does one use FeedMe to import content to a multi language setup? I can have one feed with all languages, or a feed for each language, but I cannot see how to set the locale of the import content, nor then how to link them as tranlsations of the same entry.

The documentation here does not seem to include info about it:
https://docs.craftcms.com/feed-me/v4/

There is a small paragraph about Target Site, but I do not have that option on my multi-site install, and it does not detail how to link entries together.

Thanks

You will need to:

Set Entries to propagate across all sites for you chosen section
Import your main language (which will propagate to all your sites)
Using ID's (or else) to match elements, import second language to update previously propagated entries and correct content.

Here's an article explaining the process.


{{ entry.image.first().url }} won't show image I am on my first Craft CMS test site. Have some problems showing a simple image.
<img src="{{ entry.hero.first().url }}" title="{{ hero.title }}">

I get the title but can't get the URL. The src attr is always empty. Tried a couple of variants like:

entry.hero.first().url()
entry.hero.first().getUrl()
with and without ()
etc.

But entry.hero.first().filename gives me "my_testfile01.jpg"
I can't see what is wrong.
File is local with path set to "./"
Image field has no sub path.
MAMP (Apache + PHP 7)

By the way, is your Craft CMS version 3.x? If so, using "one" is recommended instead of "first", which is deprecated.


How can I show a list of product options as checkboxes in the cart? In my cart (Craft3/Commerce2), I need to show a line item's possible options from a checkbox field called "productOptions", and allow the user to select the desired options.

Based on the Craft Docs, I can manually test if an item.options exists, but this means hard-coding the list of possible options(35+) into the cart, and keeping that updated as available options change:

<form method="POST">
    <input type="hidden" name="action" value="commerce/cart/update-line-item">
    {{ redirectInput('cart') }}
    {{ csrfInput() }}
    <input type="hidden" name="lineItemId" value="{{ item.id }}">
    <span {% if item.getFirstError('qty') %}class="has-error"{% endif %}>
    <input type="number" name="qty" min="1" value="{{ item.qty }}"></span>

{#  Manual List of Options to Test if Exists #}
    {% if item.options.optionOne is defined %}
        <label class="checkbox">
            <input type="checkbox" name="options[optionOne]" checked> Option One
        </label>
    {% endif %}
    {% if item.options.optionTwo is defined %}
        <label class="checkbox">
            <input type="checkbox" name="options[optionTwo]" checked> Option Two
        </label>
    {% endif %}
            ...

OR, I can output the list of product options available for a given product, and use that to update the cart:

{#  To access the product options, set a variable "product" #}
    {% set product = item.purchasable.product %}
    {% for key, value in product.productOptions %}

        <label class="checkbox">
{#          <input type="hidden" name="options[{{ value }}]" value=""> #}<!-- uncheck it if not checked -->
            <input type="checkbox"  name="options[{{ value }}]" value="on"
            {% if item.options.value is defined %}checked{% endif %}> {{ value }}
        </label>

    {% endfor %}

    <input type="submit" class="button" value="Update"/>
</form>

But I can't seem to figure out how to test if the checkbox is selected/value =="on" from the cart array. I know that
{% if item.options.value is defined %}checked{% endif %}
is not the correct way to access this value if it even can be accessed in this for loop.

Help? Many thanks in advance!

{% if item.options.value is defined and item.options.value == 'on' %}


Minor math in template, display result before logic in DOM Currently I’m looping through some results on an athlete’s bio page to get their individual win/loss record… Something like {% if matchWon is defined %}{% set wins = wins + 1 %}{% endif %} is looping in a table of their records. This works great, and will accumulate their record just fine, but what if I want to show the athlete’s record *before* the table where all that logic is run? Any way to display those final win/loss values out earlier in the dom?

Just do a {% set myEntries = craft.entries.whatever.find() %} to load the entries into an array. Then do two loops, the first to get whatever totals you want, the second to display the players stats.

Yes, you're doing two loops. But you're only hitting the database once to load into the array, which is where the performance bottleneck will be unless there are a ton of entries.

In any event, wrap it all in a cache tag.


How can I get blog categories and blog entry urls to play nice together? I'm building a simple blog that has the ability to publish entries:

Within a set of categories.
With no category set.

The URL format of a blog entry is /blog/YYYY/MM/DD/{slug}

Everything so far works, my section blog works and the templates/blog/index.html template loads correctly as does the templates/blog/_entry.html for blog entries.

Categories however don't seem to work as they seem to be conflicting with the entry URLs… I have a list of all blog categories at the top of the blog section with each section, eg: 'Recipes', linking to /blog/recipes (using the {category.url} var).

In Craft I have set the Blog categories settings set to:

Category URL Format: blog/{slug}
Nested Categories: not set/empty
Category Template: _category.html (I have also tried _category without the .html extension as the value with the same result)

The issue is that when I navigate to blog/recipes I get a 404 instead of the system serving the templates/blog/_category.html template I have set up.

Note: There are no custom routes setup for this site.

I'm not sure what I am doing wrong, single entries serve up fine, but I can't seem to get to the category listing of a blog's category.

Any help would be much appreciated.

I think the problem here could be to do with the path to your Category Template.

Make sure that in your category settings, the path to your Category Template file includes the folder it is nested within.

So instead of _category.html, you should put blog/_category.html (if that file is inside the Blog template folder)

There is also some docs on the Craft site that tells you how to template this file if you haven't seen it already.


How to display number of entries for a tag and not display if no entries? I want to be able to display the number of entries that have a tag. Like:

Fruit (9)
Vegetables (4)

I also want to avoid displaying any tags without any related entries.

My code right now looks like this:

{% extends "_layout" %}
{% set title = "Tags" %}
{% block content %}
{% for tag in craft.tags.order('title') %}

}{{ tag.title }}

{% endfor %}
{% endblock %}

Something like this should work:

{% set tags = craft.tags.limit(null).relatedTo(craft.entries.limit(null)).order('title') %}

{% for tag in tags %}
    {{ tag.title }} (craft.entries.relatedTo(tag).total())
{% endfor %}

Note that if you have a significant amount of tags, the above could be a costly affair, performance wise – consider alternative approaches.


Commerce 1 with Apple Pay, is it possible? We are using Stripe on our website. Craft CMS 2.6.2997 and Commerce 1.2.1351. Can we use the apple pay function?

I read the Stripe document(https://stripe.com/docs/stripe-js/elements/payment-request-button#html-js-testing-chrome). It seems possible to do that. But, I am not sure is it work on Commerce 2...

Anyone know?

Thanks!

Quick answer.

Yes you can use Apple Pay with Craft Commerce and the first-party Stripe Gateway Plugin.

In order to do that, you need to customise your template and add the functionality for the Payment Request button. What this does is more or less generating a charge promise token for Stripe (same way it does for card).

Charging the token is then handled by the gateway itself as you would with a card charge.

You can choose to display the button by checking if a relevant Payment API is supported with paymentRequest.canMakePayment() method.

I hope this helps in terms of a high overview.

[EDIT]

The above answer was for use with Craft Commerce 2, as originally set by the question.

Requirement changed to Commerce 1.

The quick answer is still yes.
We have completed a similar task before (with Stripe Elements and Stripe Sources), though that's before SCA.
But Elements are SCA ready as far as I know and you need to use the PaymentIntents API PaymentMethods API.

Difference is that the main Stripe Gateway for commerce 1 (by omnipay) doesn't seem to support webhooks from Stripe, which informs your system whether a token (Source at the time) can be charged or not.

Hence, you need to build kind of your own plugin that loads an extra stripe gateway either new or extending the existing Stripe gateway class (extending is easier as you don't need to rebuild everything).
Might need to add a custom Payment Form to your plugin.

You still need to build a custom template.
The template should use Stripe elements.
Logic is same, chargeable promise token which you need to charge.
Request for charging
Await webhook that notifies your system if your intent can be charged
And then continue with charging if available, otherwise inform user for any errors.

That's still a high overview of how the process works.
You would need to use Payment Intents API and Payment Methods API

[/EDIT]


Is there a user stats plugin available? I am looking for a plugin or simple method that can add some stats to the User Admin. We have a membership site running for a client and it would be good to add either a count to the sidebar User Groups filters (eg "Users (11)") or a dashboard widget of basic stats.

Has anyone added this already, or used something suitable?

Until the plugin store officially becomes a thing, Straight up Craft has got the most curated list of plugins available for Craft at the moment.

I'm not seeing anything like you're describing for users, but it is definitely something a plugin should be able to handle.


Upload any size image into carousel I wanted to create a php which allow admin to upload their pictures in any resolution and image file type, but it has to display into a bootstrap carousel with fixed size.
Does anyone has the similar script I can have a look?

It might needed to do the following;
Upload image into a specific location, convert image type into jpg, specific resolution, and be able to read by bootstrap carousel. My head is about to broke thinking of this script :(

You shouldn't need to create a custom plugin to do that.

You can easily create a Matrix content field for your carousel. Create a new block called slide. From there you can create an asset field to upload the slide image.

You can render this into whatever markup you'd like (even bootstrap).

As for cropping an image and converting it into a jpg, check out Aviary Image Editor. It's a wysiwyg editor in the admin panel for doing exactly what you are looking for.


Store Hours Plugin - Output Details Anyone using the "Store Hours" plugin know how to print out day open and close hours details?

I have tried this but not outputting anything.

{% for openTime in entry.openTimes %}
    {{openTime.day.open}}<br>
{% endfor %}

Note: openTimes is a field of StoreHours type.

Any help will be appreciated.

Following from Lindsey D's answer, I just wanted to point out you can skip manually mapping the weekday names by calling craft.i18n.getLocaleData().getWeekDayName() like so:

{% set day = craft.i18n.getLocaleData().getWeekDayName(dayIndex) %}

It's also worth mentioning, you can check for empty values to indicate the store is closed.

E.g.,

{% for dayIndex,dayHours in companyInfo.storeHours %}

  {% set day = craft.i18n.getLocaleData().getWeekDayName(dayIndex) %}

  {{day}}: {{ (dayHours.open is empty) ? 'CLOSED' : dayHours.open|date('g:i a') ~ '-' ~ dayHours.close|date('g:i a') }}

  <br>

{% endfor %}


Does Craft / Twig support regex groups? I see Craft does support regex in replace search. But there is no info on using regex groups, ie string | replace('/this is a (string)/', 'This is another $1').

Is this feature implemented? If so - how?

Yes.

{{ 'this is a string'|replace('/this is a (string)/', 'This is another $1') }}

will output

This is another string

When you pass something that looks like a regex into the |replace filter,  preg_replace() is called behind the scenes, so |replace can do anything preg_replace() can do.


Fetching a Localized Global as a Static Translation Causes Error in How Plugins Load I've extended all my "translations/[locale_id].php" to refer to this  function which enables us to put all our translations under a global in the control-panel.

However, when this is done – we lose data attached to our assets. We currently use a Focal Point plugin attached to our assets. It describes with a field how images are to be cropped. This particular plugin stops working when the line highlighted below is executed.

function get_dynamic_translations() {
    $translations = array();

    if (!craft()->request->isCpRequest()) {
        // the following line makes the plugin "FocalPointField" stop loading its data
        $i18n = craft()->globals->getSetByHandle('i18n');

        foreach ($i18n->getFieldValue('translations') as $current_block) {
            $translations[$current_block->content->key] = $current_block->content->value;
        }
    }

    return $translations;

}

I would love for these two solutions to work together in perfect harmony – but I can't seem to figure out why this is not working.

Do you have any idea how I can go forth?

This line:

$current_criteria->fieldId = craft()->fields->getFieldByHandle('translations');

should probably have a ->id at the end?

$current_criteria->fieldId = craft()->fields->getFieldByHandle('translations')->id;

But the whole code could probably be replaced with:

function get_dynamic_translations() {
    $translations = array();

    if (!craft()->request->isCpRequest()) {

        $i18n = craft()->globals->getSetByHandle('i18n');

        foreach ($i18n->getFieldValue('translations') as $current_block) {
            $translations[$current_block->content->key] = $current_block->content->value;
        }
    }

    return $translations;
}


Is Matrix > Entries > Matrix possible? I have a matrix field with an entries field which ties into another matrix field. Is this possible? Here's what I have so far...

{% for block in entry.contentMatrix %}

  {# Tabs Block Type #}
  {% if block.type == "tabs" %}
    {% set entries = craft.entries.relatedTo(block.tabEntry) %}

    {% for entry in entries %}
      {# Matrix Content #}
      {% for block in entry.tabsMatrix.type('videoChannel, videoPlayer, copy') %}
        {{ block.title }}
      {% endfor %}
    {% endfor %}
  {% endif %}

{% endfor %}

This does not produce an error, just nothing.

Do you need to filter by block type?

Maybe something like this:

{% for block in entry.contentMatrix %}

    {# Tabs Block Type #}
    {% if block.type == "tabs" %}

        {% set entries = craft.entries.relatedTo(block.tabEntry) %}

        {% for entry in entries %}
            {# Matrix Content #}
            {% for content in entry.tabsMatrix.type('videoChannel, videoPlayer, copy') %}

                {% if content.type == "videoChannel" %}
                    {{ content.title }}
                {% elseif content.type == "videoPlayer" %}
                    {{ content.url }}
                {% else %}
                    {{ content.text }}
                {% endif %}

            {% endfor %}

        {% endfor %}

    {% endif %}

{% endfor %}

Note: Matrix Content vars (*.title, *url, *text) are just examples.


What are best practices for using Matrix fields to establish a grid layout I am using a Matrix field for content blocks like heading, text, images, ... similar to the HappyLager demo site. Now I would like to combine this with common CSS grid systems (e.g. from Bootstrap, Foundation, ...).

Typically they need to wrap rows in a
 and columns in e.g. a
. The easiest way would be to provide dummy matrix blocks for opening rows and columns (with a radio-button field to specify column with) and blocks for their corresponding closing tags. But of course the user should not forget to close the blocks otherwise the layout breaks. Is there a better way to do this?

Easiest way I can think of is just to use some math. If your grid columns need to add to 12, keep a current column count while iterating over the matrix blocks.

I'd imagine you'd want your content blocks have some sort of built-in "column" width to begin with... a text content block might be 8 columns and an image would be 4. Or 6 and 6.

If the current block + the previous block adds to over 12, close the current row and start a new row.  Practically speaking, the actual column count doesn't really matter to a user, it's creating a specific layout... whether that's 8 + 4 or 6 + 6, etc. The grid is kind of a formality, really, to keep everything sane.

You'd probably have to look ahead and see what the next block or 2 look like to get an idea of your column count or to adjust it to make sure the user isn't putting in 2 images or 2 half blocks, for example. If they are, then the image could automatically start its own row or something. If you're feeling ambitious, the last one in the row could take up more or less space, depending on how you want the layout to look.  IIRC I think that's how the Happy Lager site does it, if you put two images next to each other, they adjust a bit.

I've experimented a bit with this as well. If you're trying to save the user from himself, it's pretty rare you want to have an arbitrary sized text block... like 2 columns or whatever. I can see where you might want to have a pull quote or something that might take up that size, so define that instead.


Live Preview XMLHttpRequest error When I watch my site trough live preview the previewframe is left blank, and in the console there appears the error: `

  XMLHttpRequest cannot load http://domain.com/template . No
  'Access-Control-Allow-Origin' header is present on the requested
  resource. Origin 'http://www.domain.com' is therefore not allowed
  access.

What is that?

Instead of allowing cross site access, I'd recommend that you instead just make sure that the site is only accessible through one domain (not both www.domain.com and domain.com). This will also improve your SEO ranking, since search engines will index both these domains as separate, duplicated content. You can rewrite the domain in your .htaccess, like this:

# Remove the www from the URL
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

# Force the www
# RewriteCond %{HTTP_HOST} !^www\.
# RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]

Notice that only one of these rules should be used, if you enable both you'll get a redirection loop.

Also, make sure you use the correct domain in your Craft config.


Reordering entries tied to categories? We have a client that has a good deal of products in one channel. We're categorizing each product entry with a pretty extensive category tree. The reason we didn't go with a structure is because many products needed to exist in multiple categories and a structure tree would get messy.

Everything is working great, but they now want to be able to re-order entries by category in the CP and we're sort of stuck. The new Category Sources plugin sort of gets us half way there but it doesn't allow you to reorder and save the order in any way.

Anyone run into this sort of issue? Thanks.

If you reverse the relationship then you should be able to order the entries (i.e. add products to an entries field within the category, instead of adding categories to a categories field within the product).

So instead of grabbing the products using relatedTo(category),

{% set products = craft.entries.section('products').relatedTo(category) %}
{% for product in products %}...{% endfor %}

you would be able to grab the products directly from the products entries field in the category using category.productsFieldHandle, which should be returned in the order defined in the CP.

{% set products = category.productsEntriesFieldHandle %}
{% for product in products %}...{% endfor %}


Categories or Structures: Most efficient way to organize FAQ sections Working on a plan for a site that has multiple audiences, with a FAQ section for each audience.

FAQ entries are organized by Topic (Finance, Advertising, Publicity)

each FAQ entry can be associated with multiple topics

FAQS and Topics are also organized by audience: (trainee, associate, lead)

a given FAQ entry or an entire Topic full of entries can be associated with multiple Audiences

It would be nice to be able to order the entries in each topic, but not a must have.

The three separate FAQ pages would have content that maps out like this, as an example:

Trainee Audience page

Advertising
     Ad Entry 1
     Ad Entry 2
Finance
     Fin Entry 1
Publicity
     Pub Entry 1

Associate Audience page

Advertising
     Ad Entry 2
     Ad Entry 3
Publicity
     Pub Entry 2

Lead Audience page

Advertising
     Ad Entry 1
     Ad Entry 2
     Ad Entry 3
Finance
     Fin Entry 1
     Fin Entry 2
     Fin Entry 3

I know that this can be accomplished in various ways using categories, structures, and related entries, but I'm aiming for efficiency, then ease of editing for the users.

I've tentatively landed on this:
One main Structure, with Topic and FAQ entry types. Both entry types have a Category field to select audience

but not sure if I'm missing a better option for performance/ease of use.  Any advice is appreciated!

If your clients wants to have control about the order of the entries for each audience,  e.g.

 Trainee
 Advertising
    Ad Entry 2
    Ad Entry 3

 Associate
 Advertising
    Ad Entry 3
    Ad Entry 1
    Ad Entry 2

a good solution might be a entries field. The ability to simply drag and drop entries to change the order is the most intuitive option from my experience. If you have many entries you could combine both logics - e.g. render first all elements that you selected with the entries field and after that add the missing ones according to your categories / structure.


How to keep staging install synced with member registration What is the best way to keep live and staging environments synced with member registrations?
I can export/import the database from the live to staging environment to keep it in sync - and have a content freeze on the live version during development on the staging version.
But the live website will continue to allow new member accounts to be created, meaning the staging environment will be out of sync.

You should have a look into project config if you haven't already.
It allows you to sync just the structural changes of your development, staging and live sites, without affecting the content/users.
This way you can still sync your production database to staging, but then you can just sync the structural changes back to production – no freezing necessary.


Do Freeform Events Fire From Control Panel? It appears to me that Freeform Submission events do not fire when editing events in the control panel. They certainly fire from a front-end submission.

That would make this statement in the documentation untrue. Emphasis added.

  Hook into Submission events to attach your own logic for when
  submissions are being created, edited or deleted. [1]

Can someone smarter than me confirm or deny this, please?

"Submissions" is referring to the submission  of a front end form. Not the Control Panel.


Point a plugin into to a local file This should have been easy. But, I am dorking something up.

I am trying to point FeedMe to a local file.

In Finder, the file is located under /Users/shellyar/Desktop.  I also tried `file:////Users/shellyar/Desktop'.  Neither worked.

This is fixed in 3.0.0-beta.10. Additionally you can use the concept of aliases in your URL for all sorts of variables:

@web/assets/data/clients.xml

Which would be related to your web root.


Matrix max block type limit Currently it's possible to set a max block value for the collection of block types. However I have a case where it would be great if I could set block type limit.

For example I have a situation where I need a carousel matrix. A block type with assests for the carousel but also a heading and text block type describing the carousel. I want the assets block type to have x amount of repeatable entries but the description and title block type limited to 1.

How would you currently achieve this? Would it be worth requesting adding it to the roadmap?

I just published a plugin called Limit Block Type, which adds the ability to limit Matrix blocks per block type.

There's also a feature request for adding this feature to core.


JS templating in Craft CP I'm writing a plugin where I need to render some semi-complex HTML clientside at runtime (all inside the CP).

Does Garnish (or any other library/framework/JS-thingamabob shipped with Craft) offer any built-in JS templating functionality a'la Handlebars or Underscore?

The only JS library that ships with Craft (besides the Craft-specific Garnish) is jQuery. Of course, jQuery is a helpful JS library, but by no means a full-fledged framework. Fortunately, adding a separate JS library is painfully easy!

How to CDN from a Twig template...

{% includeJsFile '//full/path/to/cdn.js' %}

How to CDN from PHP...

craft()->templates->includeJsFile('//full/path/to/cdn.js');

When you use includeJsFile, it wraps your path in a standard <script> tag... It doesn't matter where the file is, as long as the path is valid.

Keep in mind, a PHP call will take effect in both the back-end and front-end of your site. So to keep the file loaded only in your CP, make sure to wrap a conditional around it:

if (craft()->request->isCpRequest()) {
    craft()->templates->includeJsFile('//full/path/to/cdn.js');
}

Don't want to CDN? No problem! The best place to store local JS files would be in a resources folder:

/craft
  /plugins
    /myplugin
      /resources
        /js
          /handlebars.min.js

In that case, you can use includeJsResource instead of includeJsFile.


Search Form with Craft Commerce I am using the following form in Craft

    <form class="parts-search-block" action="{{ url('parts/results') }}" method="get">

        {#-- CATEGORY SEARCH --#}

            Search by Category:

            <select name="q">
                <option value="">--Select A Category--</option>
                <option value="Compressors">Compressors</option>
                <option value="Coolers">Coolers</option>
                <option value="Doors">Doors</option>
                <option value="Electrical">Electrical</option>
                <option value="Freezers">Freezers</option>
                <option value="Gaskets">Gaskets</option>
                <option value="GFV">GFV</option>
                <option value="Glass">Glass</option>
                <option value="Graphics">Graphics</option>
                <option value="Grills">Grills</option>
                <option value="Harnesses">Harnesses</option>
                <option value="Lighting">Lighting</option>
                <option value="Misc">Misc</option>
                <option value="Motors">Motors</option>
                <option value="Plastic">Plastic</option>
                <option value="Refrigeration">Refrigeration</option>
                <option value="Repair Panels">Repair Panels</option>
                <option value="Shelves">Shelves</option>
                <option value="Skins">Skins</option>
                <option value="Vendor">Vendor</option>
            </select>

        {#-- CATEGORY SEARCH --#}

            <button type="submit" class="cat-search">
                Begin Search
            </button>

    </form>

And calling it on the results page with...

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

    {% for entry in entries %}

I am now using Craft Commerce and need to use the form to search my Commerce Products.  Is this possible?  Any suggestions?

The Simplest Answer

{% set products = craft.commerce.products.search(query).order('score') %}

However, I am not sure a search is guaranteed to return ALL the products in quite the same way as using relatedTo, which is how you'd typically get entries/products related to a category - so see below.

A Slightly Fuller Answer

(Using your form)

So in this case I think you're just wanting to get all products related to a category?  As in, you're not actually searching within those right?

If so you can leave out the search parameter below, as all you're doing is finding the products related to the category.

(If you want to search within those products for something else, then you need the search: "some value" part).

Anyway, q has your category (title?) in it (would be better to use the slug in your form values really), so you can just:

{% set categoryTitle= craft.request.getParam('q') %}
{% set category = craft.categories.title(categoryTitle) %}  {# (or better change form values and this to .slug) #}
{% set products = craft.commerce.products({
                relatedTo: category,
                search: "whatever",
                order: "title asc",
            }) %}
{% for product in products %}
    etc...

(Obviously a more typical way of doing this is to do it off a url segment or whatever for an index page, rather than by a search)

A Considerably Fuller Answer

Absolutely you can search products in the same way.  Even better, since about Craft 2.5 when they added the serachScore to the results, you can simultaneously search multiple element types and combine the results.

Here's some sample code that will get you started:

    {% if query|length %}

    {% set product_results = craft.commerce.products.search(query).order('score').limit(limit_for_each_section).with('variants') %}
    {% set article_results = craft.entries.search(query).order('score').limit(limit_for_each_section) %}
    {% set category_results = craft.categories.search(query).order('score').limit(limit_for_each_section) %}

    {% set all_results = [] %}

    {% if product_results|length %}
        {% set all_results = all_results|merge(product_results) %}
    {% endif %}
    {% if article_results|length %}
        {% set all_results = all_results|merge(article_results) %}
    {% endif %}
    {% if category_results|length %}
        {% set all_results = all_results|merge(category_results) %}
    {% endif %}

    {% if all_results|length %}

        {% set all_results = all_results|sortByField('searchScore', 'desc') %}

        {% set items = [] %}

            {% for result in all_results %}

            {% if result.url|length %}

                {% if result.elementType == 'Commerce_Product' %}

                     ... etc


how to access to event object propereties I want to access for particular information which is contained in event object.

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

    craft()->on('entries.saveEntry', function(Event $event)
    {

        var_dump($event->params['entry']);
    });
}

it dumps info (brining a needed part)

     ......
["_preppedContent":"Craft\BaseElementModel":private]=>
  array(1) {
    ["tweet"]=>
    array(23) {
      ["created_at"]=>
      string(30) "Thu Nov 13 09:15:40 +0000 2014"
      ["id"]=>
      float(5.3282410346476E+17)
      ["id_str"]=>
      string(18) "532824103464763392"
      ["text"]=>
      string(115) "'The innovation insight you didn't get from Forbes' great blog by @LydiaRagoonanan @nesta_uk http://t.co/PImPVvWeAv"
      ["source"]=>
      string(63) "Hootsuite"
      ["truncated"]=>
      bool(false)

How can I extract text, id_str information?
Thanks

I assume both text and id_str are custom fields?

$event->params['entry']

Is an EntryModel, so you should be able to do this:

$entry = $event->params['entry'];
$idString = $entry->id_str;
$text = $entry->text;


How do I install the FormBuilder 2 plugin in my local Craft project? I tried cloning https://github.com/roundhouse/FormBuilder-2-Craft-CMS to my plugins folder of my local Craft project and opened the plugins module from admin settings but the formbuilder2 plugin did not show in the list. Can you please help me if somebody has used this plugin for their Craft CMS project? Thank you.

I rolled old-school and just downloaded the zip file to my local machine.
When I did that & unzipped the directory the folder is called FormBuilder-2-Craft-CMS-master

You will want to rename that to formbuilder2, copy/paste that folder to /craft/plugins/ and then it should show up in your list of plugins when you navigate to settings->plugins.

Hope this helps!


Can I define a path to my 404 template? Wanting to move static/single templates in to a directory pages and thus, the path to my 404 template is now pages/404.html. I don't necessarily need dynamic content as asked here. Is there a config setting I can use to point the default 404 URI behavior to that template?

Yes, use errorTemplatePrefix.

'errorTemplatePrefix' => "pages/",


Searching Number Field To See If It Falls In A Range I'm building a property search form and searching by different types of fields in Craft.

Here are my questions:

How can I get a list of the unique cities in the entries section to declare my form options?
I'm stuck on searching by square feet.  (see # sf # section in my code) My plan is to let the user select from a few different ranges of square footage. What I was trying to accomplish below is if my search parameter is "sf=1", the field buildingSQFT is searched for numbers in between 10000 and 20000. I would then set up different ranges based on the parameter.

I'm not sure if this is a good way to do this.  Your input has to how to best accomplish this is appreciated.

{% if not craft.request.isAjax %}
{# set base params #}

{% set params = {
    section: 'propertiesSection',
    limit: null
} %}

{% set relatedParams = ['and'] %}

{# status #}
    {% if craft.request.getParam('status') %}
        {% set status = craft.categories.group('propertyStatus').slug(craft.request.getParam('status')) %}
        {% set relatedParams = relatedParams|merge([{ targetElement:status }]) %}
    {% endif %}

{# city #}
    {% set city = craft.request.getParam('city') %}
    {% if city %}
        {% set params = params|merge({'city':city}) %}
    {% endif %}

{# sf #}
    {% set sf = craft.request.getParam('sf') %}
    {% if sf == "1" %}
        {% set params = params|merge({'buildingSQFT':range(10000,20000)}) %}
    {% endif %}

    {# add relatedParams to params #}
    {% if relatedParams|length > 1 %}
        {% set params = params|merge({'relatedTo':relatedParams}) %}
    {% endif %}

    {% set entries = craft.entries(params).search() %}

    {% if entries|length %}

Remember: all parameters in your Query are set to null by default. They won't be parsed into an SQL statement until they have a valid value (not "", not NULL not 0) so you can just pass null values.

{% set range = null %}
{% switch craft.request.getParam('sf') %}
    {% case '1' %}
        {% range = ['and', '>=10000', '<=20000'] %}
    {% case '2' %}
        {% range = ['and', '>=20000', '<=30000'] %}
{% endswitch %}

{% set query = craft.entries
    .city(craft.request.getParam('city')) // <-- if city is null, nothing happens
    .buildingSQFT(range)
    .section('propertiesSection')
%}

Keep in mind query is currently only a Query and not an array of entries. You can still attach your parameters

{% if craft.request.getParam('status') %}
    {% set status = craft.categories.group('propertyStatus').slug(craft.request.getParam('status').one()) %}

    {% do query.relatedTo(['and', {targetElement: status.id}]) %}
{% endif %}

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


Redis Enviornment Specific DB's I'm not entirely well versed in how Redis works, but I have an idea that it probably makes the most sense to have the 3 craft sites I have running on the same server, have 3 different redis databases assigned to each?

Is there a way to do so, like in general.php or db.php

As in

"site-one.com" => {
    'database' => 0,
},

"site-two.com" => {
    'database => 1,
}

You'll want to set your cacheMethod config setting to 'redis' and create a rediscache.php file in craft/config/.

That config file is multi-environment aware, just like the other files in craft/config/ and you can see the default settings for Redis in craft/app/etc/config/defaults/rediscache.php.


Rendering form from Entry Field I'm trying to pass an entry field type "Formfield" into a template. I have it working without passing any custom values through but when I do it outside of the render tag, No matter what I do I am getting an error saying null variable cannot render.  Thoughts?
ie: (Below works)
{{ entry.contactFormHandle.render() }}

But: (Does Not) in many variables and difference does not...
{{ craft.freeform.form("{entry.contactFormHandle}", {
                        labelClass: "my-label-class",
                        inputClass: "my-input-class",
                        submitClass: "my-button-class",
                        instructionsBelowField: true,
                        overrideValues: {}
                    }).render() }}

I'm sure it's something stupid. Any help would be appreciated!

Welcome to Stack Exchange! Yes, your syntax is wrong - you need to remove the curly brackets around entry.contactForm.handle, and the quotations, and actually get the handle.
{{ craft.freeform.form( entry.contactForm.handle,
    {
        instructionsBelowField: true
    }
).render() }}

Source: Freeform docs


Redactor removing IDS I'm using the plugin Redactor Extras https://github.com/elliotlewis/Redactor-Extras as I need be able to insert IDs to then anchor link to them.

However I'm finding the plugin adds the IDs as it should but on save they get stripped out. Oddly this plugin also allows you to add Classes which seems to be working but is still a bit temperamental.

Are there any settings I could try for Redactor to stop it doing this?

To prevent Rich Text fields from stripping your ID attributes, you'll need to disable the "Purify HTML?" setting for your field.

Note that disabling the HTML purifier does represent a potential security risk, but as long as you trust your content editor(s), you should be fine.


Update fails: mod_fcgid: read data timeout I keep getting the following error when trying to update my craft installation.

mod_fcgid: read data timeout in 31 seconds, referer: https://mysite.com/admin/manualupdate/craft
End of script output before headers: index.php, referer: https://mysite.com/admin/manualupdate/craft

I have tried updating my /etc/apache2/mods-available/fcgid.conf file with:

FcgidConnectTimeout 600
FcgidIOTimeout 600
IdleTimeout 600
ProcessLifeTime 600
IPCConnectTimeout 600
BusyTimeout 600

And this has given no results. I still get the error. The database wasn't able to go rollback and the site is currently not available. Unfortunately this is happening in production...

Help?

If running Webmin, check the Website Options under Server Configuration and set Maximum PHP script run time to unlimited or a largar value.

This is what finally did the trick but updating /etc/apache2/mods-available/fcgid.conf with the following values may have also played a role.

FcgidConnectTimeout 600
FcgidIOTimeout 600
IPCCommTimeout 600

After these changes and restarting apache, the script was finally able to finish and update the installation successfully.


What's the best way to paginate through entries from an entries field type? I have an entries field type associated with a structure section page. This displays the entries on this page in a particular order. When you click an entry link ti will take you to  a detailed page for more information about that entry. What I'd like to be able to do is paginate through these entries in the order set in the entries field, not just paginate through the entries in asc/desc or alphabetical order as would happen if I just paginated through the channel section that stores the entries.

I tried straight forward pagination as detailed in the documentation but two problems occurred. First the pagination links were created with proper beginning end and number but when clicking through them you remained on the same entry. Second, a pagination URI was appended to the URL which I don't want.

Is pagination even the proper approach to this problem or is there a better solution?

To do this, you would need to use getPrev() and getNext() on the related entries’ template.

The trick is telling getPrev() and getNext() to use the order you defined in the source entry’s Entries field.

So first, you will need to get that source entry. If you only have a single entry in your structure section that has one of these Entries fields, that could be as simple as this:

{# Get the entry in the structure section that relates to `entry` %}
{% set sourceEntry = craft.entries.section('myStructureSection').relatedTo({
    targetElement: entry,
    field: 'myEntriesField'
}) %}

Once you have that, you can just pass its Entries field into getPrev() and getNext():

{% set prevEntry = entry.getPrev(sourceEntry.myEntriesField) %}
{% set nextEntry = entry.getNext(sourceEntry.myEntriesField) %}

{% if prevEntry %}
    Previous: {{ prevEntry.title }}
{% endif %}

{% if nextEntry %}
    Next: {{ nextEntry.title }}
{% endif %}


Conditional for user registration fields What’s the best way to validate a user registration form to make sure that at least one of two fields is not empty?

I’ve tried a very simple controller but can’t get this to work past the point of trying to save the user. Any pointers with this method or for a different method entirely?

public function actionIndex() {

    $this->requirePostRequest();

    $fields = craft()->request->getPost('fields');

    $customField1 = $fields['customField1'];
    $customField2 = $fields['customField2'];

    $user = new UserModel();
    $user->email = craft()->request->getPost('email');
    $user->password = craft()->request->getPost('password');
    $user->setContentFromPost('fields');

    if ($customField1 != '' || $customField2 != '') {

        // RETURN CUSTOM ERROR

    }

    // OTHERWISE SUBMIT USER REGISTRATION REQUEST
    // AND RETURN ANY ERRORS

    craft()->users->saveUser($user);
    $this->redirectToPostedUrl();

}

Looks like I needed to set $user->username = craft()->request->getPost('email'); for my attempt to work.


Searching for entries across multiple fields including a relationship I'm trying to fetch a set of entries based on search parameters. The search is an "and" search, meaning that if criteria exist then they should all match for there to be a result returned.

I have managed to get this working with all the criteria except for one which needs to match a relationship.

My code below shows what I have so far. The relationship field is named "category" (although this actually relates to an entry in another channel).

{% set cat = craft.request.getParam('category') ? craft.request.getParam('category') : '' %}
{% set start_date = craft.request.getParam('start_date') ? craft.request.getParam('start_date') : 0 %}
{% set wage_from = craft.request.getParam('wage_from') ? craft.request.getParam('wage_from') : 0 %}
{% set wage_to = craft.request.getParam('wage_to') ? craft.request.getParam('wage_to') : 9999 %}
{% set location = craft.request.getParam('location') ? craft.request.getParam('location') : '' %}

{% set results = craft.entries({
    section: 'vacancies',
    order: 'score',
    relatedTo: [
          'and',
          { targetElement: cat },
          { field: 'category' }
      ],
    location: [
          'and',
          '= ' ~ location
      ],
    wage: [
          'and',
          '>= ' ~ wage_from,
          '<= ' ~ wage_to,
      ],
      startDate: [
        'and',
        '>= ' ~ start_date
      ]
  }) %}

It all seems to work until I add in the relationship. I know I'm not formatting this part of the query correctly but cannot work out how it should be formatted.

Basically, I am searching the channel "vacancies". The "category" field is a relationship with an entry in a channel named "apprenticeshipsCategories".

How do I do this?

I think I just had my Craft "Lightbulb moment".

I've got this working now. Once I realised that I needed to retrieve the category as an object in order to match against it using relatedTo it made more sense.

I also realised that I needed to used a wildcard rather than an empty string if a parameter was missing.

Here's my solution:

{% set cat = craft.request.getParam('category') ? craft.request.getParam('category') : '' %}
{% set start_date = craft.request.getParam('start_date') ? craft.request.getParam('start_date') : 0 %}
{% set wage_from = craft.request.getParam('wage_from') ? craft.request.getParam('wage_from') : 0 %}
{% set wage_to = craft.request.getParam('wage_to') ? craft.request.getParam('wage_to') : 9999 %}
{% set location = craft.request.getParam('location') ? craft.request.getParam('location') : '*' %}

{%
  set category = craft.entries({
        section: 'apprenticeshipsCats',
        title: cat
  })
%}

{%
  set results = craft.entries({
      section: 'vacancies',
      relatedTo: category,
      location: [
            'and',
            '= ' ~ location
        ],
        wage: [
          'and',
          '>= ' ~ wage_from,
          '<= ' ~ wage_to,
        ],
        startDate: [
          'and',
          '>= ' ~ start_date
        ]
    })

%}

So I still fetch the parameters and set default values for them, note the wildcard if "Location" is empty.

But then I get the category to be searched as a craft entries object.
Once I have that I can use its reference in my results query and bingo!


Loading an existing entries drafts in template/frontend I've been searching for a method to load in an existing entries drafts. Here is what I am trying to implement.

User can add or edit an entry from the front end of my craft site. They cannot publish.
Admin can see new drafts and publish them.

I see how to submit a draft update via the front end using the entryRevisions/saveDraft method. But how can I load in the current entries draft information into a form on the front end for a user to edit? Hopefully I missed this, or is it undocumented.

After doing some digging around I found the getDraftsByEntryId(entryId, locale) method of the craft.entryRevisions service that might help.

The following should return the first draft of an entry. Note: there is a second argument for 'locale', which defaults to current locale if none provided. Also not sure whether 'first' or 'last' would be considered the most recent draft.

{% set drafts = craft.entryRevisions.getDraftsByEntryId(entry.id) %}
{% if drafts|length %}
    {% set draft = drafts[0] %}
    {{ draft.title }}
    ...
{% endif %}

You will need to load the entry manually (i.e. through a custom route of some kind) as the draft's entry is likely to be 'disabled' (although not necessarily) and thus not load through the entry's default url. Something like '/mysection/edit/slug' perhaps (where 'slug' is a custom route token).

{% set entry = craft.entries({
    section: 'mysection',
    slug: slug
    status: null
}).first() %}


Using PayPal Standard with Craft Commerce Is it possible to use PayPal Standard with Craft Commerce? The docs are saying that Paypal is "fully supported", but I only see PayPal Express and PayPal Pro in gateways dropdown in conrol panel.

Craft Commerce uses Omnipay for its payment processing library.  Here's a list of the Omnipay officially supported 1st party gateways: https://github.com/thephpleague/omnipay#payment-gateways

Omnipay: Paypal says it supports these Paypal services:

PayPal_Express (PayPal Express Checkout)
PayPal_ExpressInContext (PayPal Express In-Context Checkout)
PayPal_Pro (PayPal Website Payments Pro)
PayPal_Rest (Paypal Rest API)

Didn't have much Googling luck trying to find a 3rd party Omnipay plugins that support Paypal Standard, but there's always the option of writing an Omnipay compatible one that wraps the Paypal Standard API, then a Craft plugin to bring that into Commerce.


Richt text change default configuration Is it possible to change the default settings of the Rich text field? I know that I can change the configuration in Simple.json and Standard.json but I can't find a Default.json file.

No, "Default" is Craft's default configuration and is not user configurable.


How to output Name in Matrix entries I have matrix field set up, is that possible to output Name in Field Settings (refer to the handle: aggressiveBehavior)? Thanks

I believe that it is not possible looking at the Matrix Block Model Docs.

What I would usually do, instead of having the front end facing title as the Field Name, is keep the Field name solely for the back end.

An example be (for a front end form)

<label>{{ 'Is your pet ever aggressive to strangers?' | t }}</label>
{% for option in matrixBlock.aggressiveBehavior.options %}
<input type="radio" name="aggressiveBehavior" value="{{ option.value }}">{{ option.label }}
{% endfor %}


Day and month names ignore certain formats in date filter and revert to number When I try to output the day name (l or D) or month name (F or M) i get a number instead of the day/month-name.

{{ entry.end|date("j. F Y") }}

turns into:

1. 9 2015

when output.

Expected output would be 1. oktober 2015 (site language is Norwegian (nb)) or even 1. October 2015 (if internationalization did not work).

This is a bug in the latest version of Craft specific to Norwegian locales that will be fixed in the next (post 2.3.2643) release.


Nested Matrix as field types Are nested matrices panned for the coming future releases?

I currently have a matrix where users can upload various assets. For each asset, they should be able to specify different details but this cannot be achieved with the current features as there is no way in which the details could be related to a particular asset that has just been uploaded.

I'll let Brandon and Brad answer regarding what's planned. :)

But, couldn't you solve this by adding fields to your assets? You can make fields of whatever type and add them to the field layout of asset sources. To edit them, you just double-click on the asset in the matrix. This works both for existing assets and newly uploaded assets as far as I can tell.


Remote assets space issue storage/runtime/assets/sources I was wondering if someone could help me with the following issue:

I'm saving assets on Amazon S3 and as per Craft's documentation Craft is keeping a copy of remote assets in storage/runtime/assets/sources folder. The issue is that this website has a lot of images and sources folder in storage is taking up a lot of space. It can go up to 5GB.

Is there a way I can tell Craft to not keep a copy of remote assets?

Many thanks

You can instruct Craft not to keep a local copy of remote assets by setting the maxCachedCloudImage config variable to 0 (zero).

It may be worth experimenting with that setting, to find a balance between caching some smaller images locally (thereby speeding up transformations), and preserving disk space.


PHP 500 Error On One-click Update I am trying to use the one-click update feature and continually am getting a 500 error when attempting retrieve available updates on staging server. All my permissions work correctly as my craft install works all over except when updating.

the URL that gives this error is:

http://staging.link.com/index.php?p=admin/actions/update/getAvailableUpdates

Stacktrace:

PHP Error [500]

chmod(): Operation not permitted (/var/www/staging/craft/app/helpers/IOHelper.php:1023)

#0 /var/www/staging/craft/app/etc/errors/ErrorHandler.php(184): Craft\ErrorHandler->handleError()
#1 /var/www/staging/craft/app/framework/base/CErrorHandler.php(133): Craft\ErrorHandler->handleError()
#2 /var/www/staging/craft/app/framework/base/CApplication.php(824): Craft\ErrorHandler->handle()
#3 /var/www/staging/craft/app/etc/web/WebApp.php(681): Craft\WebApp->handleError()
#4 unknown(0): Craft\WebApp->handleError()
#5 /var/www/staging/craft/app/helpers/IOHelper.php(1023): chmod()
#6 /var/www/staging/craft/app/etc/cache/FileCache.php(138): changePermissions()
#7 /var/www/staging/craft/app/framework/caching/CCache.php(185): Craft\FileCache->setValue()
#8 /var/www/staging/craft/app/etc/cache/FileCache.php(64): Craft\FileCache->set()
#9 /var/www/staging/craft/app/services/CacheService.php(130): Craft\FileCache->set()
#10 /var/www/staging/craft/app/etc/et/Et.php(247): Craft\CacheService->set()
#11 /var/www/staging/craft/app/services/EtService.php(54): Craft\Et->phoneHome()
#12 /var/www/staging/craft/app/services/UpdatesService.php(277): Craft\EtService->checkForUpdates()
#13 /var/www/staging/craft/app/services/UpdatesService.php(170): Craft\UpdatesService->check()
#14 /var/www/staging/craft/app/controllers/UpdateController.php(57): Craft\UpdatesService->getUpdates()
#15 /var/www/staging/craft/app/framework/web/actions/CInlineAction.php(49): Craft\UpdateController->actionGetAvailableUpdates()
#16 /var/www/staging/craft/app/framework/web/CController.php(308): CInlineAction->runWithParams()
#17 /var/www/staging/craft/app/framework/web/CController.php(286): Craft\UpdateController->runAction()
#18 /var/www/staging/craft/app/framework/web/CController.php(265): Craft\UpdateController->runActionWithFilters()
#19 /var/www/staging/craft/app/framework/web/CWebApplication.php(282): Craft\UpdateController->run()
#20 /var/www/staging/craft/app/etc/web/WebApp.php(811): Craft\WebApp->runController()
#21 /var/www/staging/craft/app/etc/web/WebApp.php(281): Craft\WebApp->_processActionRequest()
#22 /var/www/staging/craft/app/framework/base/CApplication.php(184): Craft\WebApp->processRequest()
#23 /var/www/staging/craft/app/index.php(62): Craft\WebApp->run()
#24 /var/www/staging/html/index.php(19): require_once()

That PHP error is happening as Craft is trying to adjust permissions in some folder, either in craft/app or craft/storage.

You’ll need to ensure that both of those folders (and all subfolders) are writable by PHP.


Unique input IDs in Freeform Apologies if this has already been brought up but shouldn't each input have a unique id? I assumed Freeform would prepend the input ids with the form id or something but it seems it just duplicates ids everywhere. Doesn't seem great for what is a pretty expensive plugin.

Solution for Freeform 3:

Preventing duplicated field id:
Set a custom field id prefix. Using the form handle might be a good id, as long as you're not using the same form twice on the same page.

Preventing duplicated form id:
Manually adjust the form id parameter to something unique.


How do you show which Sale a product has applied in Commerce? It's easy to know if a product has a valid Sale applied to it with product.defaultVariant.onSale - but how do you know which Sales are being applied to the product? How do you output that the product is currently part of a specific named sale, and any associated content you might want to show?

The real answer is:
{% for sale in variant.sales %}

    {% sale.description %}

{% endfor %}


Existing contents get deleted on Live Preview when adding new content on a matrix field When I add a new content for a matrix block field on an existing entry, all its previous contents gets deleted from the Live Preview, except for the editor which still has the previous contents. And then, when I try to save the entry, it seems that what is shown in the Live Preview was the only one saved and the previous data were gone.

Do you have this problem in a multisite-installation? If so, it could be something with your propagation mode on the matrix field.

Please give us some more details to your setup: which version of Craft CMS, which propagation mode, multisite or not.


Search form generates blank page I am trying to set up a search form in my website. Followed this tutorial on builtwithcraft documentation website.

So in my top navigation bar I include this code

<form class="navbar-form navbar-right" role="search" action="{{ url('/oeuvres/_results') }}">

        <input type="search" class="form-control" name="q" placeholder="Recherche">

            <button type="button" class="btn btn-default" value="Go"> </button>

</form>

And then the result page:

{% extends "_layout" %}

{% block main %}
    {% include "includes/_topNav" %}

Résultats

                {% set query = craft.request.getParam('q') %}
                {% set entries = craft.entries.search(query).section('oeuvres') %}

                {% if entries|length %}

{{ entries|length }} Votre recherche:

                        {% for entry in entries %}

{{ entry.title }}

                        {% endfor %}

                {% else %}

Votre recherche “{{ query }}” n'a donné aucun résultat.

                {% endif %}

    {% include "includes/_javaScript" %}
{% endblock %}

I have no idea what is wrong, it seems that the "q" param is passing through the result page (the address line is for example: http://www.example.com/oeuvres/_results?q=routes
But the page is totally blank. Meaning nothing gets generated between the body tags. (not even the template tags...

I can't find what I am missing here.

Templates starting with an underscore character is by default denied direct access in Craft (resulting in a 404 not found error). I guess that renaming your template to "results" should fix it.


need file extension in url to access template I've got a structure setup, and one of the entries under it is called "Our people" at the top level, in the "About" structure. So the url would look like this: /about/our-people.

I have a template setup at: craft/templates/about/our-people.html

When browsing /about/our-people it does not route there, though /about/our-people.html works fine.

In my general config I have 'omitScriptNameInUrls' => true set.
Only weird thing I have is a "Single" entry is setup to deal with the top level "about" page viewable at /about.

Any ideas?

Thanks!

The documentation for how Craft picks a template is here. Two of the relevant steps are:

  Is it an entry/category request?
  If the URI matches an entry’s or category’s URI, the section’s/category group’s template will get loaded, and the matched element will be made available to the template via a pre-populated entry or category variable.

and

  Does the URI match a template?
  Finally, Craft will see if the URI is a valid template path. If it is, it will return the matched template.

/about/our-people matches #4, and you get the about/_entry.html template. /about/our-people.html matches #6, so you get the about/our-people.html template.

The important thing is that Craft uses the first rule that matches.


Undefined property: Craft\WebApp::$urlManager in /var/www/craft/app/controllers/BaseController.php on line 37 So I'm trying to setup my first Craft installation on Digital Ocean. I'm bound to use Craft version 2.0.2535 since I'll be duplicating a site using this (so I cannot use Craft 3).

I've spun up a new Droplet on DigitalOcean. I've set up Apache, PHP and Mysql and verified it all works. After copying the the Craft files and resolved all the issues regarding rights to folders, I was finally ready to run the installer, I get this:

  Notice: Undefined property: Craft\WebApp::$urlManager in
  /var/www/craft/app/controllers/BaseController.php on line 37

  Fatal error: Uncaught Error: Call to a member function
  getRouteParams() on null in
  /var/www/craft/app/controllers/BaseController.php:37 Stack trace: #0
  /var/www/craft/app/framework/web/CController.php(308):
  Craft\BaseController->getActionParams() #1
  /var/www/craft/app/framework/web/CController.php(286):
  CController->runAction(Object(CInlineAction)) #2
  /var/www/craft/app/framework/web/CController.php(265):
  CController->runActionWithFilters(Object(CInlineAction), NULL) #3
  /var/www/craft/app/framework/web/CWebApplication.php(282):
  CController->run('renderError') #4
  /var/www/craft/app/framework/base/CErrorHandler.php(331):
  CWebApplication->runController('templates/rende...') #5
  /var/www/craft/app/framework/base/CErrorHandler.php(289):
  CErrorHandler->render('error', Array) #6
  /var/www/craft/app/etc/errors/ErrorHandler.php(149):
  CErrorHandler->handleError(Object(CErrorEvent)) #7
  /var/www/craft/app/framework/base/CErrorHandler.php(131):
  Craft\ErrorHandler->handleError(Object(CErrorEvent)) #8
  /var/www/craft/app/framework/base/CAp in
  /var/www/craft/app/controllers/BaseController.php on line 37

I honestly have no idea on what can be wrong. Any pointers would be very welcome...

You're probably running PHP v. 7.0 or higher on your DigitalOcean box; Craft CMS didn't have PHP 7.0 compatibility until Craft 2.4.2697, which is why it chokes.

Downgrading your PHP version to 5.6 or 5.4 should resolve your issue.

You should also beware of your MySQL version – Craft 2 has issues on MySQL 5.7; ideally you should make sure your droplet uses 5.6.

And also – I'd look into upgrading the install to the latest and greatest Craft 2.x, if not Craft 3. A lot of good stuff has happened since 2014 ;)


What Might Be Causing This Serialization Error? Craft Pro 3.0.7Notifications Plugin 1.0.6PHP 7.0

In trying to send notifications for new entries that have a checkbox field, we get this error in the logs:

  2018-05-14 09:19:32
  [192.168.10.1][1][-][error][UnexpectedValueException]
  UnexpectedValueException: Error at offset 0 of 2 bytes in
  /home/path/to/vendor/yiisoft/yii2-queue/src/serializers/PhpSerializer.php:32

This manifests as the notification getting stuck in queue, never releasing, always showing progress bar.

Removing only the checkbox field from this section, the notifications work as expected without any errors.

From what I read, serialization errors may result from encoding problems.

What else can I try to resolve this? Where else can I look?

Update the Notifications plugin.

From Craft Support:

  Ultimately Yii/Craft is using PHP's serialize() method to do the
  serialization, which has always had quirks with serializing different
  types of objects, especially the more complex those objects are.

  We try to only serialize simple objects and primitive data structures
  (arrays, strings, bools, etc.) to try and minimize those issues as
  much as possible.

From The Developer:

  Notifications are no longer queued as this causes a lot of issues with
  serialization. Will find a better solution for this in the future.

Prior to version 1.1.0, the Notifications plugin was attempted to serialize the entire entry to place it in queue.


Fatal error on install I have AMPPS installed on my Mac OS X, and am trying to install the CMS. When I browse to http://craft.dev/admin to install, it redirects to http://craft.dev/admin/install with the following error:

Fatal error: Call to undefined function ctype_alpha() in /Users/username/domains/craft.dev/craft/app/vendor/twig/twig/lib/Twig/Lexer.php on line 380

Any suggestions on fixing the issue?

Check that the php ctype extension is installed or enabled.


Rich-Text/Redactor hyperlink classes I’m trying to implement different hyperlink styles within a rich-text field by adding formatting options via a Redactor config file.

"formattingAdd": [
  {
    "title": "Button",
    "tag": "a",
    "class": "button"
  }
]

This isn’t working as expected though. The above, for example, adds a <span> around or within the <a> tag, occasionally removing the <a> tag altogether.

Is there a way to add classes to hyperlinks within a rich-text field?

Note: This rich-text field is already within a containing Matrix field, so that’s not an option.

If you only want to style how the link looks visually, and need a work-around, you could use my Redactor Styles for Craft plugin. If you add an inline style to the plugins Styles JSON object like this:

[
  {
    "btnName":"Action button",
    "className":"btn-action",
    "spanClass":"btn-action"
  }
]

Depending on which order the user creates the link and marks the text/link and select style, you now can get the following markup from your rich text field:

A link
A link

If this works for you or not depends on your design. Unless there are some styles on the  that can't be removed, you could style it so that it looks the same by using:

.btn-action > a,
a > .btn-action { ... }

You could also instruct your users to always create the link, then select the style, or the other way around. But, it's of course a very fragile solution.

Thinking of making a new plugin just for creating more advanced links, the built in one doesn't really cut it.


Feed Me: Valid JSON file returning as invalid Can anyone see why this data would return as invalid in Feed Me? It's valid JSON.

    [
      {
        "FIELD1":"1",
        "FIELD2":"Airmax",
        "FIELD3":"150-08ACW-134 ",
        "FIELD4":"09 Apr 2013",
        "FIELD5":"31 Dec 2030",
        "FIELD6":"24",
        "FIELD7":"23",
        "FIELD8":"28",
        "FIELD9":"29",
        "FIELD10":"29"
      },
      {
        "FIELD1":"2",
        "FIELD2":"Airmax",
        "FIELD3":"270-11AC3-134",
        "FIELD4":"01 Nov 2012",
        "FIELD5":"31 Dec 2030",
        "FIELD6":"23",
        "FIELD7":"21",
        "FIELD8":"27",
        "FIELD9":"28",
        "FIELD10":"28"
      }
    ]

The JSON example tab in the docs just shows the XML version so I can't see what it's supposed to be! I know there needs to be a primary element so my data just might not be right.

Thanks

I think the Json-file in it self is valid (you can always run it through a linter like JsonLint) but the problem lies with the fields. Some items (such as title) are required. I found a more accurate example in the repo of the plugin. You can find it here

[
  {
  "title":  "JSON",
  "slug": "json",
  "pubDate": "Tue, 24 Feb 2015 09:00:53 +0000",
  "entry_date": "Tue, 16 Jul 2013 17:14:36 +0000",
  "status": "enabled",
  "Assets": {
    "asset": [
      "350x150.png",
      "350x155.png"
    ]
  },
  "Categories": {
    "category": [
      "Category 1",
      "Category 2"
    ]
  },
  "Checkboxes": "option_2",
  "Color": "#ffffff",
  "Date": "Tue, 24 Feb 2015 09:00:53 +0000",
  "Dropdown": "option2",
  "Entries": {
    "Entry": [
      "Sample Event",
      "homepage"
    ]
  },
  "Lightswitch": "Yes",
  "Multi": "Option2",
  "Number": "10",
  "PlainText": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
  "Position": "right",
  "Radio": "Option2",
  "RichText": "
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam lectus nisl, mattis et luctus ut, varius vitae augue. Integer non lacinia urna, nec molestie enim. Aenean ultricies mattis ligula vel consectetur. Etiam ultrices fringilla lectus nec mollis.

Nunc elit magna, semper ac faucibus ut, volutpat eu augue. Vivamus id nibh facilisis, fermentum massa vitae, rhoncus mi. Praesent sit amet efficitur dui.
",
  "Table": {
    "row": [
      {
        "one": "Option1",
        "two": "Option2",
        "three": "6",
        "four": "true"
      },
      {
        "one": "Option3",
        "two": "Option4",
        "three": "7",
        "four": "false"
      },
      {
        "one": "Option5",
        "two": "Option6",
        "three": "9",
        "four": "true"
      }
    ]
  },
  "tag": [
    "Tag 1",
    "Tag 2"
  ]
 }
]


Exclude certain entries and its children from navigation I need to split up a navigaton tree. So I try to exclude certain pages from a structure based navigation tree PLUS their children automatically, but don’t seem to get it.

{% nav page in craft.entries.section('pages').id('and,not 3,not 4,not 5') %}

Excluding certain entries like this works.

But:

{% nav page in craft.entries.section('pages').descendantOf('and,not 3,not 4,not 5') %}

… doesn’t return anything of course, because descendantOf needs one exact ID. But how could I manage to exclude entries 3, 4 and 5 AND all their children from the navigation without calling the exact IDs of all the children?

Thanks!

If it’s true that the descendantOf param doesn’t allow to pass in multiple entries, you probably need to work around that issue and grab the descendants for each parent entry individually.

{% set parentIds = [3, 4, 5] %}
{% set excludeIds = parentIds %}

{% for parentId in parentIds %}
    {% set ids = craft.entries.descendantOf(parentId).ids() %}
    {% set excludeIds = excludeIds|merge(ids) %}
{% endfor %}

{% set idParam = 'and, not ' ~ excludeIds|join(', not ') %}

{% set entries = craft.entries.section('pages').id(idParam) %}