How can I pass a variable defined in a Controller to my variables? In my Craft 3 plugin I would like to pass a variable defined in my Controller to my PluginVariable.php file. Is this possible?

The shortest answer is "that's not possible," and the slightly longer answer is "that's not possible because Controllers and Variables have no reason to ever interact." If your Controller relies on a Variable (or vice versa), something is architecturally incorrect. There's no reason for the two to cross paths.

The purpose of a Controller is to receive input from a form, AJAX call, or to be used as an API endpoint. It can also be used via routing to show a particular template under particular conditions.

The purpose of a Variable is simply to render a value in your Twig template.


Craft or Twig filter for MD5 or SHA3 hash creation? I've been digging around and haven't found an existing Twig filter for what I'm trying to do. Basically, I'd like a filter that would provide a hash of a phrase.

Pseudo-template code would be something like this:

{{ "my phrase here"|hashwithmd5 }}

And would generate this in my rendered template:

6e6d5618f8ab8a302a236eac07c59300

Does something like this exist? Am I going about this in a bad way?

sounds like a simple plugin will do the trick for you. You will need to set up your main plugin class and a variable class.

Your variable class will look something like this:

<?php
namespace Craft;

class YourPluginNameVariable
{
    public function makeHash($string)
    {
        $hashed = md5($string);
        return $hashed;
    }
}

You can call this in your templates like this:

{{craft.yourpluginname.makeHash('my phrase here')}}

Hope this helps!


How to get users with birthday today in plugin/module? How does one retrieve users from Craft3 DB whose birthday is today?

Birthdate field type is Date/Time.

Have a working PHP/MySQL example, but unsure how to port this to Craft3 syntax.

$sql = 'SELECT
            id,
            birthDate
         FROM
            !
         WHERE
            status = ?';

$users = $db->getAll($sql, array( USERS_TABLE,
                                  'active',
                                  date('j'),
                                  date('n')
                                )
                    );

Craft plugin

$users = \craft\elements\User::find()
           ->group('siteUsers')
           ->status('active')
           ->all();

Was able to get the results I needed by using the following query:

        $users = \craft\elements\User::find()
            ->where("extract(day from content.field_birthdate) = " . date('j'))
            ->andWhere("extract(month from content.field_birthdate) = " . date('n'))
            ->group('siteUsers')
            ->status('active')
            ->all();


Notes field only for certain product types In my shop, I have two different kinds of products.type items and my products have variants.

For one of products type, I would like to show the note field in the cart.

My product types are:

products
options

For product type options, I don't want to show the note field.

How can I set this up?

Tried this without success.

{% for item in cart.lineItems %}
<form method="POST">
<input type="hidden" name="action" value="commerce/cart/updateLineItem">
<input type="hidden" name="lineItemId" value="{{ item.id }}">

{% if product.type('products') %}
<input class="form-control" type="text" placeholder="Productsort"  name="note" value="{{ item.note }}" required>
{% endif %}
<input class="form-control" type="submit" class="button" value="Bijwerken"/>
</form>
{% endfor %}

I think you can do something like;

{% if product.type('products') %}
    code to show notes field
{% endif %}

See the product model docs here https://craftcommerce.com/docs/product-model

The note attribute is part of the lineitem model so you should be able to show it.

https://craftcommerce.com/docs/line-item-model#note

The following should work.

{% for item in order.lineitems %}
    {{ item.note }}
{% endfor %}

You could try naming your input field like so;

<input class="form-control" type="text" placeholder="Productsort"  name="item[note]" value="{{ item.note }}" required>

I'd need to test this though. I've done something along these lines but can't remember exactly what I did.


in a for loop, how do i only display entries of a certain category? I see a few answers that look, hopefully, way more complicated than I'm looking for. I simply want to loop through entries with a normal for loop like:

{% for entry in craft.entries.section('News').limit(1).all() %}
loop through entries of a specific category only here
{% endfor %}

Is there no way just to throw on something like .category('BreakingNews') onto that chain?

{% for entry in craft.entries.section('News').relatedTo(57).limit(1).all() %}

does work! 57 being the Category ID in this case. Thanks for the help.


How to include search results where keyword input exists only as a category title? I have a request to extend an existing "advanced search" form (multiple fields, including keyword and a categories dropdown) so that entries with a category that matches the keyword input are returned.

For example, let's say my entries are all book authors, and among various entry fields like their bio and their published books, there's also a Topic category, and authors may be associated with 0-n categories.

And let's say I have an author Jane Smith, and one of her selected Topic categories is Poetry, but for some reason the word "poetry" does not exist in her bio or any of her book titles or for that matter anywhere at all in her main entry, but rather only as that category selection.

How would I modify my search so that anyone typing "poetry" into the keyword search field (rather than picking it from the Topics dropdown menu field) will get back Jane Smith as one of their results?

Still pretty new to Craft, but I feel like there has to be some way. If not via clever query construction on the results template, then maybe by some kind of way to automatically replicate the text of the author's topic categories into an entry field that's never displayed to users, just only exists to get that text into a place where it's picked up by the search index? Would be grateful for any thoughts. Thanks.

Existing search (this is followed by a bunch more Twig that merges these results with results of other entry types but I don't know that any of that is relevant here):

{% set profileParams = {
    section: 'profiles',
    search: {
        query: 'title:' ~ query ~ ' OR ' ~
                     'position:' ~ query ~ ' OR ' ~
                     'jobTitle:' ~ query ~ ' OR ' ~
                     'institution:' ~ query,
        subLeft: true,
        subRight: true
    },
    order: 'score',
    limit: null
} %}

[...]

{% set profileEntries = craft.entries( profileParams ) %}

It's hard to say how you could include it since we don't know the rest of your search. Generally the best idea to search is with php and not with twig but you could grab all categories with the title (or whatever field it should be) with

{% set categoryIds = craft.categories.title("Your search term").ids() %}

Then you can fetch all entries that are related to these categories with

{% set entries = craft.entries.relatedTo(categoryIds).find() %}

However: if you just follow this example category titles are included in your search.


How to re-generate titles for all entries in a section? Having changed the format of a Dynamic Entry Title, how do I get Craft to re-generate them all? I thought a background task would take care of it but nothing happens.

My understanding is that dynamic titles only get updated whenever an entry is saved — so without using a plugin you would have to re-save them each manually. If you wanted to automate this process in a plugin, you would use something like this.

public function updateMySectionTitles()
{
    $criteria = craft()->elements->getCriteria(ElementType::Entry);
    $criteria->section = 'mySection';
    $entries = craft()->elements->findElements($criteria);
    foreach ($entries as $entry) {
        craft()->entries->saveEntry($entry);
    }
}

Untested (if anyone sees an error please comment). Also, keep in mind, this might only update the current locale — I'm not sure. You'll need to test, and modify if needed. You could also potentially add this is as a custom command to the amcommand plugin for easy access.


you cannot access the CP with that account New user has activated account but is getting this message when trying to log in: "you cannot access the CP with that account"

If a user gets that message when logging in, then it means they haven't been assigned the "Access the CP" permissions in the Control Panel, either directly or through a User Group that they belong to.


How to set a field of an asset from within a plugin I am using the following code to save an asset that has been downloaded to the storage/runtime/temp directory from an external API

$response = craft()->assets->insertFileByLocalPath(
    $tempPath,
    $photo['FileName'],
    $folderId,
    AssetConflictResolution::Replace
);

// if the response is a success, get the file id
if ($response && $response->isSuccess()) {
    $fileIds[] = $response->getDataItem('fileId');
}

In this example $photo[] array is the response from the api with all photo information. What I need to do is also save $photo['PhotoId'] to a field I have setup on the photo asset source in Craft.

I can't however find an example of how to achieve this. Does anyone know how?

To save a custom field value on an Asset, you'll first need to pull the actual AssetFileModel, set the custom attribute on the Asset's ContentModel, and finally re-save the Asset.

The following example assumes you've set a field photoId on your asset source:

$fileId = $response->getDataItem('fileId');
$asset = craft()->assets->getFileById($fileId);
$asset->getContent()->setAttribute('photoId', $photo['PhotoId']);
$success = craft()->assets->storeFile($asset);


Set return URL after password is set When I add a new user in the admin area, they get a link to activate their account. On the screen that link goes to, they are prompted to set a password. After the password is submitted, they are returned to /dashboard. How do I alter that return? I have the following config variables set

'useEmailAsUsername' => true,
'autoLoginAfterAccountActivation' => true,
'activateAccountSuccessPath' => 'members/index',

Solved this by

creating the Set Password form in a template with the correct
return
setting it's path with setPasswordPath
setting a path for    setPasswordSuccessPath to catch forgot password
resets


Saving to user's custom field I am using saveUser and i am trying to save a value to a user's custom field.

        $userModel = new UserModel();
        $userModel->mycustomfield = 'test value';
        craft()->users->saveUser($userModel);

This is what i have so far.

I am getting this error:

Internal Server Error
Property "Craft\UserModel.mycustomfield" is not defined.

How do i save to a custom user field?

EDIT

Also tried:

        $user = craft()->userSession->getUser();
        $userModel = new UserModel();
        $userModel->id = $user->id;
        $userModel->getContent()->setAttributes(array(
            'mycustomfield' => 'my field value'
        ));
        craft()->users->saveUser($userModel);

No error, doesnt save either.

EDIT

$userModel->getContent()->mycustomfield = 'my value';

No error, doesnt save.

SOLUTION

    $user = craft()->userSession->getUser();
    $userModel = new UserModel();
    $userModel->id = $user->id;
    $userModel->username = $user->username;
    $userModel->email = $user->email;
    $userModel->password = '';
    $userModel->getContent()->mycustomfield = 'my custom value';
    $success = craft()->users->saveUser($userModel);
    if (!craft()->users->saveUser($userModel))
    {
        $errors = $userModel->getErrors();
    }

It's probably a validation error.  Use this to check if there are any.

$userModel->getContent()->setAttributes(array(
    'mycustomfield' => 'my field value'
));

if (!craft()->users->saveUser($userModel))
{
    $errors = $userModel->getErrors();
}


How to display the parent category on an entry page? I have a simple Craft 3 website, with products that are organised in categories.

Can someone please tell me how to do the following:

On the the individual product pages (_entry.html) display a 'breadcrumb' menu that includes the parent category name/url (I've followed the few examples posted here - they don't work).

And also be able to simply display the name of the parent category of the product in text (e.g. to use as part of the h1 title for the product page).

Many thanks for your help - it is very much appreciated!

Assuming your categories are accessible from a Categories field called 'productCategory', and you only have 1 category assigned to each product, you can display the name of the parent category with:

{{ entry.productCategory.one() }}

Or you can loop through multiple Categories with:

{% for category in entry.productCategory.all() %}
    {{ category.title }}
{% endfor %}

And to get the category link for your breadcrumb, you could use something like:

{{ entry.productCategory.one().slug }}


Database Exception: Column not found: 1054 Unknown column 'position' in 'order clause' I deployed the project from the git repository on hosting. When trying to open the homepage I get the following error:

Database Exception
    SQLSTATE[42S22]: Column not found: 1054 Unknown column 'position' in 'order clause'
The SQL being executed was: SELECT `elements`.`id`, `elements`.`fieldLayoutId`, `elements`.`uid`, `elements`.`enabled`, `elements`.`archived`, `elements`.`dateCreated`, `elements`.`dateUpdated`, `elements_sites`.`slug`, `elements_sites`.`siteId`, `elements_sites`.`enabled` AS `enabledForSite`, `elements_sites`.`uri`, `categories`.`groupId`, `content`.`id` AS `contentId`, `content`.`title`, `structureelements`.`root`, `structureelements`.`lft`, `structureelements`.`rgt`, `structureelements`.`level`, `structureelements`.`structureId`
FROM (SELECT `elements`.`id` AS `elementsId`, `elements_sites`.`id` AS `elementsSitesId`, `content`.`id` AS `contentId`, `structureelements`.`structureId`
FROM `elements` `elements`
INNER JOIN `categories` `categories` ON `categories`.`id` = `elements`.`id`
INNER JOIN `elements_sites` `elements_sites` ON `elements_sites`.`elementId` = `elements`.`id`
INNER JOIN `content` `content` ON (`content`.`elementId` = `elements`.`id`) AND (`content`.`siteId` = `elements_sites`.`siteId`)
LEFT JOIN `structureelements` `structureelements` ON (`structureelements`.`elementId` = `elements`.`id`) AND (EXISTS (SELECT *
FROM `structures`
WHERE (`id` = `structureelements`.`structureId`) AND (`dateDeleted` IS NULL)))
WHERE (`elements_sites`.`siteId`='1') AND (`elements`.`archived`=FALSE) AND (`elements`.`enabled`=TRUE) AND (`elements`.`dateDeleted` IS NULL) AND (`elements_sites`.`enabled`=TRUE) AND (`structureelements`.`level`='2') AND (`elements`.`draftId` IS NULL) AND (`elements`.`revisionId` IS NULL)
ORDER BY `position`) `subquery`
INNER JOIN `categories` `categories` ON `categories`.`id` = `subquery`.`elementsId`
INNER JOIN `elements` `elements` ON `elements`.`id` = `subquery`.`elementsId`
INNER JOIN `elements_sites` `elements_sites` ON `elements_sites`.`id` = `subquery`.`elementsSitesId`
INNER JOIN `content` `content` ON `content`.`id` = `subquery`.`contentId`
LEFT JOIN `structureelements` `structureelements` ON (`structureelements`.`elementId` = `subquery`.`elementsId`) AND (`structureelements`.`structureId` = `subquery`.`structureId`)
ORDER BY `position`

But the admin page opens without errors.
And when I run a project on a local machine, there is no such error.
What can i do to fix this problem?

Command ./craft migrate/all fixed this issue.


Trouble with transliteration in slug caused by hardcoded charmap in craft.js I've been struggling with automatic slug generation in Czech language: there are letters such as "š" or "č" and Craft has a charactere map hardcoded in craft/app/resources/js/craft.js, resp. craft/app/resources/js/compressed/craft.js, which tells craft to convert "š" to "sh" and "č" to "zh" for instance.

In Czech language that is not necessary; it's rather bad behavior which I need to change. Letter "š" should become "s" etc.

Is there any systematic way how to configure this character map?

I technically have no problems with rewriting the table, although that solution might either cause errors with automatic updates or my changes could get rolled back with every update - neither being good.

PS: This issue is NOT related to the same thing as here: How to transform German umlauts when creating slugs? - the described behavior is in place even with "limitAutoSlugsToAscii == 1"

UPDATE:

In case this question was not resolved yet or had no solution, here is a minified charmap which works as a hotfix to Craft issues with Czech slugs: http://pastebin.com/pc6etBFu

It works as a drop-in replacement for the same map in craft/app/resources/js/compressed/craft.js. My current version of craft is Craft Pro 2.3.2643

You can try using my plugin, which will overwrite the character map in craft.js by applying the customAsciiCharMappings setting:

https://github.com/farmstudio/slugcharmap

Tell me if it's working for you.


Incorrect content/mime-type on S3 SVG upload I've setup an S3 asset source for images and it's working well for everything but SVGs.

SVGs are uploaded with the default content-type of binary/octet-stream where the correct content-type would be image/svg+xml.

Am I doing something wrong or is this a bug?

Your SVG file is probably missing the the XML declaration at the top (<?xml version="1.0" encoding="UTF-8"?>). PHP's FileInfo detects XML files (which SVG is) without that declaration as text/html files.

Lots of SVG editors/exporters will (annoyingly) omit that.


“Access Plugin” doesn't appear in Permissions list Non-admin users are not able to access my plugin in the CP. With admin rights, everything is fine—the templates are accessible, but all the other users are getting 403.

I've tried to build the plugin based on Craft 3 best practices and used:

EVENT_REGISTER_CP_NAV_ITEMS - to register nav items

EVENT_REGISTER_CP_URL_RULES - to register url rules like this:

$event->rules['plugin-name'] =  ['template' => 'plugin-handle/index'];

What am I missing?

Should I add / register something else in the plugin's init()?

The permission checkbox for the plugin doesn't even show up in User(Group) Permissions.

I'm not using controllers because routing to templates are working fine and seems to be enough. Is that a problem?

If your plugin has a CP section (specifically, the main Plugin class declares a $hasCpSection property, and it’s set to true), you should get an “Access My Plugin Name” option near the top of the permissions list—this might be enough to grant access to your plugin's controllers. See how this is enforced, here.

If you want to use more granular permissions, you'll have to check that box, plus anything you register via the UserPermissions::EVENT_REGISTER_PERMISSIONS event. Here's an example of that being done in a stripped-down main plugin class:

<?php

use Craft;

use craft\base\Plugin as BasePlugin;
use craft\events\RegisterUserPermissionsEvent;
use craft\services\UserPermissions;

use yii\base\Event;

class MyPlugin extends BasePlugin {
    // ...

    public function init()
    {
        Event::on(
            UserPermissions::class,
            UserPermissions::EVENT_REGISTER_PERMISSIONS,
            function (RegisterUserPermissionsEvent $event) {
                // Each "group" is just a key in the Permissions array, and you can have
                $event->permissions[Craft::t('my-plugin', 'My Plugin Features')] = [
                    // You might have discrete feature permissions, or different ones for `access` vs `modify`:
                    'my-plugin-access-first-feature' => [
                        'label' => Craft::t('my-plugin', 'Can Access Feature A')
                        // You can also use the `nested` key here to group permissions!
                    ],
                    'my-plugin-access-second-feature' => [
                        'label' => Craft::t('my-plugin', 'Can Access Feature B')
                    ]
                ];
            });
    }

    // ...
}

In a controller action, you can call $this->requirePermission('my-plugin-access-first-feature'); to lock down access.

  Also worth noting: Some plugins (like Commerce) use a few abstract controller definitions (i.e. BaseController, BaseCpController, BaseAdminController) to lock down entire bundles of functionality. If you're using this paradigm, you won't be able to easily relax permissions—only tighten—enforced by the parent Controller.


Sprout Form submit: The CSRF token could not be verified! I have a form created by Sprout Forms, which results in an error when submitted:

The CSRF token could not be verified!

Here is the log:

2016/06/09 11:06:17 [error] [exception.Craft\HttpException.400] exception 'Craft\HttpException' with message 'The CSRF token could not be verified.' in /home/forge/www.fira.co.uk/craft/app/services/HttpRequestService.php:1314
Stack trace:
#0 /home/forge/www.fira.co.uk/craft/app/framework/base/CComponent.php(561): Craft\HttpRequestService->validateCsrfToken(Object(CEvent))
#1 /home/forge/www.fira.co.uk/craft/app/framework/base/CApplication.php(212): CComponent->raiseEvent('onBeginRequest', Object(CEvent))
#2 /home/forge/www.fira.co.uk/craft/app/framework/base/CApplication.php(183): CApplication->onBeginRequest(Object(CEvent))
#3 /home/forge/www.fira.co.uk/craft/app/index.php(62): CApplication->run()
#4 /home/forge/www.fira.co.uk/public/index.php(19): require_once('/home/forge/www...')
#5 {main}
REQUEST_URI=/publications/industry-statistics
HTTP_REFERER=http://www.fira.co.uk/publications/industry-statistics

The form code in the template was wrapped in a {% cache %} tag.


Odd error message when editing field settings (Variable "targetLocaleFieldHtml" does not exist) After upgrading a site from 2.4.x to 2.6.x, I'm experiencing an odd issue where Craft throws the following template error whenever I attempt to edit a field:

Variable "targetLocaleFieldHtml" does not exist

The error message only displays if devMode is set to true, occurs for all fields and fieldtypes (also when attempting to create a new field), and prevents me from actually editing field settings (unless I turn off devMode).

Here's the full stack trace:

Template Error

Variable "targetLocaleFieldHtml" does not exist

/somepath/craft/app/templates/_components/fieldtypes/elementfieldsettings.html(33)

21                     options: sources,
22                     value: settings.source
23                 }) }}
24             {% endif %}
25         {% else %}
26             {{ forms.field({
27                 label: (allowMultipleSources ? "Sources"|t : "Source"|t)
28             }, '
' ~ "No sources exist yet."|t ~ '
') }}
29         {% endif %}
30     {% endblock %}
31
32     {% block targetLocaleField %}
33         {{ targetLocaleFieldHtml|raw }}
34     {% endblock %}
35
36     {% block limitField %}
37         {% if allowLimit %}
38             {{ forms.textField({
39                 label: "Limit"|t,
40                 instructions: "Limit the number of selectable {type}."|t({ type: type|lower }),
41                 id: 'limit',
42                 name: 'limit',
43                 value: settings.limit,
44                 size: 2,
45                 errors: settings.getErrors('limit')
2016-06-06 18:44:40 Apache / Craft 2.6.2789

This had me stumped for a while, but it turned out to be a custom fieldtype extending BaseElementFieldType, in which the settings attribute targetLocaleField apparently was renamed targetLocaleFieldHtml with Craft 2.5.2750.

Not sure why the error was thrown for all fields and fieldtypes (even PlainText fields), but in any case the fix was simply replacing the targetLocaleField attribute with targetLocaleFieldHtml in the returned array for the getSettingsHtml() method in the custom fieldtype.

Edit: It just occurred to me that the reason for getting the error on all fields/fieldtypes is – of course – due to Craft actually pre-rendering the settings templates for all fieldtypes, I assume to make changing the fieldtype (via the dropdown) seamless/instantaneous.


How can I pass a Craft Field into a JavaScript function? I have a chart generated in script.

{
    "country": "China",
    "visits": 1882,
    "color": "#FF6600"
},

This is what I want to do (and I know this is not correct).

{
    "country": "{{ entry.country }}",
    "visits": {{ entry.visits }},
    "color": "#FF6600"
},

What do I need to do?

Is the JavaScript inline in your template file? e.g. using {% includeJs %} or even just a <script> tag? If so you should be able to do it as you suggested by outputting Craft variables directly into the JavaScript within your template.

If the function is in an external script, you could call a function from within your template, something along these lines:

{% includeJsFile "/path/to/myfile.js" %}
{% set myJs %}
   myFunction('{{entry.country}}','{{entry.visits}}');
{% endset %}
{% includeJs myJs %}

And then in your JS file you can have something like

function myfunction(country, visits){
   //do something
}


Solspace FreeForm assign notifications recipient in entry I've got a client who would like to be able to assign a notification recipient for each entry where a form appears. I would imagine that a new form needs to be created for each recipient, but is there a way to take the form handle, add it to an entry then output that form on a page? Or is there a better way to do it?

Not sure if I understood the question correctly but why don't you make use of the Freeform Forms Field if you want to attach a form per entry.

{% if entry.myFreeformfieldname is defined and entry.myFreeformfieldname is not empty %}
    <h3>{{ entry.myFreeformfieldname.name }}</h3>
    {{ entry.myFreeformfieldname.render() }}
{% endif %}


Generic catch-all error template Is there a catch all error page template?

I'd like to use http://http.cat for my statuses.

(originally asked by Bryan Redeagle in Craft Slack)

Yes — an error.twig template in your error templates directory serves as a catch-all template when a more specific template (e.g. 404.twig) can't be found, or when the system throws a general error that doesn't have a status code attached.

(You can customize the path prefix for error templates by changing the errorTemplatePrefix setting in the Craft General Config.)


Updating matrix field from font-end with $entry->setFieldValue() pulls in Cp bundle on save I have an entry with a matrix field which I'm updating from front-end. The update works fine, but when the (font-end) page reloads after submitting the form, the CP bundle assets get included (selectize.css, craft.css, charts.css). If I then reload the page, the CP assets are no longer included. I believe have narrowed it down to the use of $entry->setFieldValue(). Does anyone know why that's happening and how to stop it? Or is there a different way to update an entry with a matrix field from font-end that doesn't require me to use setFieldValue()?

Here's the relevant part of my update function:

$field = Craft::$app->getFields()->getFieldByHandle('fieldHandle');
$existingMatrixQuery = $entry->getFieldValue('fieldHandle');

$serializedMatrix = $field->serializeValue($existingMatrixQuery, $entry);
$serializedMatrix['new1'] = [
    'type' => 'update',
    'enabled' => 1,
    'collapsed' => true,
    'fields' => array_merge($params['fields'], $params['required'])
];
$entry->setFieldValue('fieldHandle', $serializedMatrix);

if (Craft::$app->getElements()->saveElement($entry)) {
    return true;
}

Turns our it was this line causing the issue:

'collapsed' => true,

Removed it and all works as expected.


Craft updater still spinning after at least half an hour--no error message I hadn't updated site in a while now. Checked Craft's control panel and something like 12 updates were available and i clicked update. "Updating Composer dependencies (this may take a minute)…" has been on display for over half an hour, maybe an hour, and the activity spinner just keeps spinning. No error report or any feedback. I'm reluctant to stop the process as the site is currently unavailable due to this situation.

If you have ssh access to your remote server you might be better off just updating composer via command line. I find it's ofter faster and less prone to causing errors by updating composer and craft this way.

Let me know if you need help doing that.


Image transforms return cpresources URL and doesn't apply crop Despite having tried the tips from Image transforms returning cpresources url, I am still having issues with image-transforms.

the problem is when i put the image without transform it work fine, but when i add the transform parametre it vanish, and even i tried to apply transfom in the template, the image show up but without crop option, only adjust the width and height in the front.

I have tried clearing the cache and db table already as well as updating the asset index. I have double checked the sources paths and it is not a file permission issue.

I am running Craft Pro 2.6.2992

'generateTransformsBeforePageLoad' => true is set in craft/config/general.php

template-code :

          {% set  blocWith = "large-12" %}
          {% if block.image.first.url is defined %}
          {% set imageUrl = block.image.first.getUrl('imagewidthlarge') %}
          {% set imageHeight = block.image.first.getHeight('imagewidthlarge') %}
          {% set imageWidth = block.image.first.getWidth('imagewidthlarge') %}

      {% endif %}

                {% if block.heading is not empty %}
{{ block.heading }}
{% endif %}
                {% if block.subtitle is not empty %}
{{ block.subtitle }}
{% endif %}
                {{ include(template_from_string(block.text)|raw) }}

this is what the page-source looks like

vu front :

please i'm on a deadline on this projects i tryied all i could to work it out but still, i need this image transform to work

I did find the solution i checked the basepath with the server hosting my project and it turned out that the relative path dosen't work like the absolute path, so i serached for the root in the server and i inserted the full path, it work !! thanks for letting me know this by myself :)


Website not indexing Not sure what is going on but my website is not getting indexed by google (went live last week). Robots is correct. What am I missing here?

I'm using the plugin seomatic for the SEO, Site robots meta tag has index, follow.

Site is: http://gastro-on-fire.be

You need to tell Google that you have a new site or the best SEO in the world won't matter a jot; Google has no idea your site exists until you tell it.

There are 4 essential steps to getting your site indexed:

Add your URL – Submit your website for inclusion in Google's index.
App crawling – Get your app indexed by Google.
Search Console – Submit a Sitemap of your website to Google.
Structured data – Label your structured content to help users find pages relevant to their search.

These steps, and more, are detailed here.

Edit: I've taken another quick look at your site and I think you may be sending Google mixed signals about what to index.

You said your site is http://gastro-on-fire.be but that re-directs to https://gastro-on-fire.be -- These are two different sites.
Both sites are accessible also at the www subdomain, so you have actually 4 sites, which one do you want to index? Pick one, and follow Google's advice for that one. Add the others in Webmaster tools but set tell Google which is your preferred one, which one it should index.
Ensure your seo strategy is inline, and remains in line with that choice. Currently, the sitemap at https://gastro-on-fire.be/sitemap.xml gives all the site links as the www version; so you're telling Google to crawl the www site instead!!

Which one do you want to be indexed? Pick one, and ensure everything you tell Google backs up that choice.


Loop through entries that share current entry category and restrict to Cat Group Id I've been racking my brains trying to get my head around categories and entries, hopefully someone can help and show me the best way.

I have an entry page with product information and this product is assigned to multiple categories across multiple groups. I need to exclude the category 'preferential' and only show entries that belong to the category group 'offers'.

Here's what I've got so far:

{% set categories = craft.categories.relatedTo(entry) %}
{% set excludeCat = craft.categories.slug('preferential').first() %}

{% set allIds = [] %}
{% for id in categories.ids() if id != excludeCat.id %}
    {% set allIds = allIds|merge([id]) %}
{% endfor %}

{% set entries = craft.entries.relatedTo(allIds) %}

{% for offer in entries %}
    {{ offer.title }}

{% endfor %}

I've tried variations of 'group', 'ids' and 'groupId' but no joy. This is my first Craft CMS build so still learning.

Thanks!

You can make use of 'not' to exclude items from your parameters. An example of how this would be implemented in the above use case would be as follows

{% set categories = craft.categories.slug( 'not preferential' ) %}
{% set entries = craft.entries.relatedTo( categories ) %}

If you need to specify category groups or entry sections then use

{% set categories = craft.categories.group( 'groupHandle' ).slug( 'not preferential' ) %}
{% set entries = craft.entries.section( 'sectionHandle' ).relatedTo( categories ) %}


Display entries related to Category Field I'm sorry If this has been answered before, but I couldn't find any answer that would work for me. Maybe I'm just treating category fields the wrong way and I should be trying to do this with tags.

Basically, I created a category group called colors. I also have several categories like green, blue, red...
I assigned URLs that look like mysite/colors/red, mysite/colors/blue.

All of the colors point to the same template colors/index.html

How can I display only the entries in craft.entries.section('news') that are in the "red" color category when I visit mysite/colors/red?

Thanks in advance.

You want to use the relatedTo filter. See the docs here: https://craftcms.com/support/entries-related-to-category where category is your last URL segment (eg red).

Just a quick addition... if your category URL for the category group matches what you've used above mysite/colors/red and you are using the category template for that group then you will have a category variable already to use in the relatedTo filter.


Custom Newsletter template I'm trying to create an email newsletter template to make it easier to send out blog newsletters by looping over entries and generating the email straight out of craft. I did this often with Wordpress.

However I'm getting twig syntax errors because of the inline CSS. I know you can do this <style>{{ source('file.css') }}</style> but that's not going to cut it for all the tables I need to add inline CSS to.

Am I missing a Twig filter that I could wrap all my HTML code it?

Just to be clear I am only trying to generate, not send the email newsletter through Craft.

You can include standard HTML in Twig templates. So something like this would work:

You don't have to use Twig filters to add CSS or CSS files. Although you could create some CSS variables using {% set gray = '#eee' %} or {% set border = 'border: 1px solid black' %} for repeated styles such as colors, borders, etc., and then reference those like this, using the variable name:


I would like to implement the remarketing tag into my website I was wondering if anybody can help me with the implementation of the remarketing tag into my site. I have the codes and I just don't know where to enter them.

I assume you're asking about AdWords?

Forgive me if I need to ask this but who developed your website? It sounds like you need to have your developer add that bit to the website's code. (If you're actually a developer and I'm talking under your knowledge, go ahead and modify your question!)

Otherwise, if have access to ftp or some other form of modifying files on your server, you can add it yourself. (Before you modify any file, make a duplicate copy in case you have to go back.)

The exact place is going to depend on your templates, located in the craft/templates/ and likely in the _layout.html (or some other file like header.html or footer.html).

If you're running Google Analytics (which is a safe bet, since you're using AdWords), the easiest way to do it would be to add a line to your GA tracking code which probably is already installed.  Just look for ga('send', 'pageview'); and add ga('require', 'displayfeatures'); right above that, as in the example given on the page (assuming you're using their newer Universal code).


Craft 2.5 plugin sub navigation icons I notice that you can add icons for your sub navigation. However looking at the template for the subnav loop there isn't any markup to render that icon. Anyone know if this is coming in the future or missing code?

Example pulled from Craft Commerce plugin

$context['subnav']['settings'] = array('icon' => 'settings', 'label' => Craft::t('Settings'), 'url' => 'commerce/settings');

Not actually possible. That icon key is not being used anywhere – just a remnant from a past feature idea that didn’t make it into Craft 2.5. (I just removed it for the next release.)


Get currentSite.handle in Element API I need to get the currentSite in Element API. How can this be achieved? Is it as a slug in the endpoint URL? or as a Query param? Here is the current code:
<?php

use craft\elements\Entry;
use craft\helpers\UrlHelper;
use craft\services\Sites;

return [
    'defaults' => [
        'resourceKey' => 'suggestions',
        'cache' => false,
        'paginate' => false,
        'pretty' => true,
    ],
    'endpoints' => [
        'api/search.json' => function() {

        $searchQuery = Craft::$app->request->getQueryParam('query');
        $site = Craft::$app->request->getQueryParam('site');

        $sectionHandles = [
            'pages',
            'news',
        ];

        // Search criterias
        $criteria = [
            'section' => $sectionHandles,
            'search' => $searchQuery,
            'site' => $site,
            'orderBy' => 'score',
            'limit' => 10,
        ];

            return [
                'elementType' => Entry::class,
                'criteria' => $criteria,
                'paginate' => false,

            'transformer' => function(craft\elements\Entry $entry) {

                return [
                    'title' => $entry->title,
                    'url' => $entry->url,
                ];
            },

            ];
        },
    ]
];

The currentSite property from the Sites service is what you're looking for. Here's how you would use it:
'api/search.json' => function() {

    $siteHandle = Craft::$app->getSites()->currentSite->handle;

    ...

    $criteria = [
        'site' => $siteHandle,
        ...
    ];

    return [
        ...
    ];
},


I am unable to correctly return the url of an uploaded asset I'm a newcomer to Craft from the far-off lands of WordPress. I hope my stay is long and fruitful, but at the moment that prospect is in danger. The problem I'm having must be embarrassingly simple, but I can't find my way through it.

The simple task I am attempting to accomplish it to display an image I uploaded to an entry via a new asset field.

If there is a method or practice for displaying an image via asset fields found on the internet, I have tried it. Currently, this is how I am trying to render the image in my twig file:

{% for image in entry.featuredImage %}
    <img src="{{ image.url }}" alt="blah">
{% endfor %}

No image shows up.

When I dump(image), should it be returning an array with 666 lines? I understand an asset returns a kind of Asset File Model (although I don't entirely understand what that means), but I find it hard to believe it's supposed to be that large.

Hoping to find at least the url of the asset, I perform dump(image.url), but it only returns bool(false). Why would it be doing that?

I created my uploads directory, and setup my asset source. I've tried doing this on an entirely fresh, up-to-date and clean install, but it still behaves the same way.

What am I missing or doing wrong?

Thank you!

I found the answer in a similar post here: Image asset url is not being output

My problem was with my Asset Source settings. Now that I think about it, it's obvious: I had no public URL declared for assets from my 'Uploads' source. Giving that a public url fixed the problem.

As I said, it's obvious now, but it'd be nice in the documentation could make even just a small reference to this.


getHeadHtml() not outputting CSS included with {% includeCss %} I think there is a bug in the getHeadHtml function of craft. In the Documentation (https://craftcms.com/docs/templating/includecss) it says:

  Your CSS snippet will be output by the getHeadHtml() function. If you aren’t calling that function anywhere, Craft will insert it right before the HTML’s < /head> tag.

But in my templates it works only, if the tag getHeadHtml() is placed after the includeCss Tag.
So the following simple Example does not work as expected:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Title</title>
    <!-- Here should the CSS start -->
        {{ getHeadHtml() }}
    <!-- Here should the CSS end -->
  </head>
  <body>

      {% set myCss %}
        .content {
            color:  red;
        }
      {% endset %}

      {% includeCss myCss %}

  </body>
</html>

It outputs the following code:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Title</title>
    <!-- Here should the CSS start -->

    <!-- Here should the CSS end -->
  <style type="text/css">
  .content {
            color:  red;
        }
  </style></head>
  <body>
  </body>
</html>

It outputs the CSS before the closing < /head> Tag and not between the two comments. Is there any workaround/fix for this?

This is just an order of operations issue. The documentation is correct, but incomplete.

getHeadHtml() will only output head HTML that was queued up for it before the function was actually called. Any head HTML that is queued up after you've called getHeadHtml() will end up getting inserted in the default location - right before the </head> tag.

So, if you had this in your template instead:

{% includecss %}
  .content {
      color:  red;
  }
{% endincludecss %}

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Title</title>
    <!-- Here should the CSS start -->
        {{ getHeadHtml() }}
    <!-- Here should the CSS end -->
  </head>
  <body>

  </body>
</html>

Then the CSS would get included between the HTML comments as you’d expect.


Is it possible for photo's to be uploaded to a form? I would like to create a form for competition entries. However, there needs to be the option for entrants to upload pictures with their entry form, is this possible?

Many thanks

As mentioned in Oli's comment, there's an example of how to do this in the documentation: https://docs.craftcms.com/v3/assets-fields.html#uploading-files-from-front-end-entry-forms


Stuck when grouping entries to get any other parameters like url, id etc So I am trying to group entries by location and then group entries in this group by weekday.
I have this aspect working with the following code:

{% set allClasses = craft.entries
  .section('tuitionClasses')
  .relatedTo({
  targetElement: entry,
  field: 'tuitionCourse'
})
  .all() %}

{% set allEntriesByLocation = allClasses|group(e => e.location.one.title) %}

    {% for location, entriesInLocation in allEntriesByLocation %}

        <button
          class="focus:outline-none p-4 px-6"
          :class="{ 'text-pink-600': tab === '{{ loop.index }}' }"
          @click="tab = '{{ loop.index }}'"
        >

{{ location }}

        </button>

    {% endfor %}

  {% for location, entriesInLocation in allEntriesByLocation %}

      {#
{{ location }}
#}

      {% set locEntriesByWeekday = entriesInLocation|group(i => i.weekday) %}

        {% for weekday, entriesForWeekday in locEntriesByWeekday %}

{{ weekday }}

              {% for class in entriesForWeekday %}

                  {{ svg('@icons/bx/bx-time.svg', class="w-5 h-5 mr-1 flex-shrink-0 fill-current") }}
                  {{ class.classTime.one.title }}

              {% endfor %}

        {% endfor %}

        <button
          @click="html='loading...'; showLoading = true; showModal = !showModal;
              fetch('{{ entry.url }}', {
                method: 'GET',
                headers: {
                'X-Requested-With': 'XMLHttpRequest',
                },
              })
              .then(response => response.text())
                .then(text => {
                html = text
                showLoading = false;
              })"
          class="flex items-center justify-end text-left"
        >

            {{ svg('@icons/bx-solid/bxs-map.svg', class="p-px w-full h-full flex-shrink-0 fill-current") }}

            {{ location.url() }}

              Map and Directions

        </button>

However, where I am stuck is accessing the url for the locations.
I have a button that should load the location page into a modal when clicked.

However, when I try {{ location.url() }} I get the following error.

Impossible to invoke a method ("url") on a string variable ("Hatch End").

So How can I get any other element details of the location via this approach?
Or is there a different approach I need to take?

Thanks.

The group filter creates an associative array so the location Twig var in your loops is the array item key, which is a string.

I think you'll have to get the location object that's related to the entry you're currently working with in the loop in order to access its URL. Maybe try setting the location object to a variable by adding something like {% set locationObj = entriesInLocation[0].location.one() %} right after {% for location, entriesInLocation in allEntriesByLocation %}. Then, you should be able to access the location URL using {{ locationObj.url }}.


Order entries by DATEDIFF I'm trying to order the results of an entries query by the difference between two date fields but I can't seem to get it to work.
Here is my query:
{% set todaysStreamsParams = {
  section : 'films',
  orderBy : "DATEDIFF(`screeningDateFirst`, `screeningDateLast`) DESC",
  limit   : 5,
} %}

{% set todaysStreams = craft.entries(todaysStreamsParams).all() %}

But I'm getting the following database exception:
Unknown column 'screeningDateFirst' in 'order clause.

Any tips?

Digging around a bit, it looks like more complex order queries need to be fully elaborated. I adjusted as follows for it to work:
orderBy : "DATEDIFF(`content`.`field_screeningDateFirst`, `content`.`field_screeningDateLast`) DESC",


Are there any tools for Craft similar to the Yii Code Generator? There is Yii demo tutorial at http://www.yiiframework.com/screencasts/ that uses the Yii Code Generator. Are there similar Code Generator tools in Craft?

There are third-party code generators, such as the Element Type Generator or the Craft Plugin Generator

You also have the migration tools that generate code. Using the querygen command you can output Records as db query commands.


Redactor adds  to both image and video embeds, how to style differently When video or images are embedded redactor wraps both the iframe and img tags in a .
I've been using the following css to style the iframe to maintain the ratio responsively:
figure {
    position: relative;
    padding-bottom: 56.25%; /* 16:9 */
    padding-top: 25px;
    height: 0;
    margin: .5em 0 1em 0;
}
figure iframe {
    position: absolute;
    top: 0;
    left: 0;
    width: 100% !important;
    height: 100% !important;
}

But this screws up the embedded images as I don't want the ratio stuff to apply to images.
Is there a simple way to be able differentiate the two?
I used to add a DIV class to a specific embed in CKEditor with a custom config file containing:
CKEDITOR.on( 'instanceReady', function( ev ) {
ev.editor.dataProcessor.htmlFilter.addRules({
    elements: {
        $: function (element) {
            // Add embed_media class name to embedded media
            if (element.name === 'div' && element.children[0].name === 'iframe') {
                element.attributes.class = 'embed_media';
                return element;
            }
        }
    }
});

});

It's probably not the answer you want to hear, but the best way to avoid these kind of problems is to modernise your content model so that videos are stored in their own dedicated section, and then allow authors to create relationships to those video entries via a dedicated 'video' block type in a content matrix. Similar for images really (though it is arguably still important to allow for inline images in Redactor such as for images in the middle of sentences). If you want to prevent Redactor from wrapping images with a figure element you can specify imageFigure: false in your Redactor config json files.
If you can't update your content model easily, then as a last resort you might need to delve into the Retcon plugin to manipulate Redactor's output.


List applied discounts that have codes So on a cart page, I need to list out the discounts that have been applied to a cart. I need to list them one by one, but only discounts that are applied with a code. I'm having trouble figuring out how to get the discount code, and I need to output the code. Something like this:

Item Total: $200.00
Promotional (25OFF): -$25.00
Promotional (FATHERSDAY): -$10.00
...

I'm looking over the discount info like this:

{% for discount in cart.adjustments %}
    {{ dump(discount) }}
    <br>
{% endfor %}

I don't see an accessible code variable jumping out at me. The only places I can see pulling it is from the optionsJson string, but that is not practical as Twig doesn't have a default JSON filter to decode.

So I can get the discount ID easily enough from that loop; but I'm not sure how to pull a Discount model based on ID. I'm not super versed with Craft and Twig, so I'm hoping there is a simple solution to look up Discounts based on discount ID.

So like this:

{% for discounts in cart.adjustments %}
    {# look up discount based on discount.id #}
        {% if discount.code | length %}
            Promotional ({{ discount.code }}): {# discount amount, probably have to do math here if it is a percentage #}
        {% endif %}
    {% endfor %}
{% endfor %}

I imagine I'm going about this wrong.

(There can be only one code on a cart at any one time)

Here's some example code that does the sort of thing you want:

{% if cart.couponCode %}
    {% set coupon = craft.commerce.getDiscountByCode(cart.couponCode) %}
{% endif %}

{% if cart.totalDiscount or coupon is not null %}

    {% for adjustment in cart.adjustments if adjustment.type == "Discount" %}
        {% set isCoupon = adjustment.optionsJson.code ? true : false %}

    Applied:

        {% if isCoupon %}

                        Coupon: {{ adjustment.optionsJson.code }}

                    {{ adjustment.description }}

            {% set couponPrinted = true %}
        {% else % }
            etc...


User profile public page I'd like to manage my users (both active site users, and other employees at my client's company) via the Craft user management. I've added more profile fields, etc. But i'm wondering, is there a built in public profile page/route for users?  I'm listing various users on a page, and i'd like their profile image to link to a profile page for each of them, with more info, contact info etc. What's the best way to do this?

You will need to add a custom route for the path for which you want to show the profile from a list of all users.

Per my example of /profile/{{ username }}:

In your profile/index template, you would run a loop on the user set of your choice:

{% set users = craft.users %}
{% for user in users %}
    {{ user }}
{% endfor %}

Craft Admin › Settings › Routes
New Route
If the URI looks like this: profile/* (Use the * token provided)
Load this template: profile/_profile

Then, in your profile/_profile template,

{% set user = craft.users.username( craft.request.segment(2) ).first() %}

Once user is defined, you can use the UserModel to return any data from that user (i.e. {{ user.email }} ).


Show value of default variant I'm trying to display the value/price of the default variant for a product.

This is what I currently have:

{% for variant in product.variants %}
  From {{ variant.price|currency(cart.currency) }}
{% endfor %}

This displays the price of every variant that a product has. How can I just display the default variant price? Or better still, the product variant with the lowest price.

You can access the default variant using {{ product.defaultVariant }}.

Because product.variants isn't an ElementCriteriaModel you can't sort it like one. You'd have to retrieve the products variants as an ElementCriteriaModel first like so:

{% set lowestPriceVariant = craft.commerce.variants({
  productId: product.id,
  order: 'variants.price'
}).first() %}

{{ lowestPriceVariant.title }}


How do you query entries by field values? I need to arbitrarily query entries based on the values of various fields.

For example, if I have an entry type called "Widgets" I can grab them like this:

$widgets = Entry::find()->section('widget')->all();

Now what if widgets have a field called "widgetColor" and I want to select all with a value of "blue" in that field?

How can I query for those entries?
Also, how can I query for any entry with no value in that field?

I've tried my best to figure it out using the documentation and it seems like method such as where only apply to certain data, such as the title and slug, which are not custom fields on the entry type.

Thanks!

You can do the same like with the section, if the query param exists in the field layout

$widgets = Entry::find()->widgetColor('blue')->text(':notempty:')->anotherField(':empty:')->section('widget')->all();

Will search for entries where widgetColor is blue, text is not empty/null and anotherField is empty/null

Edit: just for people who like to understand the behavior

Just to explain you the where parameter in the ElementQuery. The where function uses the Yii2 Query function directly and works directly at the database layer. When you take a look at your content table you'll see all custom fields have a certain prefix (if you didn't change it) so your widgetColor column will look like field_widgetColor when you do

where->(['widgetColor' => 'blue');

it will query

where `content`.`widgetColor` = `blue`

which will throw an error since the column name is field_widgetColor. The __set function in the Yii/component/ QueryBuilder class will set magic property that exists because of the field handle in your field layout... Or to keep it simple: you can access any "magic" property with the same name like an existing field handle.

Doing

->widgetColor($property)

will call the __set function that calls a wrapper that will wrap/attach the field content prefix (field_) to the where function. Thus you can use

where->(['field_widgetColor' => 'blue');

or

where->([Craft::$app->getFields()->oldFieldColumnPrefix . 'widgetColor' => 'blue');


Edit entry, on the front end, with the entries field I currently have front-end code working for a user to create an entry, add a title (text input) and also relate entries via the entries field type and checkboxes. All on a front-end application.

Creating the entry is fine, but I'm having an issue with the editing of the entry.

I'm unable/unsure how to "check" what the previously selected relate entries where. Code for showing entry items...

{% set entries = craft.entries.section('exercises') %}
{% for entry in entries %}
<li>
    <input type="checkbox" name="fields[planItems][]"
           id="fields[planItems]" value="{{ entry.id }}">{{ entry.title }}
</li>

Other fields are fine such as the title field, all you have to add is {%- if entry is defined %} value="{{ entry.title }}"{% endif -%}>.

Any ideas on how to get that value so I can add checked to the previously selected entries?

Thanks!

There is a in operator to check if a variable is in a string or an array. Your entries field actually contains an object of type ElementQuery instead of an array of elements.

All you need to do is to check if the current entry is in the list of selected entries

{% set selectedEntries = entry.planItems.ids() %}

{% set entries = craft.entries.section('exercises') %}
{% for entry in entries %}
    <li>
        <input
            {% if entry.id in selectedEntries %}checked{%endif%}
            type="checkbox"
            name="fields[planItems][]"
            value="{{ entry.id }}">{{ entry.title }}
    </li>
{% endif %}


Entries relations with additional fields I'm searching for a way to have additional fields on relations.
The simplest exemple would be; you have stores entries and products entries, and you want to create a many to many relationship with the price as additional information.

How could it be done ?

Thanks in advance,

From a database point of view you would have a pivot table between stores and products. And in that pivot table you would have additional columns like the price.

Using native fields

You can‘t do that on a relation field per se. (In this case entry field, assuming that products are entries) But you could wrap a repeatable field around an entry field and a price field, e.g. matrix or table and build the relationship this way. This way you can select products from within a store entry and put a price on each product.

One caveat is that you can’t bulk select products anymore. You’d have to select them one by one.

Alternative solution

You could write a custom module where you create a new field type that solves your problem. This would not result in an actual pivot table but it would work in a similar way. As far as I know a field type's value is bound to be saved in a single database column (may be wrong). However, you could even come up with some kind of bulk editing solution if you want to, although this would require some more work.


URI for nested categories in Craft 3 I am trying to set up the URIs for some nested categories in Craft 3 but am having some issues. My structure is basically:

service-one
|-subservice-one-a
|-subservice-one-b
service-two
|-subservice-two-a
|-subservice-two-b

I have set my Category URI Format to:

what-we-do/{slug}

Which is working fine, however I would like the URI for the nested categories to look like:

what-we-do/service-one/subservice-one-a

rather than what I have currently:

what-we-do/subservice-one-a

Is this possible?

You can actually use a bit of Twig logic to determine your category URI formats.

Try this for your Category URI Format:

{parent ? parent.uri : 'what-we-do'}/{slug}

Which is just a more compact way of doing this:

{% if parent %}{{ parent.uri }}{% else %}what-we-do{% endif %}/{slug}

That will only add 'what-we-do' to the URI if the current category doesn't have a parent (top-level category). Otherwise, it prepends the entire parent's URI.

That should give you URIs like:

/what-we-do/service-one
/what-we-do/service-one/subservice-one-a
/what-we-do/service-one/subservice-one-b
/what-we-do/service-one/subservice-one-b/subservice-one-b-nested


Does Craft have an equivalent of EE's Custom Fields loop for front-end entry forms? We're in the process of scoping out an online assessment form to be build in Craft CMS. We need to give the client the ability to add, edit and remove questions (custom fields) and would ideally like to handle all entries through a channel, rather than a dedicated form plugin. The thing I'm struggling with at the moment is how to render the field layout for a channel in my template. Expression Engine handles this using the {custom_fields} loop.

Is there an equivalent template tag for Craft CMS? Or would we be better of working with Freeform or SproutForms?

Any help would be much appreciated. Thanks.

Personally I don't have any experience with Free Form but have been using Sprout forms for quite some time now.

In Sprout forms your client can create entire forms or just add a couple of fields however you like it. The support on Sprout forms is decent aswell.

Plus sprout forms got email notifications aswell which might be interesting for your client.


onBeforeRender event? Is there an event or hook I can use with my plugin? I am looking for away to manipulate and record data about an entry before it is returned to the client. I could do this with AJAX after the page is rendered by the browser but I would prefer to do this on the server.

Is there an event or hook I can use to accomplish this?

The full list of events that Craft provides is documented here.

There currently isn't onBeforeRender or onRender events, but it is on our list with no particular ETA.  It gets tricky because it's difficult to distinguish between the main template and any other template that might happen to call TemplateService->render() (includes, etc.).


Getting blocks from matrix and injecting them throughout a page, NOT a single loop statement I have a matrix field that allows the user to add little 'designed' features throughout the page.
These are placed in certain positions on the page and so I want to loop through these but because they are dotted about he page,  I cannot do a simple, for loop.
Instead I could get all the blocks like this:
  {% set nuggets = entry.nuggets
    .with([
    'nugget:nuggetBody',
    'nugget:icon'
  ])
    .all() %}

Then I could place them like so:
{% set nugget = nuggets[0] %}
{% include '_includes/_components/nugget.twig' with {
  self: {
    size:'xl',
    bgColor: nugget.circleColour.color[0].class,
    iconPath:nugget.icon[0].path,
    body: nugget.nuggetBody[0].bodyPlain
  }
} %}

{% set nugget = nuggets[1] %}
{% include '_includes/_components/nugget.twig' with {
  self: {
    size:'xl',
    bgColor: nugget.circleColour.color[0].class,
    iconPath:nugget.icon[0].path,
    body: nugget.nuggetBody[0].bodyPlain
  }
} %}

etc etc

I wondered if there is a better or more streamlined way than this?
And what happens if they don't have 'enough' blocks, how to accomodate, if for example, I have placed 6 around the page in the design and code, but they only add 4.  I know I could do this...
{% if nuggets|length >= 3 %}
  {% set nugget = nuggets[2] %}
  {% include '_includes/_components/nugget.twig' with {
    self: {
      size:'xl',
      bgColor: nugget.circleColour.color[0].class,
      iconPath:nugget.icon[0].path,
      body: nugget.nuggetBody[0].bodyPlain
    }
  } %}
{% endif %}
etc

But is there a better approach...?

I would use a macro to output the contents of a single nugget (matrix block), this way you don't have to repeat the include statement multiple times. The only thing you need to keep track of is the current index, i.e. which item is next. You can't do this inside the macro, since a macro can't have persistent state. You have two options:

Set up a variable to keep track of the current index and increment it every time you include the macro.
Since you have six predefined positions where nuggets may be displayed, you can just hardcode the index and output the item at that index, if it exists.

Macro definition
{% macro nugget(nugget = null) %}
    {% if nugget %}
        {% include '_includes/_components/nugget.twig' with {
            self: {
                size: 'xl',
                bgColor: nugget.circleColour.color[0].class,
                iconPath: nugget.icon[0].path,
                body: nugget.nuggetBody[0].bodyPlain
            }
        } %}
    {% endif %}
{% endmacro %}

{% import _self as macros %}

Having the if-condition inside the macro to handle missing nuggets means you don't have to repeat that if-condition everywhere you want to include a nugget.
Option 1: Index variable
{% set nuggets = entry.nuggets
    .with([
        'nugget:nuggetBody',
        'nugget:icon'
    ])
    .all() %}
{% set nuget_index = 0 %}

{# Nugget position #1 #}
{% include macros.nugget(nuggets[nugget_index] ?? null) %}
{% set nugget_index = nugget_index + 1 %}

{# Nugget position #2 #}
{% include macros.nugget(nuggets[nugget_index] ?? null) %}
{% set nugget_index = nugget_index + 1 %}

{# Nugget position #3 #}
{% include macros.nugget(nuggets[nugget_index] ?? null) %}
{% set nugget_index = nugget_index + 1 %}

Option 2: Hardcoded nugget indexes
{# Nugget position #1 #}
{% include macros.nugget(nuggets[0] ?? null) %}

{# Nugget position #2 #}
{% include macros.nugget(nuggets[1] ?? null) %}

{# Nugget position #3 #}
{% include macros.nugget(nuggets[2] ?? null) %}


Price formatting thousands/decimal signs In the webshop we're building we're outputting the price like so:

{{ cart.itemSubtotal|commerceCurrency(cart.paymentCurrency, convert=true) }}

which displays for example:

€1,680.00

We will be using multiple currencies in the webshop. Is it possible to set the thousands/decimals signs? Or does the CMS take these settings from the locale? We can't find the settings for this anywhere.

Thanks in advance!

The thousands/decimals signs are based on the current users locale and can not be configure at the moment. The number is formatted based on the currency and locale. You would need to make your own currency formatter as a twig extension.

You could set format=false in the craftCommerce filter, then pass the value to your own number formatter filter.


How can I create an ElementCriteriaModel with 'and' and 'or' In my template, I want to:

Get all the entries in the section 'uploads';
Get all the assets that are related to one of the upload entries, and have a relation to all the tags I provide.

So, that would be:

{% set company = craft.entries.section('company').id(companyId).first() %}
{% set uploads = craft.entries.section('uploads').relatedTo(company).limit(null) %}

{% set relatedToUploads = ['or'] %}
{% for upload in uploads %}
    {% set relatedToUploads = relatedToUploads | merge([upload.id]) %}
{% endfor %}

{% set relatedToTags = ['and'] %}
{% for tag in tags %}
    {% set relatedToTags = relatedToTags | merge([tag.id]) %}
{% endfor %}

But, how would I combine those two relatedTo-arrays to one, usable in the ElementCriteriaModel for the assets?

It’s not currently possible to specify both of those conditions at once with the relatedTo param, so you would have to do it with two separate queries.

First, get all of the asset IDs that are related to the upload entries:

{% set uploadAssetIds = craft.assets.relatedTo(uploads).ids() %}

(Note that the relatedToUploads variable is not actually necessary here.)

Then you would get all of the assets whose ID falls within one of the uploadAssetIds, and who are related to all of the tag IDs.

{% set relatedToTags = ['and'] %}
...

{% set assets = craft.assets.id(uploadAssetIds).relatedTo(relatedToTags) %}


Class 'Craft' not found I am new to PHP and trying to call reCaptcha API in CraftCMS. I have the following variable:

$captcha = Craft::$app->getRequest()->getParam('g-recaptcha-response');

But I get the following error when I submit a form:

Fatal error: Uncaught Error: Class 'Craft' not found

How can I import the Craft class?

This is not really specific to Craft, but you should import Craft at the beginning of your class file like this:

<?php

use Craft;

...

I suggest you take a look at that documentation for more details about how to import PHP classes: https://www.php.net/manual/en/language.namespaces.importing.php


Templating - printing entry.url throws js error when trying to embed Disqus? Default Disqus embed code includes the following:

var disqus_config = function () {
    this.page.url =   // Replace PAGE_URL with your page's canonical URL variable
    this.page.identifier = {{ entry.section }}-{{ entry.id }}; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
};

I am trying to use this.page.url = {{ entry.url }}.  This prints the url, but it includes the http:// and the : is throwing an error preventing Disqus from loading.  Is there anyway to template the url without the http://????

Note that the config I am using is straight from Disqus.  The CraftCMS knowledge base article does not include this-page.

Try wrapping your entry.url in quotes so JS reads it as a string.

this.page.url = '{{entry.url}}


Access add and remove events with the Craft Element Selector? Is there any way to access an event, and trigger some function, when an element is added / removed with the Craft Element Selector logic available in Garnish?

I am working on a custom field type and to keep everything tidy I only want to show a set of options when an asset is selected.

As of Craft 2.4.2688:

  It is now possible to access Craft.BaseElementSelectInput objects
  from their container elements, via .data('elementSelect').

On select element:

$('#theElementSelectField').data('elementSelect').on('selectElements', function(e) {
    console.log(e); // Take a look
    // Do stuff here when elements are selected...
});

On remove element:

$('#theElementSelectField').data('elementSelect').on('removeElements', function(e) {
    console.log(e);
    // Do stuff here when elements are removed...
});

NB. If you are using the Craft macros to build the select element inputs, make sure your javascript is run after craft has done its magic with the input field.

Thanks to Brandon Kelly & Lindsey D


Logged in admin, can't see front end site when system is off This just started happening. When I am logged in as admin and system status was off I could still see the front end. Now I can't. I need to set the system status to on in order to see the front end. This isn't ideal for development. Any thoughts?

I resolved this by adding a redirect to get rid of the www. The issue was my admin would be www but the front end wasn't.


What does General Settings > Logo do? I am a craft newbie and was wondering what General Settings > Logo does, as I can't find anything about it (how to use it with twig etc.) in the documentation or elsewhere.

The logo you upload there will replace the default Craft graphic on the login page for the Control Panel.


Get a hash’s key name This is possibly more of a Twig thing, but if I have a hash…

{% set hash = {
    "key": "value"
} %}

How can I output the key name?

{% for value in hash %}
    {{ value }}
{% endfor %}

There's an example of this in the Twig documentation: https://twig.symfony.com/doc/3.x/tags/for.html#iterating-over-keys-and-values

In your example, it would be:

{% for key, value in hash %}
    {{ value }}
{% endfor %}


Display variant title on cart page On the cart page, I currently display items that have been added to the cart with:

{{ lineItem.description }}

What I want to do, rather than displaying the product name and variant title as one, is to split them. So that I can display the variant title separately from the product name.

What is the correct model for this?

lineItem.purchasable.title is the variant title, lineItem.purchasable.product.title is the product title.


Create new Asset Kinds I have updated my craft/config/general.php file to allow some new file types to be uploaded to my site.

'extraAllowedFileExtensions' => 'bim, dwg, rvt'

When I output these file assets in the template, I would like to be able to use the {{ asset.kind }} property to output "PDF" or whatever name for my additional types.

Currently I see unknown for each of my new types.

I've had a look in the documentation for the IOHelper Class but could not see a way to add additional definitions.

Currently, the "file kinds" list is hard-coded and doesn't expose itself to a config setting or plugins.

You can definitely make a feature request to open it up, though!


Deleting oldest 404 redirects task stalling I have a site which has 100's of pending "Deleting oldest 404 redirects" tasks and they keep stalling so the list isn't clearing.

The client has added lots of custom rules to the .htaccess which I will need to investigate, could this be the cause?

Is there a way I can remove all the pending/stalled tasks manually?

I found the table 'craft_tasks' in the database, there were actually over 5,000 tasks in here all run by Sprout Seo. I emptied the table which has cleared the tasks.

I will need to look into why these tasks are not running correctly on the clients server.


Parse a String dynamic in Twig I would like to output a field from a variable like this:

{% set foo = "entry.title" %}
{{ foo }}

In this example it outputs "entry.title".

Other Example like this:

{% set prefixVar = "en_" %}
{% set foo = "entry."~ prefixVar ~"title" %}
{{ foo }}

In this example it outputs "entry.en_title". Is it possible in Twig to get the content of the entry field instead of the string?

Surrounding text in quotes declares it as a string, whereas no quotes will assume variables. If you remove the quotes, you should get what you need.

{% set foo = entry.title %}
{{ foo }}

EDIT:

  I realy want to render a string and get the fieldvalue. A other example would be like this: I have a Variable with a Prefix and now i would like to output a field with this prefix: {% set foo = "entry."~ prefixVar ~ "_fieldName" %} {{ foo }}. Is that possible?

I am not sure if that's possible when accessing keys through the dot formatting (ie. array.keyname)

But you could tweak the approach a little bit, to access dynamic keys in entry using the attribute() twig function, such as:

{% set foo = attribute(entry, prefixVar~"_fieldName") %}


How to add addition attribute and fields in public registration form in Craft CMS User Registration Form

I want to setup a public registration form in Craft CMS.  Currently this form support only fields username, email, password, but I want to add at least 10 other fields.

Also I want to create three types of user groups. How do I update the group in the public registration form?

User registration in Craft

Before you can allow any type of user groups you will need at a minimum of the Client version of Craft. To allow public registration, you will need the Professional version. Only the Professional version will allow you to have public registration on our site. Here is more information about users and user groups.

To add additional fields to your registration form, I would start here. That will get you started with a basic form.

You will need to create a new field within the CP. For example - let's say I want to capture your pets name.

I will create a text input, called petName. Then in the layout builder, I will assign that field to the user profile tab.

Next, I need to update my registration form with my new input.

Note: any new field you want to add to the user's profile must be prefixed with fields[]. For example:

<label for="petName">Pet Name</label>
<input type="text" id="petName" name="fields[petName]" {%- if account is defined %} value="{{ account.petName }}"{% endif %}" placeholder="">
{{ account is defined and account ? errorList(account.getErrors('petName')) }}

Hope this helps!


Can I rename my craft/ folder? I have one site on my server that's currently using Craft, and I'd like to setup a second one to use Craft as well. Can I rename the craft folder, and then set the $craftPath variable to point to it?

Absolutely! In fact, you've outlined the steps needed to do so...

Rename craft folder
Change $craftPath value in index.php

That's it!


Show Adjuster Amount Only in Commerce I have adjusters that dynamically add/remove costs to things like baseShippingCost and baseDiscount, and want to be able to specifically show the numbers for those adjusters on the cart page - not just the total baseDiscount or baseShippingCost number - as things like shipping costs, or coupons, are also bundled into those.

Here's the adjuster example from documentation, I'll use this as the example:

class BusinessLogic_TaxRemover implements Commerce_AdjusterInterface {

    public function adjust(Commerce_OrderModel &$order, array $lineItems = []){

    $myAdjuster = new Commerce_OrderAdjustmentModel();

    $order->baseDiscount = $order->baseDiscount - 5;

    $myAdjuster->type = "Tax Remover";
    $myAdjuster->name = "Australian GST Remover";
    $myAdjuster->description = "Removes the 10% GST";
    $myAdjuster->amount = -5.0;
    $myAdjuster->orderId = $order->id;
    $myAdjuster->optionsJson = ['lineItemsAffected'=>null];
    $myAdjuster->included = false;

    return [$myAdjuster];

    }

}

How would I access the $myAdjuster->amount in the template/twig file for the order? I've tried {{ cart.myAdjusterName.amount }} and I simply get the error "Craft\Commerce_OrderModel and its behaviors do not have a method or closure named "myAdjusterName".

Does anyone know how to get this information? Any help would be great!

You can access each adjuster and its respective amount via the cart.adjustments tag. Here's the example supplied with the templates from the commerce plugin (commerce/cart.html):

{% for adjustment in cart.adjustments %}

        {{ adjustment.type }}

        {{ adjustment.name }}
({{ adjustment.description }})
        {{ adjustment.amount|currency(cart.currency) }}

{% endfor %}

If you have set the included attribute of your Adjuster to true then it won't show up as an adjuster but only affect the cart amounts outputted (such as baseShippingCost and baseDiscount) so if you have something similar to the above already, that's why it won't be displayed. You can read more about the included attribute here.


How I am supposed to send product data to stripe for web hooks? How I can add data to craft commerce stripe product while ordering, Actually I have used stripe webhooks so need meta data to identify the products

If this is Commerce 2, you're probably looking for the buildGatewayRequest event. From the transaction property set on that event, you should be able to get the Order and all the products.


How to output the full page URL? Very simple request!
All I want to do is to be able to get the full URL of the page & output that in the HTML (for a 'share this page' link).
Can anyone help please?
Many thanks!

In Craft 3 this is now {{ craft.app.request.absoluteUrl }} — for those who land here from a search and want to avoid using the deprecation notice to update it!


How do I implement Google+ comments on a Craft site? How can I implement Google+ comments into Craft CMS?

This is a bit tricky, and there may be some tradeoffs that I'm unaware of, but the following code works for me:

Two things to note about the code above.

You want to pass the url that will be associated with the comments to the data-href attribute. The example above assumes you are on a page where {{ entry.url }} is the value you want.
The line that references BLOGGER is required: data-first_party_property="BLOGGER"

I can't explain why that is, but the odd specificity of it may also be a reason why this isn't an easy thing to figure out how to do, as it may suggest this is an unsupported method of adding Google Comments to your site or that the method to add Google Comments to your site will change at some point.

In my searches however, this was the only method I found to do it at all and it seems to be used by several people and work just fine at the time of this post.


Programatically create a Neo block with children I already discovered how to create a neo block programmatically from this post: How can I set a Neo field's values from my plugin/module?
However, I don't know how I can create a neo block with child blocks.
So the idea is I want something like this:
[
    'blocks' => [ // Neo field handle
        'new0' => [
            'modified' => 1,
            'type' => 'topLevel', // Top level neo block
            'enabled' => 1,
            'collapsed' => 0,
            'level' => 0,
            'fields' => [
                'someField' => true, // Neo block field
            ],
            'children' => [
                'new0' => [
                    'modified' => 1,
                    'type' => 'secondLevel', // child neo block
                    'enabled' => 1,
                    'collapsed' => 0,
                    'level' => 0,
                ]
            ]
        ]
    ]
]

The children array is just what I imagine the solution might be like. But this doesn't work.
Does anybody know how it should be done?
Thanks

I figured it out. You have to create a separate block and it somehow figures out it's a child based on the level you specify. So something like this:
[
    'new1' = [
        'modified' => 1,
        'type' => 'parentBlock',
        'enabled' => 1,
        'collapsed' => 0,
        'level' => 0,
        'fields' => [
            'theme' => 'black',
        ],
    ],
    'new2'= [
        'modified' => 1,
        'type' => 'childBlock',
        'enabled' => 1,
        'collapsed' => 0,
        'level' => 1, // increment the level
        'fields' => [
            'value' => 'text',
        ],
    ]
]


How to exclude child elements when looping through categories? I've got a few categories set up with a few child categories for each. Each one has assets (PDFs) assigned to them, by going into the assets, double clicking, and setting the category field there. So for example:

Category 1
-- asset 1
- Sub Category 1
-- asset 2
-- asset 3

Category 2
-- asset 4
- Sub Category 1
-- asset 5
-- asset 6

But when I'm looping through the related assets, using:

 {% for category in craft.categories.group('categoryGroup').level(1) %}
    {% set resources = craft.assets.relatedTo(category).find() %}
      {% for resource in resources %}
        {{ resources.title }}
      {% endfor %}
 {% endfor %

I get:

Category 1
- asset 1
- asset 2
- asset 3
- Sub Category 1
-- asset 1
-- asset 2
-- asset 3

Category 2
- asset 4
- asset 5
- asset 6
- Sub Category 1
-- asset 4
-- asset 5
-- asset 6

Which logically makes sense, that it's returning all assets related to the children categories, since those are also related to the parent. But how can I exclude them from the loop, so I only get back the assets that are directly related?

Rather than preparing multiple queries - you can execute the Query in your field value

{% for category in craft.categories.group('categoryGroup').level(1).find() %}
    {% for resource in category.fieldHandle.find() %}
        {{ resources.title }}
    {% endfor %}
{% endfor %


Craft Queues: Job Event In Control Panel we can see the progress of a certain job. I would like to hook on events like "DONE" or "FAILED" and do certain things in Control Panel, e.g. reloading the page, or redirecting somewhere

Update: in Craft.js line 11429, I can find

// Fire a setJobInfo event
this.trigger('setJobInfo');

Maybe I can do something with it.

I found a solution. In my control panel module javascript, I can do

Craft.cp.on('setJobInfo', function(e){
  console.log(e);
});


How do I use dynamic variables for plugin settings? I would like to use a "dynamic" variable (for lack of better words) in my plugin settings. I am sending whomever fills out my contact form a welcome email. I'd like to be able to include the persons name if I could.

Here is my settings file:

_settings.html

{{
forms.textareaField({
    label:        "Welcome email Message"|t,
    id:           'welcomeEmailMessage',
    name:         'welcomeEmailMessage',
    instructions: "The email message that is sent to that the person who filled out the contact form."|t,
    value:        (settings.welcomeEmailMessage ? settings.welcomeEmailMessage : "Thank you {firstName} from {siteName}"|t({ siteName: craft.app.siteName })),
    errors:       settings.getErrors('welcomeEmailMessage')
    })
}}

I know {siteName} is a variable that's available everywhere. {firstName} is the name of my form input that I'd like to somehow hook into.

I have all of the information I need to send the email to the user - just not sure how to connect the dots between the service that sends the email and the settings so I can use {firstName} and it will get replaced with the value of the firstName input field.

Here is my service if it helps to see what I'm trying to do...

MyService.php

...
    $email->toEmail = $contact->email;
    $email->subject = $settings->guestSubject;
    $email->body = $settings->welcomeEmailMessage;
...

EDIT
Sorry, this is kind of hard to describe. I'll keep going maybe that will help.

I have a contact form plugin, that has a setting of welcomeEmailMessage. That setting allows the admin to set the text to the email that is sent to whomever filled out my form. Think of it like a confirmation email.

But, instead of just saying "Hi there..." I was trying to grab the value of the firstName input and inject that into the email message that resides in the plugin settings.

The email could then read: "Hi there Bob..."

I have attached a screen shot of my settings page.

So you can see in the image I have {firstName} in the textarea. I'm struggling on how to grab the value from the contact form - and inject it into that template variable.

It looks like it's very similar to the "Email Settings" area within the CP. Only instead of getting the dynamic parts from the install settings, I want to get the values from the form that was submitted.

Hope that helps?

EDIT

Reading though the comments, I'm struggling a little about how to implement them.

Here is my welcomeEmailMessage. It's located in my plugin's directory/templates

html

<html>
    <body>
        <div>
            Hello, {{ firstName }}
        </div>
    </body>
</html>

Then in my service I now have this:

php

$email = new EmailModel();
craft()->templates->renderString($settings->welcomeEmailMessage, ['firstName' => $contact->firstName]);

So now it seems like I need to tell my plugin how to get to that template?

First - you don't need a template file. You can type the template right into the settings textarea like you already had, and like the other email twig templates do it. Then, in your service, you do:

$email->body = craft()->templates->renderString($settings->welcomeEmailMessage, ['firstName'=>$firstName]);

The settings textarea then need to have something like:

Hello {{firstName}}, welcome!

And then you should be all set!


File Permissions on Compiled Templates We use an automated deploy system when developing with Craft.

We have a deploy user "deploy" and a web server user "www-data"

Deploy is a member of the www-data group.

Our first few deployments went fine but when we hit the point where the system started deleting old version (15 or so in) we started getting errors where it couldn't delete the old files properly.

On examination folders created here - /craft/storage/runtime/compiled_templates have the permission drwxr-xr-x so only www-data can edit/write to them.  Is there anyway we can make this group writable when created rather than having to do a manual clean up?

Normally folders in the /craft/storage/runtime/* directory are just cached files.

Those files are generated by craft, so really they're generated by php/php-fpm/nginx/apache or what ever you've got setup.
Maybe check the user that made those folders are in the www-data group if you do want to look into it further.

The better solution is to completely ignore that folder... Those files do not need to be deployed at all. They're just cached files generated by Craft. So just ignore that directory from your repo completely.


Another gallery question I have looked around but cant find an answer to this.

I have a structure for my gallery page, in-which there are three separate entries called A, B and C.

There are different images within these entries. But how would I go about showing all the images within these entries in a random order?

Say I went to the gallery page and they all showed up randomly, then theres a sub navigation to the separate entries on there own?

It's probably a simple solution but templating it has me really confused.
Thank you

You can set an array and order them by random.

{% set gallery = craft.entries.section(['galleryA','galleryB','galleryC']) %}

Then you have to display them by random using .order('RAND()')

So your for loop looks like:

{% for entry in craft.entries.section(gallery).order('RAND()') %}


Update a remote stock database I am building an online store with craft commerce, but I have a problem, I need to update a remote stock on every purchase, this stock is located in a remote server, do you know if  exist a plugin that makes this task easier for me?
Maybe a plugin that sends a POST API on every purchase or something.

There is a first party web hooks plugin available here:
https://plugins.craftcms.com/webhooks
https://github.com/craftcms/webhooks
That may well do what you need, but I have no personal experience of it, and of course any pre-built plugin will have some limitations.
Alternatively, you can write your own module to do this of course (https://craftcms.com/docs/3.x/extend/module-guide.html)
In essence, in that, you would listen to Commerce events (see https://craftcms.com/docs/commerce/3.x/extend/events.html for information on those) - and take whatever action you like when the event is triggered.  Of course you have the full power/scope of PHP to do anything you like at that point.
It's highly likely you'll end up needing at least some custom module code in a typical Commerce project, so this might be a good place to get started!


Modelling flexible content sections and recommendations A little background first; I'm coming from WordPress, along with the Advanced custom fields (ACF) plugin, so my thinking behind this may not be the best way in Craft.

In ACF I usually set up a field set that consists of an outer repeater field, with a nested flexible content field inside (much like the Matrix field in Craft). Within the repeat field, there are a couple of options that controls the appearance of a section, such as a background colour/image. This is also used in my template to differentiate where a <section> starts and ends, and often has styles associated to style the overall section. Anything within the flexible content fields is contained within this.

Then, within the flexible content field, I define my layout types (title block, two column text, text with image, etc.). An image to describe the layout structure if my description is a little confusing:

I'm looking to create a similar sort of set up with Craft. Without an outer repeater field, I'm struggling to think how to achieve the "section" container. What would be a way to achieve this sort of thing?

Thanks!

I'm not familiar with ACF, but if you're looking for blocks-within-blocks, you could use the Neo plugin/fieldType. It allows you to define blocks, and then have nested blocks. It allows for decent management of blocks, too, so that you have children of specific parents.

For example:
You could have the following blocks/content types:

Copy
Card
Image slider
Form
Ad Unit
Related Content

And then the following layouts and components:

Two-column
Three-column
Single column w/ Sidebar
Column
Sidebar

The Neo fieldType would allow you to make block groups, and then allow the content blocks to be limited to certain layout blocks. It would look like this (demo only, not fully configured):

The layouts are selectable at the top level. You need these to target template files (or at least it makes it easier, IMHO).

The layouts can only have columns or sidebars. The two- and three-column only have columns, while the single has column and sidebar.

  Note: Currently blocks are only limited on the page level and not the block level, meaning if you set the max number of columns to 1, you'll only be allowed one column per entry.

The column block has the main content types, while the sidebar block has the sidebar content types.


How to get one entry's related stuff in Vuejs component For example, in a vuejs component, i send a ajax request to get an article. And in this article, there is a relation field called relatedTopics.

How can I get this article's relatedTopics with something like article.relatedTopics?

So your AJAX request likely hit an Element API or GraphQL endpoint, which would return the data to you as JSON.

What exactly that endpoint returns is totally up to the endpoint, but realize that it's not a PHP/Twig object that gets returned. It's a JSON-ified representation of it.

So for you to get the article.relatedTopics either the endpoint would need to have resolved the .relatedTopics and return them as JSON, or it could return an id or other information that you could use in another AJAX request to return that data.

More reading:

Lazy Loading with the Element API & VueJS
Autocomplete Search with the Element API & VueJS
Using VueJS + GraphQL to make Practical Magic


Assets folder first level open by default Is there any way to make the Assets folder also show the first sub folder level by default, like in the attached screenshot?

You could modify this JavaScript to do it for you. We currently have it running on a site where this was sought-after

Caveat: Our script opens ALL folders, not just the first level - hence the need to modify.

jQuery(window).on('load', function() {
    var $ = jQuery;

    var openFolders = function() {
        var imageRootLinks = $('a[data-key^="folder:"]');

        $.each(imageRootLinks, function(index, link) {
            var imageRoot = $(link).parent();
            var toggle = imageRoot.find('.toggle');
            if (toggle.length && !imageRoot.hasClass('expanded')) {
                toggle.first().click();
            }
        });
    };

    // open folders in left menu
    openFolders();

    // open folders in image selector
    $(document).ajaxComplete(function(e, status, requestData) {
        if (requestData.url && requestData.url.indexOf('getElements') && requestData.data && requestData.data.indexOf('context=modal&elementType=Asset') != -1) {
            openFolders();
        }
    });
});

Then simply include the JS-file through a plugin

// runs on all requests
public function init() {
    // check that user is logged in and in the control panel
    if ( craft()->request->isCpRequest() && craft()->userSession->isLoggedIn() ) {
        // the includeJsResource method will add a js file to the bottom of the page
        craft()->templates->includeJsResource('myplugin/js/openFolders.js');
    }

}


bootstrap.php returns a value of 1 in Craft CMS I have a Craft CMS instance that I created a copy of by tarring up the folder and then dumping the mysql database and then transferring that to a different server. On the target server I restored the folder and the database.  When I attempt to access the instance, I get an error in the Apache logs:

[Mon Jul 29 15:48:01.415795 2019] AH01071: Got error 'PHP message: PHP Fatal error:  Uncaught Error: Call to a member function run() on integer in /var/www/html/bsf_public/craft/app/index.php:73\nStack trace:\n#0 /var/www/html/bsf_public/public/index.php(19): require_once()\n#1 {main}\n  thrown in /var/www/html/bsf_public/craft/app/index.php on line 73\n'

I have spent multiple hours chasing the errors.  A phpinfo() call in a file works so I know that PHP is properly configured.  So I focused on line 73 of the index.php file referenced in the error message.  It has these lines (in addition to others):

// Load and run Craft
// -----------------------------------------------------------------------------

$app = require 'bootstrap.php';
$app->run();

$app is returning a value of 1.  bootstrap.php has these final lines of code:

$appClass = '\Craft\WebApp';
$app = new $appClass($config);

return $app;

I can't quite figure out why the bootstrap.php is returning a 1 which is why the error message occurs.  I found one other instance of this being reported in a PHP app but the post had no resolution.

Maybe a Craft CMS guru can point me the right direction although I'll bet it is some kind of permissions or PHP issue.  I checked the PHP files and they all have execute permissions.

Ubuntu 16.04.6 LTS

5.7.26 MySQL

PHP 7.1.29 (cli) (built: May  3 2019 09:33:57) ( NTS )

Craft CMS 2.7.5

In my particular case, I downgraded the Bitnami LAMP stack using instructions found here: https://community.bitnami.com/t/how-can-i-downgrade-to-php-5-6-from-php-7-0/51792

The downgrade fixed the issue although, had I seen Brad's answer before that, no doubt I could have fixed it using those posts....


How to render an entry template in plugin? I have a section "Emails" which has an entry 'Welcome Email'. The template assigned for it under Section is '_email/welcome'. This works fine when viewed in frontend. But I want to render the same template in my plugin services. The code I have used is:

$template = 'welcome';
$data = 'foo';

$oldPath = craft()->path->getTemplatesPath();
$path = craft()->path->getTemplatesPath().'_email/';
craft()->path->setTemplatesPath($path);
$html = craft()->templates->render($template,$data);
$breaks = array("
","
","
");
$text = str_ireplace($breaks, "\r\n", $html);
craft()->path->setTemplatesPath($oldPath);

But this gives an error "_email/_layout" not found in craft.log . What am I doing wrong ? Could anyone please help.

Thanks in advance.

If it is a frontend request

$html = craft()->templates->render('_emails/_layout.twig', $data);

and in a backend request

$oldPath = craft()->path->getTemplatesPath();
$newPath = craft()->path->getSiteTemplatesPath();
craft()->path->setTemplatesPath($newPath);
$html = craft()->templates->render('_emails/_layout.twig', array());
craft()->path->setTemplatesPath($oldPath);


How to include JS and CSS resources for a plugin variable I've got a variable (widget is a better word) that I want to output with accompanying CSS and/or JS.

I'm rendering the variable (widget) with the following

return TemplateHelper::getRaw($output);

I realize the following exists but other than inline js/css is there a way to output the widget and include CSS/JS by only using a single variable? I want to make this as simple as possible.

<script src="{{ resourceUrl('plugin/js/public.js') }}"></script>

`

You can use these and Craft automatically adds the files in the appropriate spots.

$output = craft()->templates->includeJsFile(UrlHelper::getResourceUrl('plugin/script.js'));

$output .= craft()->templates->includeCssResource(UrlHelper::getResourceUrl('plugin/styles.css'));