Can plugins in the Plugin Store require development versions of libraries via Composer? I recently put together a basic Constant Contact plugin for a project, and I'd like to clean it up and improve it for a public release. The problem is that it requires a development version of the Constant Contact SDK for compatibility with PHP 7+. I did this by adding a custom repository to the composer.json file pointing to the github repo, and then requiring the development branch.

"repositories": [
  {
    "type": "git",
    "url": "https://github.com/constantcontact/php-sdk.git"
  }
],
"require": {
  "craftcms/cms": "^3.0.0-RC1",
  "constantcontact/constantcontact": "dev-development"
},

In order for this to work, I had to change the stability requirements in my main composer.json file:

"minimum-stability": "dev",
"prefer-stable" : true,

It seems to me this would not be ideal for a plugin in the Plugin Store. Is packaging all of the dependencies up into a vendor subfolder within the project a better option?

Currently the Plugin Store requires non-development dependencies in your composer.json file.


Memory issue when updating all entries from a channel (allowed memory size of X bytes exhausted (tried to allocate Y bytes)) I'm trying to do a stock update for all entries within a channel with a cronjob once a day, and I can't achieve it, because I always get Allowed memory size of X bytes exhausted (tried to allocate Y bytes).

Entries are around 2000 and the server is an EC2 medium instance. The cron I'm using is:

0 9 * * * wget -O /home/ubuntu/cronStock http://domain.com/actions/garp/cron/changeStock

I will try to create a simpler script without all the loaders Craft calls in a controller, but I'm not sure it will work.

Code:

public function actionChangeStock()
{
    foreach ($this->getAllFromChannel('productVariants', 10) as $key => $entry) {

        //$entry = $this->getElementByField("3081001100390", ElementType::Entry, null, "variantSku");
        //$entry->enabled = false;
        $entry->getContent()->setAttributes(array(
            'variantStock'  => $this->getStockFromGarp($entry->variantSku)
        ));
        $success = craft()->entries->saveEntry($entry);

        echo $entry->variantSku.': '.$entry->variantStock.'<br>';
    }
    die();
}

protected function getAllFromChannel($channel, $limit = null) {
    $criteria = craft()->elements->getCriteria(ElementType::Entry);
    $criteria->section = $channel;
    $criteria->limit = $limit;

    return $criteria->find();
}

How can I fix this problem?

If you just want to re-save a large number of entries without modifying them, you can run a ResaveElements task, which takes some basic parameters and re-saves all the entries that match them.

You can do that like this:

// Queue up a new ResaveElements task
craft()->tasks->createTask('ResaveElements', null, array(
    'elementType' => ElementType::Entry,
    'criteria'    => array('section' => 'mySectionHandle', 'limit' => null, 'status' => null, 'localeEnabled' => null)
));

// Start running tasks
craft()->tasks->runPendingTasks();


CometChat integration I need to implement Comet Chat, a facebook-chat-like third-party script, into my Craft project.

Comet Chat can connect to most CMS and PHP framework but there is no Craft integration yet, so I tried to use the "custom coded site" procedure.

http://www.cometchat.com/documentation/installing-cometchat/custom-coded-site/php-site/

Comet Chat need to access a session variable to authenticate user. Ex: $_SESSION['userid'].

The problem: Craft write its session variables with some nice sorcelery that makes outside script unable to read it.

So, the Comet Chat is not able to read the userid, even if I made a Craft plugin who writes UserID in $_SESSION['userid'].

I also tried, by the Craft cookie ($_COOKIE values are bidirectionally accessible unlike $_SESSION values, of course) to find some relation or mechanism to tells Comet Chat who's the current user in Craft, unsuccessfuly.

Perhaps some other PHP scripts or cases may need to read the Craft session, so I'm pretty sure this question can be relevant for more than Comet Chat integration.

Any ideas?

Thanks in advance!

The Matt's answer was pretty complete and worked almost, but for the benefit of others, there is the changes required files to make it works:

in integration.php

find

define('SET_SESSION_NAME','');

change for

define('SET_SESSION_NAME','CraftSessionId');

and make your getUserID functions look like

function getUserID() {
            $userId = 0; // Return 0 if user is not logged in

            if ( $_SESSION[ 'craftUserId' ] )
            {
                $userId = $_SESSION[ 'craftUserId' ]; // Set this session variable in a Craft plugin
            }

            return intval( $userId );
    }

and in a Craft plugin, add this to a init() function

public function init()
    {
        craft()->on('userSession.onLogin', function(Event $event) {
            $currentUser = craft()->userSession->getUser();
            craft()->httpSession->add( 'craftUserId', $currentUser ? $currentUser->id : null );
        });
   }

If you want to be full-padded, you can also add something to unset your CraftUserId variable onLogout event, but I don't think it's needed.

Thanks a lot to Matt and Brad who helped me out on Easter day!


How Do I Restart an Entries Loop Once It Hits the Last Entry So I've got a Matrix block that is pulling in some entries and I'm looping through the entries in that block in a template. I'm then pulling a text field from each entry and putting it onto a page. Currently, there are three total entries in that block (though that will likely expand over time). Once I hit the third and final entry, I would like the loop to start over again at the first, loop through the entries again until it gets to the last entry and start over again. I'd like to do that continuously up to a point - say 15 loops.

I'm struggling with how to get the entry loop to start over once it reaches the last entry.

This is the current basic code that loops through the entries and then loops through the matrix blocks within the entries to output the text to pull into the page.

{% for entry in block.homeClientQuote %}
    <div>
        {% for block in entry.clientQuote %}
            {{ block.actualClientQuote }}
        {% endfor %}
    </div>
{% endfor %}

You can repeat a loop with another for loop.

For example, here's a loop that repeats 15 times:

{% for i in 1..15 %}
    Loop: {{ i }}<br>
    {% for entry in block.homeClientQuote %}
      ...
    {% endfor %}
{% endfor %}

You can also use the i variable if you need to change the output depending on the loop number.

{% if i > 10 %}{% endif %}


Possible to append another field to entries field title? Does anyone know of a way to append another field to the entry title displayed in an entries field? I'd like to try and append an entry_version field to the title displayed so I get something like "Entry Title - v1" instead of just "Entry Title" when selecting related entries in a parent entry.

Under the Section's entry type settings, you can uncheck the "Show the Title Field" checkbox and set the title format to be something like:

`{title} - v{myVersionFieldHandle}`


Can't get setFieldValue to work I've got this

    // Creating users through frontend
    Event::on(Users::class, Users::EVENT_BEFORE_ACTIVATE_USER, function(UserEvent $event) {
        $userId = $event->user->id;

        // Allow assigning user groups through the frontend (circumvent elevated user sessions)
        $groupId = Craft::$app->getRequest()->getBodyParam('userGroup');
        if ($groupId) {
            Craft::$app->getUsers()->assignUserToGroups($userId, [$groupId]);
        }

        // This does not work
        Craft::$app->users->getUserById($userId)->setFieldValue('discountPercentage', 15);
    });

Assigning the user group works fine, so I don't get why assigning a field value doesn't. The discountPercentage field is a simple Number fieldtype

I also tried $event->user->setFieldValue('discountPercentage', 15); without success.

Also I tried surrounding 15 in quotes, like '15', but that didn't work either.

Edit:

Submitting the "create user form" through the frontend gives no errors. discountPercentage is just left blank.

If you are going to set the fieldValue, you need to save the element:

    $userObject = Craft::$app->users->getUserById($userId);
    $userObject->setFieldValue('discountPercentage', 15);
    Craft::$app->elements->saveElement($userObject);

Should do the trick.


Set tabs in settings on Plugin I would like to add tabs in setting page in my plugin. I have the following code in /[myplugin]/templates/_setting.html. However, the tabs do not show up, does anyone have any sample code to set up the tabs? Thanks

{% import "_includes/forms" as forms %}

{% set tabs = {
customer: { label: "Customer"|t, url: url('emailUser/_settings') },
veterinarian:    { label: "Veterinarian"|t, url: url('emailUser/_vetSettings') }
} %}

{{ forms.textField({
label: "Customer Account Creation Confirmation Subject"|t,
instructions: "Customer Account Creation Confirmation Subject" |t,
name: 'custAccountCreationSubject',
value: settings.custAccountCreationSubject,
})}}

{{ forms.textareaField({
label: "Customer Account Creation Confirmation Message"|t,
instructions: "Customer email message when customer register" |t,
name: 'custAccountCreation',
value: settings.custAccountCreation,
rows:10,
})}}

In myplugin.php

public function getSettingsHtml()
{
    return craft()->templates->render('emailuser/_settings',array(
                'settings'=>$this->getSettings()
    ));
}

Here’s a simple plugin with two tabs and two fields, one field per tab. This plugin was generated on https://pluginfactory.io/. It’s a great starting point to get the plugin scaffolding set up. After that I added the code that I’ve included below to get it to work.

It should give you something like the following screenshot for the first tab:

and for the second tab it should look similar to this:

Folder Structure

[-] craft
   [-] plugins
      [-] myplugin
         [-] controllers
            |-- MyPlugin_TabOneController.php
            |-- MyPlugin_TabTwoController.php
         [+] resources
         [+] services
         [-] templates
            [-] _layouts
               |-- cp.twig
            [-] tabOne
               |-- _index.twig
            [-] tabTwo
               |-- _index.twig
         [+] translations
         [+] variables
         |-- MyPluginPlugin.php

myplugin/MyPluginPlugin.php

I'm only highlighting the functions that were necessary for the plugins to show up. Add or adjust them as needed.

...

public function registerCpRoutes()
{
    return array(
        'myplugin' => ['action' => "myPlugin/tabOne/index"],
        'myplugin/additional-settings' => ['action' => "myPlugin/tabTwo/index"],
        /**
         * Each 'action' relates to a controller in your plugin.
         * The names of your controller and these action must match.
         */
    );
}

protected function defineSettings()
{
    return array(
        'someSetting' => array(AttributeType::String, 'label' => 'Some Setting', 'default' => ''),
        'additionalSetting' => array(AttributeType::String, 'label' => 'Some Additional Setting', 'default' => ''),
        /*...more settings here as needed...*/
    );
}

public function getSettingsHtml()
{
   return craft()->templates->render('myplugin/MyPlugin_Settings', array(
       'settings' => $this->getSettings()
   ));
}

public function getSettingsUrl()
{
    return 'myplugin';
    /* This must be the same as the first segment in your cpRoutes. */
}

...

myplugin/controllers/MyPlugin_TabOneController.php

namespace Craft;

class MyPlugin_TabOneController extends BaseController
{

    /**
     * @var    bool|array Allows anonymous access to this controller's actions.
     * @access protected
     */
    protected $allowAnonymous = array('actionIndex',
        );

    /**
     */
    public function actionIndex()
    {
        $settings = craft()->plugins->getPlugin('myPlugin')->getSettings();
        $this->renderTemplate('myplugin/tabOne/_index', array(
            'settings' => $settings,
        ));
        /**
         * The path above is to your templates folder in your plugin.
         */
    }
}

myplugin/controllers/MyPlugin_TabTwoController.php

namespace Craft;

class MyPlugin_TabTwoController extends BaseController
{

    /**
     * @var    bool|array Allows anonymous access to this controller's actions.
     * @access protected
     */
    protected $allowAnonymous = array('actionIndex',
        );

    /**
     */
    public function actionIndex()
    {
        $settings = craft()->plugins->getPlugin('myPlugin')->getSettings();
        $this->renderTemplate('myplugin/tabTwo/_index', array(
            'settings' => $settings,
        ));
        /**
         * The path above is to your templates folder in your plugin.
         */
    }
}

myplugin/templates/_layouts/cp.twig

It’s not necessary to break out the templates like I have here but it does help to keep from repeating your self in the templates, especially if you have several tabs.

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

{% includeCssResource "myplugin/css/Myplugin_Style.css" %}
{% includeJsResource "myplugin/js/Myplugin_Script.js" %}

{% set title = 'My Plugin' %}

{% set tabs = {
    settings: { label: "Settings"|t, url: url('myplugin') },
    additionalSettings: { label: "Additional Settings"|t, url: url('myplugin/additional-settings') },
} %}

myplugin/templates/tabOne/_index.twig

The data-saveshortcut attribute on the form will allow you to use the keyboard shortcut to save your plugin’s settings by using ⌘ + S on a Mac. I’m assuming that Ctrl + S works on Windows although I haven’t tried it.

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

{% set selectedTab = 'settings' %}

{% set content %}

Settings

    <form method="post" action="" accept-charset="UTF-8" data-saveshortcut data-confirm-unload>

        {{ getCsrfInput() }}

        <input type="hidden" name="action" value="plugins/savePluginSettings">
        <input type="hidden" name="pluginClass" value="MyPlugin">
        <input type="hidden" name="redirect" value="myplugin">

        {{ forms.textField({
            label: 'Some Setting',
            instructions: 'Enter some setting here.',
            id: 'settings-someSetting',
            name: 'settings[someSetting]',
            value: settings['someSetting']})
        }}

            <input class="btn submit" type="submit" value="{{ 'Save'|t }}">

    </form>

{% endset %}

myplugin/templates/tabOne/_index.twig

Notice that you’ll need to set the selectedTab in each template for the tabs to work correctly. This should match one of your keys that was set in the tabs variable in the myplugin/templates/_layouts/cp.twig. Also the hidden redirect input in the form should be set to wherever you want to it end up. I noticed that it felt the best when it went back to the original page and it showed the saved values.

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

{% set selectedTab = 'additionalSettings' %}

{% set content %}

Additional Settings

    <form method="post" action="" accept-charset="UTF-8" data-saveshortcut data-confirm-unload>

        {{ getCsrfInput() }}

        <input type="hidden" name="action" value="plugins/savePluginSettings">
        <input type="hidden" name="pluginClass" value="MyPlugin">
        <input type="hidden" name="redirect" value="myplugin/additional-settings">

        {{ forms.textField({
            label: 'Some Additional Setting',
            instructions: 'Enter some setting here.',
            id: 'settings-additionalSetting',
            name: 'settings[additionalSetting]',
            value: settings['additionalSetting']})
        }}

            <input class="btn submit" type="submit" value="{{ 'Save'|t }}">

    </form>

{% endset %}

That should do it!


How do I define an entry's META description? I'd really like some help with Craft CMS, that's probably a very basic thing to achieve, but I've so far got no idea how to. In another post about SEO, I saw something like this written:

<meta name="title" content="{% if title is defined %}{{ title }}{% endif %}">
<meta name="description" content="{% if description is defined %}{{ description }}{% endif %}">

The first part, regarding the title, is in the _layout.html by default. And, in the CMS, above each entry's body, I have managed to display a box for the user to enter a title.

BUT, were I to add the second part, regarding the description, I have so far been unable to find out how in the CMS, I can add a box for the user to enter a description.

Thanks in advance for any help that anyone can provide.

With kind regards,

Mark

The Title field will be a part of every entry 90% of the time ('Singles' don't need a Title).

To add a custom field in Craft:
Settings > Fields > (create a field)

To add the new field to a content type:
Settings > Sections > (click the "Edit content-type" link to the right) > (drag your new field into the blue box) > hit Save.

I like to create a separate custom field for each e.g. "Meta Title" and "Meta Description" - I then add these to a separate tab within a given content-type. (see attached)

Normally, I leave the SEO fields optional.

Then, in _layout.html:

<title>{% block entryMetaTitle %}{% endblock %}{{ siteName }}</title>
<meta name="description" content="{% block entryMetaDescription %}{% endblock %}">

The block tags inherit content from an individual template e.g. domain.com/news/news-article-slug, will make use of a single-entry template e.g. craft/templates/news/_entry.html which will contain:

{% extends "_layouts/_layout" %}

{% block entryMetaTitle %}{% if entry.metaTitle %}{{ entry.metaTitle}} | {% elseif entry.title %}{{ entry.title}} | {% endif %} News | {% endblock %}
{% block entryMetaDescription %}{% if entry.metaDescription %}{{ entry.metaDescription}}{% else %}{{entry.summaryText}}{% endif %}{% endblock %}

{% block content %}
...
{% endblock %}

The above will display any content which the client decides to add to the custom fields, OR if nothing has been added the template will display the entry Title + Summary Text (in this case)

This post might also help you to define your own approach: How do you handle SEO on your site?


How to use plugin settings I am learning craft and trying add settings page for my plugin. I read that need to define settings like,

class CocktailRecipesPlugin extends BasePlugin
{
    // ...

    protected function defineSettings()
    {
        return array(
            'cocktailCategories' => array(AttributeType::Mixed, 'default' => array('Sours', 'Fizzes', 'Juleps')),
        );
    }
}

So isn't clear and there is no explanation what the array return and how to use it inside the template.

Thank you

How are you trying to use it in the template?

Below is a very basic way of how to display a setting in a front end twig template.

First define your settings with the defineSettings() method (as you already have).

protected function defineSettings()
{
    return array(
        'mySetting' => array(AttributeType::String, 'required' => true)
    );
}

Then create a directory in the root of your plugin folder and call it “templates”. Create a new .html or .twig file in that folder and call it “_settings.html”. Inside of that you could put the following:

{% import "_includes/forms" as forms %}
{{ forms.textField({
        label: "My Setting"|t,
        id: 'mySetting',
        name: 'mySetting',
        instructions: "Input your setting"|t,
        value: settings.mySetting,
        errors: settings.getErrors('mySetting')
    })
}}

After this go back to your primary plugin class and add the getSettingsHtml() method:

public function getSettingsHtml()
{
    return craft()->templates->render(‘pluginHandle/_settings', array(
        'settings' => $this->getSettings()
    ));
}

Now, if you go into admin/settings/plugins you can click on your plugin and there will be an input field there where you can save the setting. If you wanted to get this value you could add a method to your service like this:

public function getMySetting()
{
    $plugin = craft()->plugins->getPlugin(‘pluginHandle');
    $settings = $plugin->getSettings();

    return $settings->mySetting;
}

You could call this anywhere throughout your plugin like this:

craft()->pluginHandle_serviceName->getMySetting();

To do that on the front end in a twig template, just create a method in the variables class. It would look something like this:

public function getMySetting()
{
    return craft()->pluginHandle_serviceName->getMySetting();
}

In your front end twig template you could call it like this;

{{ craft.pluginHandle.getMySetting() }}

I hope any of this clears it up a bit.


Edit meta property value in Open Graph meta tag I would like to implement Pinterest Product Pin for my products. I need to update og:xxx values. Here is how i done:

{% set og = seomaticMeta.og %}
{% set og = og | merge({'type': "product", 'product:price:currency': "USD", 'product:price:amount': variant.price|number_format(2) }) %}
{% set seomaticMeta = seomaticMeta | merge({'og': og}) %}

This adds new tags but the property of the meta tag should not include 'og:' in product related meta tag. So this outputs something like:

<meta property="og:product:price:amount" content="300.00" />

but it should be something like this:

<meta property="product:price:amount" content="300.00" />

How can i achieve this?

Right now, SEOmatic assumes an og: namespace for all OpenGraph tags, which clearly isn't correct. So you'd just need to add these tags yourself if you want to use them.


How do you import tags from EE (solspace tags) along with entries? Has anyone successfully imported tags from EE (solspace tags) along with entries? I installed this plugin but it seems to be really old and Craft must have changed a lot since then since it reflects even a different Schema and many deprecated methods. I refactored to work with simple entry fields but importing tags along with that seems a little trickier.

I think I am good if I can just figure out how to save relations for entries. VERY new to craft as in 2 days but this all seems familiar since I'm a Laravel guy.

I can figure this stuff out by following the trails but if someone else has tackled this or can give me quick feedback on using the services and models that would so super fantastical.

I would use the "Feed Me" plugin which allows to import entries including tags from feeds (XML, RSS, Atom). So you only have to create an XML feed with all the information you want to transfer (which is in EE quite easy).


Does Craft save dates in the locale format? I have a website with multiple locales (English, Dutch, French, German and Spanish). I'm saving dates on a front-end form through Ajax, but it seems that Craft saves the dates in the locales' format, eg. in English, the 1st February 2018 would be 02/01/2018 and in Dutch it would be 01/02/2018.

I'd think Craft would save all dates in the same format, disregarding any locale. I read somewhere that craft saves all dates in UTC format.

When I'm in the locale EN and I pass the date 01/02/2018, expecting 2nd January 2018 to be saved, it saves OK.
However, if I'm in NL, DE or FR and I pass the same date, it is saved as 1st February 2018 as these languages switch the day and month around.

I always pass MM/DD/YYYY to the date field whatever locale.
I'm using the dateFns library for formatting and the date it formats is correct. I use VueJS v-calendar as a datepicker which also shows everything correct.

But when it's saved to Craft it suddenly switched day and month in the back-end!

Any help or explanation, please? Seems like strange behavior choices.

Where are you seeing the incorrect date, in the database or when you output it in the templates?

I think Craft is probably working as expected here.

Craft will expect the date submitted to be in the correct format for the locale it was submitted from, so will translate it from that format into UTC to save in the database.

Then, when the date is output in templates, it is transformed again to the correct format for the locale it is being displayed in.

The EN locale presumably assumes US date formatting so 01/02/2018 is correct as 2nd January 2018. For European locales, a date submitted as 01/02/2018 will correctly be recognised as 2nd February 2018.

You need to make sure that the date input in your form is formatted according to the expected way for the locale the form is in.


How can I use images from my live Craft Site when developing locally I'd like to sync the database of a live site to my local site for development, but don't want to download all the images and files. Is there an .htaccess that could look for the files locally, and on 404 look to the live site? What are the implications for image transforms etc?

There seem to be some solutions available for WordPress and Drupal, but has anyone had any experience with this with Craft?

Thanks

You could set up your assets through Amazon S3 or another remote service then that wouldn't be a problem.

Alternatively you will need to download all the assets locally if you have relative paths /uploads/images/banners/banner1.jpg.

Though maybe another option is to set the path to include the domain then you can probably get the files from the server (so in your markup you would see the image would be linking to http://www.yousite.com/uploads/images/banners/banner1.jpg


Craft 3 Redactor Link no longer has target option The option for opening a link in the Redactor WYSIWYG no longer includes a field for opening it in a new tab? I haven't been able to find any docs that indicate any options for the Redactor config file to add this back in?

Add the linkNewTab config option to the Redactor config you're using:
So, that would become something like:

{
    "buttons": [...],
    "plugins": [...],
    "linkNewTab": true
}


Using parameters with Embedder Embedder offers up some cool functionality, but I don't see where it explains how to set video parameters. It says you can, but not seeing how. Anyone successfully done this?

You have to use the previous example and format your own code to match.

Instead of

youtube_showinfo="0"

it goes in as

youtube_showinfo:0


import store items from Magento to Craft Commerce is there a plugin or script to import products, accounts, categories from Magento to Craft Commerce?
Or is this something to be written from scratch with FeedMe?

I don't think there's a plugin that does this. However, I would like to point you to a talk by James Greig that happened last Friday, in which he explains a number of possible ways to migrate content from X to Craft. He too uses FeedMe to do the import part, but has a few approaches to exporting the content on the other side:

https://www.greig.cc/dotall2018


URL rewrites not working return Apache 404's Content is accessible via example.com/index.php?p=page-name but not via example.com/index.php/page-name or example.com/page-name.

The .htaccess and 'omitScriptNameInUrls' => true are both in place but still no luck.

Any ideas?

Those are the 2 thing you need to ensure are correct.

If .htaccess files are being ignored, you need to check to see that AllowOverride is set correctly. See http://httpd.apache.org/docs/2.4/mod/core.html#allowoverride for details on setting "AllowOverride All". You need to also ensure that it is set in the correct scope - ie, in the right block in your configuration. Be sure you're NOT editing the one in the block, for example.

Third, if you want to ensure that a .htaccess file is in fact being read, put garbage in it. An invalid line, such as "INVALID LINE HERE", in your .htaccess file, will result in a 500 Server Error when you point your browser at the directory containing that file. If it doesn't, then you don't have AllowOverride configured correctly.


Making an entry grid with Batch 2,3 (2 in row then 3 in row) I'm trying to make a News item grid. I'm looking for a solution to output 2 type of "rows". One that shows 2 entries and the other shows 3 entries.
I tried playing around with batches already but can't really manage to get it working alright. Is batch the right filter to use? If not what should I try using?

It should look like this:

Twigless code looks like this:

With some help from HendrikEng's answer I figured out something that does work.

I had to make the batch bigger to an amount of 5 making the "row's" bigger. Also I had to set the position of the bigger block which always is the first or second of this batch so I could set this witha variable which changes if a new batch started.

This is the finalcode which works perfect:

{% for entry in craft.entries.section('cases')|batch(5) %}

    {% set bigBatchNr = 2 %}

    {% if loop.index is even %}
        {% set bigBatchNr = 1 %}
    {% endif %}

        {% for batch in entry %}
            {% if loop.index == bigBatchNr %}

            {% else %}

            {% endif %}
        {% endfor %}

{% endfor %}


Image Transform Files Path Regarding the Image Transforms and the handling of its files.

Is there a config setting that controls the location (file path) of the Image Transform Files?

By default there is automatically created a new folder which bases it name of the transform-behavior name from the CP (or the code) i.e. _crop1920x1440 in the same directory as the original image is located.

I would like to be able to store all the transformed images in one place i.e. /assets/transforms.

Not currently, but feel free to make a feature request!

https://github.com/craftcms/cms/issues


Is there a good way to eager load Craft's Element Relations through a plugin? For a specific entry in a specific section I would like to eager load all associated data from the related elements.

Say that I know the related elements are from the following field types:

An assets field
An entries field

And I know the field handles or IDs. This isn't supposed to be a "catch all" solution, it can be on a case by case basis.

I want to eagerly load all of these elements (including their relationships should they have some, i.e., the related entries have related images).

How would I go about this in a plugin?

I know I can write a hook or a custom controller action, I'm more curious about how I'd setup the calls themselves. I can't use Yii's with for Active Record because that isn't setup in the entry record itself.

Note, this is similar to the following question, but more direct:
"Eager loading" of relations like Yii's "with" function

I wanted to do this too but none of the relationships are defined in the record classes.

An approach to achieving this would be to extend the Craft record classes in your own record classes and override the defineRelations method. This does however require that you understand CActiveRecord relations.

If you need any pointers give me a hollar.


How can I display fields from Field Layout Designer in the template? I'm working on a plugin that lets you create multiple forms. For each form I have a Field Layout Designer that lets you add fields from the fields groups.

My question is how can I display those fields on the front end template..say a contact.html single page.

Basically the same way you add fields to entry types and they show up when you are adding an entry... but I would like this to render a form on user facing pages with all the fields.

Here is what I have so far: http://d.pr/f/1bHCX

EDIT:

So this is what I have so far, its getting somewhere, sort of.

In my front end index.html

{% set form = craft.formBuilder.getFormByHandle('testForm') %}

I get fieldLayout id with {{ form.fieldLayoutId}} = 69

And inside content block:

{% for item in form.getFieldLayout() %}
  {% include "_includes/fields" with {
    fields: item.getFields(),
    element: form
  } only %}
{% endfor %}

I get this error Impossible to invoke a method ("getField") on a string variable ("69")

So its great that I get fieldLayout id for specified form handle but now I need to figure how to get all the fields related to that fieldLayout. I understand the error message but maybe someone knows how to rewrite that for statement to get results I need?! :)

I guess I don't know how to query my db for the fields that belong to layoutId 69..

I need to get fieldId 15 and 16 to render on the front end.

Ok so I finally got it going with the help of that Inspector plugin. This is what I did..

In my front end template..(i used index.html)

{% extends "_layout" %}

{% import "_includes/forms" as forms %}
{% set form = craft.formBuilder.getFormByHandle('testTwo') %}
{% set fields = form.fieldLayout.getFieldLayout().getFields() %}

{% block content %}
<div class="container">

{% for field in fields %}
  {% set input = craft.fields.getFieldById(field.fieldId) %}
  {% set requiredInput = field.required %}

  {% include "_includes/field" with {
    field: input,
    required: requiredInput
  } only %}
{% endfor %}

</div>
{% endblock %}

Explanation:

Each form will have a formHandle name. With the following line I can target that form in the template (see screenshot 1)..

{% set form = craft.formBuilder.getFormByHandle('testForm') %}

Each form has a fieldLayout Builder so I now need to get the fieldLayoutId associated with the form above. While I'm getting the fieldLayoutId I will ask for fieldId's associated with this fieldLayoutId..The bellow will let me get fieldId (also see screenshot 2 in my question, basically the following line lands me on that table)

{% set fields = form.fieldLayout.getFieldLayout().getFields() %}

Now that I have fieldId's I can use the following line to get all my fields!

{% set input = craft.fields.getFieldById(field.fieldId) %}

I'll need to include that inside my for loop so I can render all the fields.

There is more work for what I need to achieve in this plugin, but this was biggest obstacle for me personally so hope this helps someone too. Thanks for help and info on the Inspector plugin.

Note

There are 2 folders you will need to copy from craft/app/templates/ directory into your craft/templates/ directory.

_includes and _components


No ordinary news post ordering I'm trying to work out how I can order news posts by postDate, unless a lightswitch is toggled for a post, at which point it will use the dateUpdated to order that item.

This is so a client can still change posts without them appearing at the top of the list (for corrections, etc), but also make substantial updates to certain posts and have them appear as the latest newest item.

You can do this entirely from the order param using MySQL’s CASE syntax:

{% set newsItems = craft.entries({
    section: 'news',
    order:   '(CASE field_myLightswitchField
                  WHEN 1 THEN elements.dateUpdated
                  ELSE elements.dateCreated
              END) DESC'
}) %}

Note that you’ll need to include that “field_” prefix before your Lightswitch field’s handle since this is a more complex condition and Craft won’t be sure if it should add that automatically.


Search Plus Plugin: How to sort facets? I'm using the Search Plus plugin with Craft, it's been a great help!
I have 2 questions I need help with, as the Search Plus docs are not too clear so far:

I have a search page with filters (facets) in place, however these
facets are arranged according to search count by default. I want to
sort them by alphabetical order instead, and I've seen that it is
possible with Algolia, but I need help to do that with Search Plus.
Upon clicking on a filter checkbox, the other filters disappear. How
do I trigger them to still appear but with a different CSS class
applied?

I ran into the same problems as you and I believe I've solved it, but it may be different for your specific use case.

There may be a way to control this with the init options but I wasn't able to find a way to do it, so I just edited the searchplus.js code directly in the searchplus folder. Look for something like e.getFacetValues(i,{sortBy:["isRefined:desc","count:desc"]}) and change it to e.getFacetValues(i,{sortBy:["name:asc"]}) instead (you can leave the isRefined:desc part at the front as well if you would like the filtered options to automatically populate to the top of the list). Keep in mind that changing the js file is a global change which would affect other faceted forms if you have more than one on your site.
When you define the facets in your init code: $(this).searchplus({facets: ['facet1', 'facet2'],});, replace facets with disjunctiveFacets and you should stop seeing filters disappear from the facet you're selecting (see faceting options on the Search Plus docs. The other facet's filters will disappear though depending on if there are valid matches or not, but it will at least prevent the other filters from your selected facet from disappearing immediately.


"Natural" sorting for ElementCriteria I want something sorted like this:

MyString8
MyString9
MyString10
MyString11

$criteria->order = 'myField asc doesn't get things quite right, as MySQL has not native "natural sorting".

You can fake it by first sorting by character length, and then by the value: $criteria->order = 'CHAR_LENGTH(myField) asc, myField asc

Its not perfect, but in certain cases, it will be all you need. Other methods exist as well: https://stackoverflow.com/a/8557307/935398

Note: CHAR_LENGTH is a MySQL function that is getting passed directly to the ORDER BY clause. It has nothing to do with Craft directly.


Importing assets with Feed Me using Element Exporter data When I export data using Craft's built-in Element Exporter, asset fields are exported with an element ID. This is the same as Category and Entry fields, for example.

However, when mapping fields in Feed Me, asset fields do not allow you to select ID as the provided data, like a Category or Entry field would. When you run import, these fields seem to be skipped as the provided data is not what Feed Me is looking for.

Perhaps I'm missing something here, but Element Exporter and Feed Me don't seem compatible when it comes to asset fields at the moment. Has anyone else had any luck using these two programs together with regards to assets?

I don't know if you're still facing this issue but it's something I'm working on right now! Basically my solution was to create a short program to parse through the Element Exporter json and to change anything that was an Asset ID to that asset's url (which Feed Me accepts).
    public function modifyExport(array $element): array {
        $result = [];
        //Parse through JSON export
        foreach ($element as $key => $value) {
            //Recursive function to keep traversing down levels
            if (is_array($value)) {
                $result[$key] = $this->modifyExport($value);
            //You've reached a root level, check the content
            } else {
                //If the value is a number, it is representing an ID
                if (is_numeric($value)) {
                    //Find the Element corresponding to this id
                    $assetCheck = Craft::$app->getElements()->getElementTypeById(intval($value));
                    //Check if the element is an asset
                    if ($assetCheck == 'craft\\elements\\Asset') {
                        //Get the actual asset data
                        $asset = Craft::$app->getElements()->getElementById(intval($value));
                        //Create the asset path *this may differ based on where your assets are*
                        $path = getEnv('DEFAULT_SITE_URL') . '/assets/images/' . $asset->folderPath . $asset->filename;
                        //Rewrite the content with the path, instead of the id
                        $result[$key] = $path;
                    //If the element is not an asset, keep it the same
                    } else {
                        $result[$key] = $value;
                    }

                }
            }
        }
        return $result;
    }

Once I got the result, I used file_put_contents('end/path/goes/here.json', json_encode('result here')); to place it in a different file OR you can simply overwrite the same export file. Hope this helps!


Click read more on a single and it takes you to items in a structure Hey guys I was wondering if anyone could help me...

I am trying to link from a readmore button in a single( it's like a services page) to pages in a structure.

So instead of having a top level services page in the structure, having it as a single and all the services together in a structure and linking to them from the single is this possible? if so, how can i do it?

You can access any information from just about anywhere in craft. In fact, the only thing that distinguishes one 'page' from another is that craft conveniently populates a predefined 'entry' variable populated with the 'current' entry (EntryModel) using the template that you defined in your section settings. But you can choose to use that 'entry', ignore it, redefine it, or grab entirely different content altogether.

If I understand your requirements, it sounds like you are trying to create an 'index' page of sorts in your single, which links to entries in your structure.

{{ entry.title}}

{% set entries = craft.entries.sections('myStructureHandle').limit(null) %}

    {% for entry in entries %}

{{ entry.title }}

{{ entry.description }}

            Read more

    {% endfor %}


Impossible to access an attribute on a null variable - on the one() method - all() works! First question - but I think this is a bug (not my fault).

I have entries/pages (a structure) - one parent (product overview) with children (products)

I have one category group with categories - only for assigning some repeating data to the child entries (like properties of products - colors for instance)

Getting the properties (the field data of the assigned category) on the product pages itself works flawless like this:

{% set properties = entry.fieldPropertiesCategory.one() %}
{{ properties.propCatFieldColor }}

BUT on my product's list page (the above-mentioned parent) it doesn't.
I try the following:

{% set products = craft.entries.descendantOf(entry).all() %}
{% for product in products %}
    {% set properties = product.fieldPropertiesCategory.one() %}
    {{ properties.propCatFieldColor }}
{% endfor %}

I get "Impossible to access an attribute ("propCatFieldColor") on a null variable."

But properties isn't null (checked this with dump()) ... it's the same like on the children entries.

My workaround is the use of all() and an additional iteration - this surprisingly works:

 {% set products = craft.entries.descendantOf(entry).all() %}
 {% for product in products %}
    {% set properties = product.fieldPropertiesCategory.all() %}
    {% for property in properties %}
       {% if loop.first %}
          {{ properties.propCatFieldColor }}
       {% endif %}
    {% endfor %}
{% endfor %}

Makes no sense to me ...

I tried everything - getting the category object of the children entries in various ways on the parent entry but this all doesn't work. Always the impossible to access error.

Has anyone an idea on this?

It feels like not all your products have a fieldPropertiesCategory value defined. Does that work?

{% set products = craft.entries.descendantOf(entry).all() %}
{% for product in products %}
    {% set properties = product.fieldPropertiesCategory.one() %}
    {{ properties ? properties.propCatFieldColor : '' }}
{% endfor %}


Finding entry by content I'm currently creating a plugin for craft and have stumbled across a slight problem. I'll try summarise of what I am doing and what I am trying to achieve.

So, I'm trying creating a plugin which will update entries within craft via an external API. I have managed to get the initial save to work using these following lines:

$entry = new EntryModel();
$entry->getContent()->title = $project->name;
$entry->sectionId = 10;
craft()->entries->saveEntry($entry);

The issue arises when I'm trying to update the model. Obviously, I don't want to duplicate entries.

I can get the entry using this line:

EntryRecord::model()->findById(45);

(this is just used for testing, eventually I will be getting the record via a custom variable).

What I'm trying to do here is update the title of this record, from what I can see this is stored in the craft_content table.

Basically what I'd like to do is something like :

EntryModel::model()->findByAttributes(array('title'=>$project->name);

So I can then update the content title of that row.
I can see I can't do it this way, would you be able point me in the right direction?

It sort of depends on what information you have to identify the entry. If your external service knows the entry id that would be the most direct — otherwise you would have to find the entry by some other unique property.

To update an entry (given $entryId, $newTitle):

$entry = craft()->entries->getEntryById($entryId);
if ($entry) {
    $entry->getContent()->setAttributes(array(
        'title' => $newTitle
    ));
    craft()->entries->saveEntry($entry);
}

To update an entry (given $sectionHandle, $title, and $newTitle - or other unique property):

$criteria = craft()->elements->getCriteria(ElementType::Entry);
$criteria->section = $sectionHandle;
$criteria->title = $title;
$entries = craft()->elements->findElements($criteria);

foreach ($entries as $entry) {
    $entry->getContent()->setAttributes(array(
        'title' => $newTitle
    ));
    craft()->entries->saveEntry($entry);
}

Could also use the 'search' method (although less reliable):

$criteria = craft()->elements->getCriteria(ElementType::Entry);
$criteria->search = 'fieldHandle:searchstring';

In the last two cases, would need to handle the possibility that more than 1 entry is returned.

Also, when creating entries might want to include the authorId and typeId, in addition to sectionId:

$entry = new EntryModel();
$entry->sectionId  = $sectionId
$entry->typeId     = $typeId
$entry->authorId   = $authorId;
$entry->enabled    = true;
$entry->getContent()->setAttributes(array(
    'title' => $title
));
craft()->entries->saveEntry($entry);


Use different template for paginated entries Puzzle of the day: How does one load paginated entries on a different template?

Let's say in my homepage I'm loading the latest 5 entries and I would like to have pagination links below, however I want these to load on a different template. (in order to have less rings and bells than on the homepage)

I tried to use routes but it doesn't seem to be working, is this because the pagination works from the original template?

Here's what I tried for example.com where example.com/p2 is paginated:

'(?P<page>\d+)'     // page must be the answer, right?       nope...
'p(?P<number>\d+)'  // let's try combining 'p' and a number  nope...
'p\d+'              // how about with just the regex?        nope...
'(?P<page>)'        // also targets homepage so...           nope...

I also tried doing it in the CP with no results.

I don't know if there's a route way to handle this, but you could do a conditional on the craft.request method getPageNum() like so:

{% if craft.request.getPageNum == 1 %}
    <!-- Header for the home page -->
{% else %}
    <!-- Header for pagination pages -->
{% endif %}


Parse files on plugin init I have a scenario in a plugin where I need to create / check data obtained by reading files. This currently happens on plugin init but isn't completed in time to make use of by other functions.

My plugin needs to parse a few SVG's and stylesheets and create data accordingly. I'am currently checking against a last modified date to avoid extraneous work.

The SVG's and stylesheets are from the website public directory and can be modified by the developer at any time and I would like to avoid any manual interaction within the CP when it comes to parsing these files.

What would be an acceptable way to ensure this data is generated before my plugin attempts to use it?

After some reordering of my logic and moving code to the init method of the plugins service I have been able to solve this problem with the below.

class SvgIconsService extends BaseApplicationComponent
{
    public function init()
    {
        $this->createResources(); // Method call to perform file operations

        parent::init();
    }

    private function createResources()
    {
        $folders = IOHelper::getFolderContents(craft()->config->get('iconSetsPath', 'svgicons'), false);

        if (is_array($folders)) {
            foreach ($folders as $idx => $f)
            {
                $iconSets[IOHelper::getFolderName($f) . IOHelper::getFolderName($f, false)] = IOHelper::getFolderName($f, false);

                // Create sprite sheet resources from Stylesheet
                $stylesheets = IOHelper::getFolderContents($f, false, '\-sprites.css');

                if(!empty($stylesheets)) {
                    foreach ($stylesheets as $stylesheetIdx => $stylesheet) {
                        craft()->templates->includeCss(IOHelper::getFileContents($stylesheet));
                        $this->getSpritesFromStylesheet($stylesheet);
                    }
                }

                // Create sprite sheet resources from SVG
                $svgs = IOHelper::getFolderContents($f, false, '\-sprites.svg');

                if(!empty($svgs)) {
                    foreach ($svgs as $svgIdx => $svg) {
                        $this->getSpritesFromSvg($svg);
                    }
                }
            }
        }
    }
}

I was originally calling craft()->svgIcons->createResources(); from the plugin init method.


How can count and then order by the # of entries assigned to a category; and then limit to only the top 3? **How can I modify this to orderBy the # of entries and then limit to the top 3? **

{% for categoryName in craft.categories.group('markets') %}
    {% set numofEntries = craft.entries.section('posts').relatedTo(categoryName).total() %}

    {{ categoryName.title }} ({{numofEntries}})
{% endfor %}

Ideally you'd do this from a custom plugin so you could write some queries directly against the database.

If you're looking to do this from a template, this should work, albeit it's not very efficient.

{% set entryArr = {} %}

{# Store the slug as the key in an array and the total number as the value #}
{% for categoryName in craft.categories.group('markets') %}
    {% set entryArr = entryArr|merge({(categoryName.slug): craft.entries.section('posts').relatedTo(categoryName).total()}) %}
{% endfor %}

{# Sort the array by the descending value maintaining the keys #}
{% set entryArr = entryArr|sort|reverse %}

{# Grab the first 3 values from the array #}
{% set entryArr = entryArr|slice(0, 3) %}

{# print them off #}
{% for slug, number in entryArr %}
    {% set categoryName = craft.categories.slug(slug).one() %}
    {{ categoryName.title }} - ({{number}})
{% endfor %}


Searching for any keyword in query I have the following text search input field:

<form action="{{ url('search') }}">
    <input type="search" name="q" placeholder="Search">
</form>

I would like to search each keyword in the user's query with the OR logic as per Craft docs.

  salty OR dog  containing either “salty” or “dog” (or both).

How can I separate the user's text search for "salty dog" so that the search query returns results for "salty" or "dog" instead of only for results containing "salty dog"?

Below is how I currently have the search set up in the template:

{% set query = craft.request.getParam('q') %}
{% set entries = craft.entries.search('*' ~ query ~ '*').order('score') %}
{% paginate craft.entries.search('*' ~ query ~ '*').limit(10).order('score') as pageInfo, pageEntries %}

I have fuzzy search enabled via config:

'defaultSearchTermOptions' => array(
   'subLeft' => true,
   'subRight' => true,
),

One way to do it is to split the search query on spaces, and then join it with 'OR':

{% set query = craft.request.getParam('q')|split(' ')|join(' OR ') %}
{% set entries = craft.entries.search(query).order('score') %}

The above will convert the search term "salty dog" to "salty OR dog". It'll work regardless of the number of keywords in the original search query string.

You should probably also make sure that you remove redundant whitespace from the original query, if you don't then a search query like "salty  dog" (double space) will result in a query like "salty OR OR dog". Here's how you could do that using some regex and the replace filter:

{% set query = craft.request.getParam('q')|replace('/(( )+|(\\n)+)/', ' ')|split(' ')|join(' OR ') %}


Output Channel entries on another page with a matrix block I know im doing something small wrong but I cant see what at this point.
I have a channel called 'testimonialEntries' and I want to randomly output one of these entries on seperate pages. I cant output the matrix block in 'testimonialEntries' but i can the title, so i know its working just not accessing the matrix block.
{% for entries in craft.entries.section('testimonalEntries').orderBy('RAND()').limit(1).all() %}
{% block in entry.matrixBlock %}

{{ block.heading }}
]

{{ block.bodyContent }}

{% endfor %}{% endfor %}

In this example im getting the entry title, but how do i also get a matrix block?
Edit: AM I getting close?
{% set testimonialEntry = craft.entries.section('testimonalEntries').orderBy('RAND()').limit(1).with(['testimonial']).one() %}
{% set testimonialEntryMatrixBlocks = testimonialEntry.testimonial %}
    {% if testimonialEntryMatrixBlocks %}

{{ testimonialEntryMatrixBlocks.body }}

{{ testimonialEntryMatrixBlocks.quote }}

{{ testimonialEntryMatrixBlocks.role }}

    {% endif %}

Ok final edit incase anyone else runs across this: It Works!
    {% set testimonialEntry = craft.entries.section('testimonalEntries').orderBy('RAND()').limit(1).with(['testimonial']).one() %}
{% set testimonialEntryMatrixBlocks = testimonialEntry.testimonial %}
    {% if testimonialEntryMatrixBlocks %}
        {% for testimonial in testimonialEntryMatrixBlocks %}

{{ testimonial.body }}

{{ testimonial.quote }}

{{ testimonial.role }}

        {% endfor %}
    {% endif %}

No need for a loop if you're just fetching a single entry:
{% set testimonialEntry = craft.entries.section('testimonalEntries').orderBy('RAND()').limit(1).one() %}
{% set testimonialEntryMatrixBlocks = testimonialEntry.matrixField.all() %}

Ideally for better performance you'd also use eager loading to load the matrix blocks at the same time as fetching the entry:
{% set testimonialEntry = craft.entries.section('testimonalEntries').orderBy('RAND()').limit(1).with(['matrixField']).one() %}
{% set testimonialEntryMatrixBlocks = testimonialEntry.matrixField %}


Craft hangs when updating entry I've had this issue for a while now and have never been able to get it solved - even after chatting in Slack about it with some people. Basically whenever I go to update an entry, Craft hangs and locks up Apache. It times out in about 5 minutes or if I manually restart Apache, things go back to normal. The entry is updated after the server restarts so it appears that the database write is successful.

It's becoming a huge problem as I'm finishing up a site for a client and they're needing to put content in. I'm running this on a Google VM and have tried installing it on a fresh server with no luck. I'm running Ubuntu 14.0.3. I'm running other Craft sites on Google and have no issues.

I tried a few steps a while back (I can't remember what exactly), I believe I increased a couple parameters in PHP.ini but I honestly can't remember. I used to be getting the zend_mm_heap_corrupted error but that's gone away now from my Apache error log.

Any help is appreciated. It's getting sort of urgent at this point since my deadline is approaching and entries need to be worked on.

My Apache version is 2.4.7 if that makes any difference.

It turns out that I was running a dev release of PHP 5.6 from a PPA and not the official Ubuntu release. With Brad Bell's help (thank you so much!) I got on the right track to looking into PHP and realized that that was the problem. After purging the PPA and reverting to PHP 5.5.9 on the official Ubuntu repo, the problem seems to have gone away. Hopefully never to return again.

Thanks again, Brad!

EDIT: As I said below, the problem appeared again. It seems to have been solved when I disabled Craft's devMode in my environment variables. I'm not sure what would cause that to be an issue, but devMode is something I can live without for now since the site is near going live. Brad, if you have any insight as to why devMode would be causing the issues, I'd love to hear it :)

Thanks!


Template output when grouping matrix blocks I have a shared content builder matrix field that has the usual blocks: Redactor, Headings, Images, etc.

A typical entry might look like this:

- Heading
- Redactor
- Image
- Redactor
- Heading
- Redactor
- Heading
- Redactor
- Image

Ideally I'd use a nested matrix - I'm aware this is on the roadmap  and Super Table / Neo do support this but I'd like to reuse my shared content builder field and handle the output via the templates.

On the page I'd like to output it like so:

- Heading | - Redactor
          | - Image
          | - Redactor

- Heading | - Redactor
- Heading | - Redactor
- Heading | - Redactor
            - Image

Basically grouping by heading block and then output any content until the next heading block.

I've seen a couple of examples which are similar to this but I haven't been able to get the template and queries right for this.

I know I can use the group filter but I'm having trouble with not being able to break out of a loop. Fairly sure I need to construct a list of structured id's and output them that way.

Anyone done something similar to this or can shed some light?

If by grouping you mean wrapping each groups in a
 for example, this should do it for you:

{% set groupCount = 0 %}
{% for block in entry.blocks %}

    {% switch block.type %}
        {% case "headingBlock" %}
            {{ groupCount > 0 ? '
' }}

            {{ block.header }}
            {% set groupCount = groupCount + 1 %}

        {% case "richtextBlock" %}
            {{ block.richtext }}

        {% case "imageBlock" %}
            {{ block.image.one().url }}
    {% endswitch %}

{% endfor %}

Changing the fields/blocks name accordingly of course.


Craft CMS 3 Boilerpoint Web Project Setups Available? Does anyone have any recommended boilerpoints or guides on setting up Craft CMS 3 with front-end tooling? Looking for an initial install to be setup properly with a preconfigured database, NPM, node.js, Sass, and page templates configured to get any web project started.

A good starting point would be the nystudio107 or marbles craft scaffolding projects:

https://github.com/nystudio107/craft

https://github.com/Marbles/craft


Pass radio button values to invisible field in Sprout forms I have a form built with Sprout forms that has a few radio button fields, all with numeric values. I'm looking to provide the total sum of these fields to a hidden/invisible field upon submit.

Is it possible to provide the value of the radio button field directly to the Invisible Field Value using twig syntax? Or should I just go the scripting route and use jQuery to update the hidden/invisible field's value?

Two potential ways to address this:

Setup a Sprout Fields Hidden Field and add javascript to your page (or in your form template using Template Overrides) to calculate the values and submit the calculated value with the rest of the form.
Create a custom front-end field integration that is aware of the Radio Button fields that you need to process and have that field calculate and display the result of those values.

The first approach is probably the easiest approach and should work fine if you're sending your submissions via email and if it's unlikely that anybody will be editing the Radio Button fields in the CP.  The second approach may be more robust if there is a chance the Radio Buttons ever get edited and the Total Field needs to get recalculated.

Side Note: The Invisible Field won't work in this use case right now as you want to calculate values based on the submitted form values. The Invisible Field lets you pass it dynamic values as the page loads but at that time the page would not have any info on the values of the Radio Buttons.


Is it possible to show a successful logout message? When site members click logout they are taken back to the homepage.

I'd like to redirect the user back to the login page but with a "You're logged out" type of message.

Is something like this possible yet?

It is not possible yet, but a quick plugin would make this possible. It would just be a controller with a logout action. You'd be able to call the action as a url with:

/actions/[PluginHandle]/[ControllerName]/[ActionName]

Then you can logout the user the same way Craft does in their controller and edit the redirect as you see fit. Something like this:

craft()->userSession->logout(false);
$this->redirect('?status=logout');

This would log them out and then send them to the homepage with a query attached to the end.


Getting "Internal Server Error: Function 'dump' does not exist" when accessing/creating custom fields On my in-development version of a site I'm working on, I'm unable to access any of my custom fields without Craft displaying an error that reads:

  Internal Server Error Function "dump" does not exist

I can navigate to Settings > Fields but when I attempt to click on any of my fields to check/adjust settings or when I try to create a new field, I get the error screen. I'm able to access all other parts of the CP, create entries, adjust settings, etc.

The odd thing is that I have a working instance of the site running in my local environment. As part of my troubleshooting process, I dumped the database on the staging site and imported my local version. I also replaced the "craft" folder on my staging site with the one from my local site. The problem still persists.

I recently updated to the latest build (2.1.2569) so I first thought something in the update might need fixing, but my local instance is updated as well and completely functional.

In case it helps, I'm hosting my staging site on Arcustech and have had no issues up to now.

Any ideas what might be going wrong?

Adding as an answer because it was confirmed via a support ticket that a plugin was at fault.

Twig's dump method is only available in Craft when devMode is enabled.

Turn it off, reproduce the problem, then search your craft/storage/runtime/logs files for [error].

The stack trace listed in that error log will show which plugin is causing the issue.

Chances are that plugin is calling Twig's dump somewhere in a template, assuming it will always be available, when that is not the case.


How to build a great multi-lingual navigation with channels, structure, and manageable in the CP I'm working on a complex website with multi locales, channels, structures and different designs per page. And the site needs a breadcrumb path.

My client needs to manage and add items the to menu.

This is a simple overview of the navigation:

Home
About us

Profile
History (different template)
Staff (listing with entry url's)
Jobs (listing)
etc

investor relations

finance
results (with iframe)

portfolio
press (custom url to external page)
etc

So no hard coding. What is the best solution to build this?

I think this is still a difficult thing in Craft. We need something like Navee or Structure (expression engine) to have a client friendly navigation system.

I've tried CraftNav. But it is still too simple.

Not sure I'm the best person to answer this having only built one Craft site but here goes.

I've created a Structure called Main Menu which has three Entry Types. (Entry types were the key for me when doing this)

A Structure allows drag and drop ordering and hierarchal navigation ordering for parent > child relationships.

Entry Link
Asset Link
External Link

Entry Link

Asset Link

External Link

Big, big (two bigs!) NavEE fan here, CraftNav has huge potential to replicate it but it's still a tad early when I tried it.

In short Entry Types were the key for me.

Note: For my own sanity at a later date it would be good to read this post on how to tell if your Structure Navigation has child elements.

Not sure if this helps but hope it does.


Why is Craft loading jQuery via cpresources? And can I stop it? I've been doing some performance checks on a website I'm building, and noticed that jQuery 3.5.1 is being loaded via cpresources:

Why is it doing this? And can I stop it? I'm already loading jQuery 3.5.1 in my scripts.js file (combined with some other stuff and minified using gulp & webpack).

If any of your image transforms have not previously been processed they will make a call to /cpresources/... To prevent this, generate all your transforms before page load with the generateTransformsBeforePageLoad config setting:
'generateTransformsBeforePageLoad' => true


Plugin settings - file field upload location My plugin needs to allow admin to upload an image. I have the field setup and saving ok. But i cant seem to control the upload location.

This is what i have so far in my settings:

{{ forms.file({
    label: "My Image"|t,
    instructions: ""|t,
    name: 'myImage',
    value: settings.myImage
}) }}

When I output the settings.myImage, I get the file name on its own and no path. I would like it to upload to my /uploads folder.
So for example, the image I uploaded was "test.jpg". When I output the result of settings.myImage, I get "test.jpg" and no path.

Unfortunately, a simple HTML file input on its own isn't enough to upload an image (in Craft or anywhere else) – the input simply exposes the file on your local filesystem to the browser/server. In other words, with your current setup, you're not actually uploading anything.

In my opinion, you have two choices:

Use Assets and Craft's built-in Assets ElementSelect input (easy)
Don't use Assets; upload the image natively using a file input (harder)

Personally, I'd recommend that unless you can't have the image be an Asset file for some reason, you should definitely go with the Assets approach. It's way easier to set up, offers a familiar user experience and you can even use image transforms and whatnot since your myImage file will be a bona fide Asset.

Either way, here's how option 1 could look:

In your plugin's settings.html file, replace your current call to the forms.file() macro with this:

{{ forms.field({
  label: "My Image"
}, include('_includes/forms/elementSelect', myImageSelectConfig)) }}

Then, fire up your plugin's primary class. Revise your getSettingsHtml() method to include the myImageSelectConfig attribute referenced in settings.html above, so the method looks something like this:

public function getSettingsHtml()
{
    return craft()->templates->render('yourpluginhandle/settings', array(
        'settings' => $this->getSettings(),
        'myImageSelectConfig' => array(
            'id'                 => 'myImage',
            'name'               => 'myImage',
            'jsClass'            => 'Craft.AssetSelectInput',
            'elementType'        => new ElementTypeVariable(craft()->elements->getElementType(ElementType::Asset)),
            'elements'           => $this->getSettings()['myImage'] ? craft()->elements->getCriteria(ElementType::Asset, array('id' => $this->getSettings()['myImage'])) : null,
            'sources'            => array('folder:2'),
            'criteria'           => array('kind' => array('image'), 'localeEnabled' => null),
            'limit'              => 1,
            'viewMode'           => 'table',
            'selectionLabel'     => Craft::t('Add image'),
        ),
    ));
}

Note: The sources attribute refers to the ID(s) for the Asset folder the admin should upload images to (and choose images from). You can look at the craft_assetfolders database table to figure out which ID(s) you want. Alternatively you can remove the sources property entirely, to enable all folders – which is probably the best option if this is going to be a publicly available plugin.

And that's it. The actual myImage setting value stored will be an array with the ID to the selected Asset file, e.g. {"myImage":["42"]}. If you need to pull the Asset in a template, you'll need to add a Variable class to your plugin, exposing the plugin settings:

class MyPluginVariable
{
    public function settings()
    {
        return craft()->plugins->getPlugin('myPlugin')->getSettings();
    }
}

...and in your template:

{% set assetId = craft.myPlugin.settings.myImage %}
{% set asset = craft.assets.id(assetId).first() %}

If you don't want to go with the Assets approach, you can keep your forms.file() macro in settings.html. However, there's a few more things you'll need to handle to get the upload working.

First, in order to actually upload a file from a file input, the enclosing form needs to have an enctype="multipart/form-data" attribute. Unfortunately, plugin settings forms don't, and there's no real way to add it. However, you can use jQuery to hack it in – add this to your plugin's settings.html file:

{% includeJs '$("form:first").attr("enctype", "multipart/form-data");' %}

Second, you'll need some server side code to actually handle the upload. Add the following to your plugin's primary class:

public function prepSettings($settings)
{

    $imageFile = UploadedFile::getInstanceByName('settings.myImage');

    if ($imageFile) {

        // Where should the image be stored?
        $basePath = $_SERVER['DOCUMENT_ROOT'];
        $uploadFolder = '/uploads/yourpluginhandle/';
        $filePath = $basePath.$uploadFolder.$imageFile->name;

        // Make sure the upload folder exists
        IOHelper::ensureFolderExists($basePath.$uploadFolder);

        // Attempt to upload the file
        if ($imageFile->saveAs($filePath)) {
            // File uploaded successfully – store the relative filepath in the plugin settings
            $settings['myImage'] = str_replace($basePath, '', $filePath);
        } else {
            // Aw.
            craft()->userSession->setError(Craft::t('Unable to upload image {filename}', array(
                'filename' => $imageFile->name,
            )));
        }
    }

    return $settings;

}

The above example is pretty much the bare minimum you'd need in order to upload a file from your plugin's settings page, to an arbitrary folder on your server's file system. The example prepSettings() script will upload the file to a folder called /uploads/yourpluginhandle in the public webroot (i.e. $_SERVER['DOCUMENT_ROOT']), before storing the relative path to the file in the settings, if the upload was successful.

Keep in mind that file uploading is actually fairly complex (lots of things can go wrong), and also a potential security risk. You should probably consider adding some code to ensure that the file's mime type ($imageFile->type), size ($imageFile->size) and other properties are legit, before calling $file->saveAs(). You might also need to create a UI for displaying and deleting the current image, and making sure old and no longer selected files are deleted from the server.

Finally, I'd posit that a vanilla browser file input is a pretty terrible user experience, compared to the Assets select input in Craft proper. There's all sorts of JavaScript libraries to help out with that, of course – in any case the above is hopefully a good starting point if you go down this road.


How do I change the default front-end language in Craft Personal? Our client wants to have an English back-end, but a German front-end (for now, other languages later). Any idea how to handle this?

Only Craft Pro supports multiple locales for a site.  You can see the feature matrix for the different editions here: http://buildwithcraft.com/pricing


How to create an entry from plugin controller? Let's say I have a section 'foo', with following fields and slug:

First Name (name)

Last Name (lname)

Plan (plan)

Cost (cost)

The field cost is dynamically created by a function already present in controller. I tried the following:

public function actionGetCost()
{
    $fname = craft()->request->getParam('name');
    $lname = craft()->request->getParam('lname');
    $plan = craft()->request->getParam('plan');

    ...

    $entry = new EntryModel();
    $entry->sectionId = 16;
    date_default_timezone_set('America/New_York');
    $date = date('n-j-Y') ;
    $entry->postDate = $date;
    $entry->authorId = 1;
    $entry->enabled = true;
    $entry->setContentFromPost([
       'name' => $fname,
       'lname' => $lname,
       'plan' => $plan,
       'cost' => $cost->id,
    ]);

    $save = craft()->entries->saveEntry($entry);

    if ($save){
      echo "saved" !
    }else{
      echo "<pre>";
      print_r($entry()->getAllErrors());
      echo "</pre>";
    }
}

What's wrong in the code? How can I do it?

As Damon mentions, I'd highly recommend checking out the Guest Entries plugin.

Specifically the private _populateEntryModel() method which creates the EntryModel class and gives a good example of the properties that are necessary to set to before calling EntriesService->saveEntry().


Twig default filter or Null coalescing operator? When testing for a variable in a template these two appear to do the same thing. I've read CruftlessCraft's article on How to check for undefined variables but can't see an explanation of why I should use one over the other. In his examples (below) I note that only the default filter includes "" in the list of results, is that correct or significant?
Is one faster or more efficient?

{% if twigVariable|default %}
    Value is set and not empty
{% else %}
    Value is either undefined, false, 0, null, "", [] or {}
{% endif %}

or

{% if twigVariable ?? false %}
    The value is set and not empty
{% else %}
    Value is either undefined, false, 0, null, [] or {}
{% endif %}

Does it make any difference if I don't need a fallback or the else and am just wrapping it around a div that shouldn't be shown if the variable doesn't have any usable content?

So things like the null coalescing operator make it easier to chain things, so if you have a number things to fall back on, it's much neater to write:

{% set woof = bark ?? howl ?? growl ?? null %}

...then it is to try to chain that all together with | default filters.

Something that may also make your life easier is the Empty Coalesce plugin, so you can write:

{% set woof = bark ??? howl ??? growl ??? null %}

What's the difference? The null coalescing operator only checks for null, so if bark = "" then it'll choose that, which often isn't what you want for strings.

There's a writeup of all of this in Handling Errors Gracefully in Craft CMS article.

Now, what is going to be more performant? Unless you're in a massive inner loop (which we should avoid in a templating language anyway), I doubt it'll matter. PHP code is transpiled to a bytecode that often gets cached, it should be fine.

But in theory, ?? and ??? are probably marginally faster.


Saving Category through API I'm trying to create a category through the api to import a load of datas,
but I'm stuck, the category won't be saved, and the saveCategory() method just returns false

$category = new CategoryModel();
$category->setContentFromPost(array(
    'groupId'       =>  $this->category_group_id,
    'title'         =>  $data[0],
    'colorCode'     =>  $data[1],
    'colorPreview'  =>  $data[2]
));
$category->enabled = true;
$res = craft()->categories->saveCategory($category);

Can I get a glimpse of what's happening, or the error ?

Is there anything wrong in this code ?
Does anyone have a good example/documentation for this ?

Thanks for your help.

Nicolas

You can get any validations errors on the category after you've attempted to save it with CategoryModel::getAllErrors() or \CModel::getErrors().

You're also setting the groupId on the Category's ContentModel, but this property is actually on the Category record itself as it sets the relationship directly.

$category = new CategoryModel();
$category->groupId = $this->category_group_id;

$category->SetContentFromPost(array(
    'title' => $data[0],
    'colorCode' => $data[1],
    'colorPreview' => $data[2],
));

if (craft()->categories->saveCategory($category))
{
    return true;
}
else
{
    // dump the error messages
    Craft::dd($category->getAllErrors());
}


How to disable template caching? devMode isn't doing it I'm trying to disable template caching in my development environment. I've tried a few things but thus far nothing has worked. I had thought that just setting devMode to true in the config would do the trick, but I'm still caching. The control panel shows the caution lines to indicate I'm in dev mode, but I still have to manually clear the cache before template changes show up. What am I overlooking?

It is true that devMode does not turn off caching. What I do is define a flag in general.php:

'cacheThings' => true, // true by default, but usually false for dev

and then in my templates:

{% cache if craft.config.cacheThings %}

update
Since version 2.4 there is a new config value: enableTemplateCaching, so all you need to do now is set this false in your development environment.


Installing and using super-filter plugin I'm currently testing the super-filter and I was wondering if someone has experience working with this plugin. The instructions are unfortunately very unclear to me. I've come as far as trying to create a new search setup but I'm dumbfounded by the following

What exactly do I have to put here and what does it do?

The documentation offers the following, but it doesn't make sense to me: "Template Override Folder - the folder of the templates that you'll override to modify html's. The items.twig must be copied to this folder to modify element attributes."

I am also unclear where to put the following code mentioned in the documentation.

    {{ craft.superFilter.setup('searchList') }}

            {{ craft.superFilter.displaySearchFields() }}

            {{ craft.superFilter.displaySortOptions() }}
            {{ craft.superFilter.items() }}
            {{ craft.superFilter.getPaginateLinks() }}
            {{ craft.superFilter.close() }}

Thanks for any hints.

This is an option to modify the html element that is being used by the search field. You will have to specify the folder in your site template path what template file to override. You can start by copying and pasting sample html template in vendor/pdaleramirez/super-filter/templates to the specified template override folder.


Can't install - Oops at step three I’m a would-be first-time Craft user. I’m trying to set up a first trial site but not having much success.

I’ve been trying to install Craft CMS on my host provider’s server. I use SmartHosting/Krystal as hosting provider.

I’ve gone through the install instructions and get as far as step three. On step three it blinks on ‘Installing Craft CMS’ for about half a second before changing to ‘Oops.’  With the circular timer beneath, it just stays on this “forever”.

When I search for this issue, there are quite a few mentions of this being a problem with Dreamhost (hosting service provider) so I have taken this up with my service provider in case it’s a similar issue. They have tried the same installation procedure on my behalf and get the same problem.  Their last reply to me is as below.

Can you help me solve my install problem?

+++++

Having spent some time on this for you I'm not entirely sure what's causing this issue. the CraftCMS system isn't outputting any PHP errors and I can't see any errors on the server logs either. Progressing this I'd have to recommend reaching out to craftcms support to find out if there's any known issues or if they can assist in debugging this issue for you.

++++

PS One possibility is that the install did work after all and the oops message is erroneous. Is there a simple way to find out if it did in fact work OK?

it was 'table already exists' and now I understand. When I first ran the installation I had guessed at the user's db priveleges (based on another CMS) as I couldnt find the Craft ones at the time. So that created the table but with the wrong privileges. Each time I subsequently ran it, it failed as the table already existed. – a1mark Oct 22 at 8:48


Get owner entry from fieldtype I have a custom fieldtype (used within Neo block) and I need to know the ID/content of entry it belongs to, when editing the entry.

I need to both populate field values based on value in other field (if present) and also perform validation on save by comparing with other fields in same entry.

So I need to know the entry content (or at least entry ID so I could fetch those) within getInputHtml and validate functions.

I know I could use $this->model and $this->element but those don't seem to provide any data related to entry

Found out that entry can be accessed with $this->element->owner


Get custom field value on entries.onBeforeSaveEntry event I am trying to get a custom field value on entries.onBeforeSaveEntry, event.  So I can perform some action depending on the value of that field.

craft()->on('entries.onBeforeSaveEntry', function(Event $event)
{
    $entry = $event->params['entry'];
    $entry->publishOnMobileApp;  //publishOnMobileApp is the field handle
});

Now this line.

$entry->publishOnMobileApp;

Returns

Craft\MultiOptionsFieldData Object (
    [_options:Craft\MultiOptionsFieldData:private] =>
Array ( [0] => Craft\OptionData Object
(
    [label] => Yes [value] => yes [selected] => )
)
   [storage:ArrayObject:private] =&gt; Array()
)

I am not sure how exactly I can access just the value of the field (which is "yes" in this case) so I can perform a check.

Please take a look at the docs it's the same in PHP as in Twig

foreach($entry->getFieldValue('publishOnMobileApp')->options as $option){
    if($option->selected){
         // $option->label is selected
    }
}


Page not found error After setting up a template file article.html in craft/templates folder, and creating the section article with the uri article and setting the entry template as article in the admin, on trying to see the Live Preview of the page when I go to it in the entries list I get a Craft page with the error:

  Page not found

I thought it might have something with cache maybe, so I cleared that, but I still got the same error. Why I am getting this error, and how can I fix that?

I restored the database backup that came with your ticket locally and created an article.html template in craft/templates and was able to load the route on the front-end of the site as well as get it to display in Live Preview.

My guess is that either 1) there's something wacky with the permissions on that file that Craft/PHP can't read it or 2) there's a .htaccess rewrite rule in your setup that's interfering with that request.


Sort entries by time part only of DateTime object I am trying to

filter and sort show entries by what time they begin
display the current show

I have two fields, startTimeand endTime, and while Craft lets me display only the time part in the Control Panel, I can't filter entries in my template by the time part only.

Listing out entries:

{% set shows = craft.entries({
    section: 'shows',
    order: 'startTime asc',
    day: 'sunday',
}) %}

Displaying the current show:

{% set nowPlaying = craft.entries({
    section: 'shows',
    startTime: '<= ' ~ rightNow | date('c'),
    endTime: '>' ~ rightNow | date('c'),
    day: rightNow | date('l'),
}) %}

If I create all my show entries on the same day, filtering by the whole date is fine, but that's assuming

the times are never changed (thus updating the date)
I don't care to know what show is currently playing (because a show will only show up if I created it today).

I prefer not to reinvent the wheel by making a template-side sorting algorithm. Is there not a more elegant way to query just the time part in Craft filtering?

For those interested, I found out you can tell Craft to search the database for the time part only with the mySQL command time() (Order entries by custom time field). For example:

{% set shows = craft.entries({
  section: 'shows',
  relatedTo: day.id,
  order: "time(startTime)",
}) %}

However, this sorts based on the absolute DB time (GMT time), so I substituted a conversion command for startTime:

{% set convertedStartTime = 'convert_tz(startTime,"+00:00","-06:00")' %}

{% set shows = craft.entries({
  section: 'shows',
  relatedTo: day.id,
  order: "time(#{convertedStartTime})",
}) %}

To my complete shock, this actually works. I could not find a similar way to search for the current show, so I first filtered entries by day, then ran a for-loop to find the current show (there's only ten shows or so per day):

{% set todaysShows = craft.entries({
  section: 'shows',
  relatedTo: today,
}) %}

{% for show in todaysShows if not done %}
    {% set start = show.startTime | date_modify('now') %}
    {% set end = show.endTime | date_modify('now') %}

    {% if now >= start and now < end %}
        {% set nowPlaying = show %}
        {% set done = true %}
    {% endif %}

  {% endfor %}`


Does Craft ActiveRecord require any special table column (dateUpdated, dateCreated,...)? I have a custom data table PA in the Craft database. I create a craft\db\ActiveRecord model and I want load() and save() data to it. The result will be custom GridView table with CRUD in front end combined with cms pages.

When I call $model->save() it throws Exception:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'dateUpdated' in 'field list'

The SQL being executed was: UPDATE `PA` SET `background`='#ffff00', `dateUpdated`='2018-10-03 11:50:26'
WHERE `idPA`=17
Error Info: Array
(
[0] => 42S22
[1] => 1054
[2] => Unknown column 'dateUpdated' in 'field list'
)

Caused by: PDOException
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'dateUpdated' in 'field list'

What is the difference between craft\db\ActiveRecord and yii\db\ActiveRecord? Is there any recommendation how to use it?

Thanks.

The only difference between Craft and Yii active records are the columns dateCreated, dateUpdated and uid if you have these columns you should extend Crafts ActiveRecord since it's save function adds compability to those columns otherwise  just use Yii2 ActiveRecord


CDbException after updating field type I've just changed a rich text field to a number field and am now unable to bring up either the front-end or the dashboard because of multiple CDbException errors. When trying to access /admin, here's the first line of the error message:

CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'content.field_sqFt' in 'field list'

I changed a rich text field named projectDescription to a number field named sqFt. I understand that the new column can't be found.

When updating a field type, I know that there's a chance for data loss. Data loss would be ok for the entries that this change would affect. But I've made other changes since my last backup that I'd like to retain if possible.

I'm running the latest Craft Pro.

Two issues here.

The first error was already a known issue:

General error: 1366 Incorrect integer value

When MySQL's strict mode is enabled, you can get errors like this when swapping an existing field from one type to another where the underlying MySQL datatypes aren't compatible. Swapping from Checkbox to Lightswitch is another time when this could occur.

That one is on our bug tracker, but it's going to be quite an involved fix, so we haven't gotten around to it yet.

The second issue is the one you found. Making the swap from one field type to another and changing the field handle at the same time would not only cause the known error to occur, it would render the rest of the control panel unusable.  That bug has been fixed for the next (post 2.4.2700) release.


filter matrix blocks by multiple light switch value, and then merge them I have a (Craft 3) matrix field with two different block types that each have a similar light switch field that I want to use to create anchor links on my page.
I need to be able to test whether any of the fields have the light switch enabled, and also loop through all of those entries.

Orignally, both light switch fields were named 'anchor', but that seemed to cause problems, so now they have two different labels. I'm having trouble combining them into a single object though, or even working with them separately in the same template:

{% set anchors = entry.pageBuilder.type('subhead').anchor('= 1') %}
{% set anchorLinks = entry.pageBuilder.type('copy').anchorLink('= 1') %}

Anchors: {{ anchors|length }}
AnchorLinks: {{ anchorLinks|length }}

If I use the code above as-is, the value of one of the objects is always 0. But if I use either of those lines indivdually, they return the proper value.

I also tried merging the two objects, but I still run into the same issue of the value of one of the objects being incorrectly set to 0.

{% set anchors2 = entry.pageBuilder.type('copy').anchorLink('1').find() %}
{% set anchors1 = entry.pageBuilder.type('subhead').anchor('1').find() %}

{% set allAnchors = anchors1|merge(anchors2) %}

one {{ anchors1|length }}
two {{ anchors2|length }}
all {{ allAnchors|length }}

{% for anchor in allAnchors %}
    {{ anchor.subhead }}
{% endfor %}

Is this a bug, or am I doing something wrong?

Keep in mind objects in PHP are always called by reference not by value thus your anchors query will always return blocks from the type subhead with the field value anchor =1 while your matrix query anchorLinks will return blocks of type copy with the field value anchor = 1 and anchorLink = 1

I'm not sure why you don't fetch the results in one single query as it would be faster and easier in my opinion but you want to create 2 queries you need to either reset the previously set property to null or use the clone  function

{% set anchors2 = clone(entry.pageBuilder).type('copy').anchorLink('1').all() %}
{% set anchors1 = clone(entry.pageBuilder).type('subhead').anchor('1').all() %}


Checked "Require a password reset on next login" on my account, can't log in anymore As a test, I checked the "Require a password reset on next login" box for my account and then logged out.

I tried logging in, expecting some sort of password reset screen, but nothing happened.

I then tried to reset my password at the login screen -- something I was able to do before -- and nothing happened.

In both cases, I get a "500 (Internal Server Error)" in the console.

Any ideas for fixing this? At the very least, can I just reset my password directly in the DB via phpMyAdmin?

FWIW, I also ran into this problem using a Craft demo site.

On your local installation if your check the "Password Reset Required" button for a user and you get a 500 Internal Server Error the next time that users logs in, there is about a 99% chance that email isn't configured/installed correctly on your server.

You can verify this by checking the craft/storage/runtime/logs files for the underlying error message.

Craft's email settings are managed under Settings->Email in the control panel.

When you tested on http://demo.buildwithcraft.com and saw the same behavior, that's because we specifically disabled all email functionality on the demo sites in order to prevent them from turning into SPAM relays.


Does a programmer have to creates meta tags? I'm the end user (not a programmer) I didn't create our website but it's been set up for me and I just use the CMS that was created for me.

Now, I'm being alerted by all kinds of website graders that I need meta tags created. I know how to do alt image tags, and the SEO section of my craft CMS has a section for SEO TITLE, SEO DESCRIPTION, and SEO KEYWORD but no where does it give me a place for meta tags...and if it did, I wouldn't know how to create one.

Do I have to have the programmer who set up my site do it?

Metadata is an important part of a website. If you are getting poor scores from website graders and don't see any place on your site to add that information it likely wasn't implemented by the team that built your site.

It's good you've noticed this and it's worth taking the time to set up a way to manage the metadata on your site. The best way to do this in a comprehensive and maintainable way is with an SEO plugin. Once you have things setup, you should no longer need the assistance of a programmer to manage the majority of your SEO needs.

For Craft, at this point in time, there are two good SEO options that are very comprehensive in the types of metadata they manage:

Sprout SEO
SEOmatic

My firm is behind Sprout SEO, so my preference is with it, but SEOmatic is made by a respectable developer who I would recommend as well so it's really a matter of your preference on which one works best for you.

With either plugin, once you have it setup, you can focus on your content and the SEO plugins will worry about generating and outputting the metadata you need on your pages. If you decide to refine or grow your SEO strategy, both plugins also have ways to give you additional control over customizing the metadata further, but that's probably something that can be left for another time in your case.

Leveraging a plugin, it will likely take a developer 2-4 hours to implement a good SEO baseline on your site. For a custom or more advanced implementation, additional planning and implementation will be required.

Please take this estimate with a grain of salt as every custom website is unique and if your original developer didn't set up any metadata that could be a signal that the rest of the project also has some non-standard things in the setup that would take the next developer more time to figure out. If you have a large site or advanced content, it can also take longer to customize metadata for special considerations, specialized content types, or your particular goals.


How to use a Structure including a homepage As far as I can tell, it's mandatory to have a Single as the site index.

I always use a Structure for organising my pages, and different entry types for different page templates. I intend to use a nav tag to output the menu. However, this time my site nav looks like this:

Homepage         (site.com/)
    Subpage 1    (site.com/subpage-1)
    Subpage 2    (site.com/subpage-2)
    Subpage 3    (site.com/subpage-3)
About            (site.com/about/)
    Subpage 4    (site.com/about/subpage-4)
    Subpage 5    (site.com/about/subpage-5)
Services         (site.com/services/)
    Subpage 6    (site.com/services/subpage-6)
    Subpage 7    (site.com/services/subpage-7)

If I have to use a Single as the home page, how do I put subpages under the home page?

Previously I've used the nav tag, and just hardcoded a link to the home page before the rest of the li's, but that's not going to work this time as the homepage has subpages.

EDIT: I've updated my sitemap to include a URL structure, which is the real challenge here.

You can place your homepage entry in a Structure by setting its slug to __home__.

Doing so causes the entry to answer for the / (empty) URI, and it even places the little "home" icon in place of the Entry's slug in the CP.

However, if you do this, its best not to nest pages under the homepage, because then their URIs would be of the form: __home__/subPageSlug

In other words, taking the pages from your example, it's best if your structure can be:

Homepage         (site.com/)
Subpage 1        (site.com/subpage-1)
Subpage 2        (site.com/subpage-2)
Subpage 3        (site.com/subpage-3)
About            (site.com/about/)
    Subpage 4    (site.com/about/subpage-4)
    Subpage 5    (site.com/about/subpage-5)
Services         (site.com/services/)
    Subpage 6    (site.com/services/subpage-6)
    Subpage 7    (site.com/services/subpage-7)

If you want the benefit of placing the homepage in the Structure, but you need to organize some pages as descendants of the homepage, you could, in theory, rig it up... But it'd get pretty janky:

Give the homepage the special __home__ slug.
Build an index template to answer for the descendant pages by finding the intended entry, setting a entry variable, and extending your regular Page template.
Create an .htaccess rule to remove the __home__ segment from a URL if anybody accidentally lands on it, to prevent duplicate content from appearing at multiple URLs.

However, there are major drawbacks to this second approach: First, you won't be able to use your entries' url() method... or, you'll have to somehow filter out the offending __home__/ segment out of the URL any time you loop through entries or use the {% nav %} tag to generate your site nav. Also, this alternative option also foils Craft's built-in slug-uniqueness checking, so if you're not careful you could end up with duplicate slugs for some pages. In general, I don't recommend it... but it's a fun thought exercise.


Variable Not Available Outside of Loop I've read that you can set a variable inside of a loop, and set that same variable outside of the loop with "" to be able to use it outside of the loop. Although when attempting this, it is not working for me. Here is the code I am using (simplified for the purpose of troubleshooting):

{% requireLogin %}

{% if currentUser == user.username %}

{# -- Set Excludes Expenses here as well, to use out of the loop -- #}
{% set excludedExpenses = "" %}

    Excluded Expenses (Outside Loop): {{ excludedExpenses }}

{{ dump(excludedExpenses) }}

    {# -- Get All Expense Entries -- #}
    {% set userExpenses = craft.entries.section('expenses').authorId(currentUser.id).limit(null) %}

        {# --- Excluded Expenses Loop -- #}
        {% for expense in userExpenses if expense.excludeExpense.contains('Temporarily Exclude') %}
            {% set excludedExpenses = expense.expenseName %}

            Excluded Expenses (Inside Loop): {{ excludedExpenses }}

{{ dump(excludedExpenses) }}

        {% endfor %}
        {# -- End Excluded Expenses Loop -- #}

{% endif %}

This is the result - http://cl.ly/image/1Z2Q2r2Q102s

The variable is only being recognized and displayed inside of the loop. The actual variable I will use (beyond this simple test) is an integer. I tested with an integer variable and that failed also, so I am not sure if that would change anything for this example. Thanks in advance for any help you can give! :)

Your dump from outside the loop is being dumped BEFORE the variable is set within the loop. Move it to after the loop and try it again.