Live Preview error when entry is disabled

Change:

{% for entry in craft.entries.section('flashback') %}

To:

{% for entry in craft.entries.section('flashback').status(null) %}

The 2nd one will grab all entries regardless of their enabled/disabled status.


renderTemplate() renders the twig file without any CSS

I sincerely appreciate the responses!
I've since resolved this issue, below is the changed code. My controller was extending the Craft web controller (\craft\web\Controller) which has its own renderTemplate() method that I switched to, which fetches the Control Panel assets I wanted for styling the page.

The template twig file remains identical as is above.

(Modified) Controller: Controller.php

class Controller extends \craft\web\Controller
{
    public function actionIndex(){

        Craft::info("hello!", __METHOD__);

        return $this->renderTemplate('plugin/done');
    }
}

This did the trick for what I wanted. Thanks again!


Controller action throws a 500 error in some environments

Brad's comment above helped us find the solution.  I had been looking at the craft.log file in the control panel at /admin/utils and it doesn't output the stack trace.  Look at the actual log file, we got more info on the issue which was that the ajax call was returning:

[status code] 401
[reason phrase] Unauthorized

The plugin on the site we have was trying to render a front-end template using Guzzle and the dev site is password protected, and the request was not making it through.

Possible solutions include:

Updating the way the template is being processed to not require a front-end request
Only use this functionality in locations that are not password protected
Hurry up and finish the massive overhaul of the plugin you are working on so this issue doesn't exist any longer!

#3 it is!


Find entries that use a specific block in their Matrix field?

You can join your matrix table and check for elements with a certain type and your owner id

{% set entries = craft
    .entries()
    .section(['your-section'])
    .leftJoin('{{%matrixblocks}} as matrixblocks', 'matrixblocks.ownerId = entries.id')
    .andWhere({'matrixblocks.typeId': 1})
    .all()
%}

replace the correct section and the correct type id of your blocktype


This should grab all of the variant's SKUs like you're looking for:

$criteria = craft()->elements->getCriteria('Commerce_Variant');
$allVariants = $criteria->find();
$allSkus = array();

foreach ($allVariants as $variant)
{
    $allSkus[] = $variant->sku;
}


You can't use the domain .dev anymore, it's Google's gTLD (https://icannwiki.org/.dev) and they don't want to share. See https://medium.engineering/use-a-dev-domain-not-anymore-95219778e6fd for a detailed backstory.

Instead, you should use the TLDs reserved by the IETF for this purpose, like .test.

For reference, this is the HSTS List maintained by Chromium which is in turn the basis for the lists used by Firefox, Opera, Safari, Internet Explorer and Edge


I had a similar problem a while ago when a plugin listened for onSaveUser and then saved the user itself, causing an infinite loop. Someone provided me something like:

craft()->on('users.onSaveUser', function(Event $event) {
    static $recursionLevel = 0;
    if ($recursionLevel == 0) {
        $recursionLevel++;
        // do your stuff
    }
});


Conditional email notification on saveUser action?

You should be able to do something like this using the event:

craft()->on('users.onSaveUser', function(Event $event) {

  $testfield = craft()->request->getPost('someField');

  if($testfield)
  {
    // Send the email
  }

});


ElementAPI: Include author/user data with entry?

$entry->author is going to be a UserModel object, so you've got access to all of its properties and methods depending on what you need to return.

i.e. $entry->author->firstName, $entry->author->lastName, etc.

Here's a list of them from a Twig perspective, but the same things are available to PHP. https://craftcms.com/docs/templating/usermodel


Error declaring TLS Version wrong in Charge plugin

Stripe changed up some API URLs, which threw off Charge's legacy method for detecting TLS compatibility.

The erroneous warning is fixed in Charge 2.2.3.


What you are looking for is the relatedTo parameter (docs) and this post will also help.

If you wanted to return any entries which has (any) tags attached, you could do:

$entries = Entry::find()->tags(':notempty:')->all();

Where tags is the handle of your tags field.


Plugins page inside CP Settings not working

Sounds like an FTP upload or an unzipping operation didn't finish properly.

Try downloading a fresh copy of Craft from http://buildwithcraft.com and replacing the old craft/app folder with the new one.


How do I reference a variable/expression inside an expression in twig templating?

With Twig, you'll never need to nest tags within other tags. In fact, it's impossible to do.

You can simply pass your variable into getUrl instead of using a string.

<img src="{{ asset.getUrl(entry.newsImageSize) }}">


EntryModel::populateModels throws a 500 error

There's probably an error in craft/storage/runtime/logs/phperrors.log and there's a 99% chance the problem is you're hitting your php.ini file's memory_limit setting.

Populating 5,000 models is going to take a significant amount of memory.


Serialization of 'Closure' is not allowed

I found the problem which is because of a plugin called "Scout". I just update it and everything seems to be fine now.


Open up this file:

/craft/config/db.php

... and take a look at the very first line. The file should start with this:

<?php

It sounds like that may not be the case with your file. Make sure there is absolutely nothing before that < character, not even a blank line.


Is there a way to retrieve discounts for a product in Craft Commerce v2?

This should do what you're looking for:

craft.commerce.discounts.getAllDiscounts()

craft.commerce.discounts is a reference to services/Discounts, so you've got access to all of the public methods in there, of which getAllDiscounts() is one.


How can I show 3 entries at random from within the next 10

You could use Craft's shuffle() function to randomize your postDate ordered array of entry models:

{% set entries = craft.entries({
    section: 'entertainmentEvents',
    entertainmentBanner: ':notempty:',
    status: 'live, pending',
    order: 'postDate desc',
    limit: 10
}) %}

{% set entries = shuffle(entries) %}

{% for entry in entries|slice(0, 3) %}
    ...
{% endfor %}


Need help trying to pass a variable of a related entry

This is how it could look like from Twig point of view. I don't know if the Solespace part is correct

{% set priceBracket = entry.relatedAdoptionLink.one() %}
{% set priceUrl = priceBracket !== null? priceBracket.getUrl() : '' %}

{{ form.renderTag({returnUrl: priceURL}) }}


Why is Craft rendering a blank page instead of an error template?

Turns out it was HHVM causing the issue. Switching back to 'normal' PHP made the problem disappear.


How do I output image in the loop for an entry?

Your image input returns and array so you need to reference the first item, even if you only allowed one to be selected.

{% set news = craft.entries.section('news').limit(3) %}
{% for news in news %}
   {% set cover = news.promotionNewsImage %}
   {% if cover|length %}
       {{ cover[0].getUrl('gtLg') }}
   {% endif %}
{% endfor %}


Include additional fields in Craft form notification template

If you look at the GitHub page for the ContactForm plugin under the section for adding additional fields, you'll see that you need to change the name of the message field to message[body]. Try that to see if it helps. I would imagine leaving it as message means that it overwrites the values of the other additional fields.


How to loop through multiple entries fields

You don't mention what your related entries field handle is, but remember that calling any related element (entries/assets/categories/users/tags) will require a .all() (or .one() or .ids() or one of the other query-executing methods) unless the related elements are eager-loaded. With that in mind I can't see anywhere in your code where you're executing a call to fetch the related entries from sidebarChoice, and you also seem to have a redundant inner loop. With eager-loading it might look like this:

  {% set sidebarChoice = entry.sidebar.with(['sidebar.yourRelatedEntriesHandle']).one() %}
  {% for sidebarEntry in sidebarChoice.yourRelatedEntriesHandle %}
      {% set myEntryQueryUrl = sidebarEntry.url %}
      {% if 'whats-on' in myEntryQueryUrl %}
        {% set myEntryQueryPath = '/whats-on/' %}
      {% elseif 'who-we-are' in myEntryQueryUrl %}
        {% set myEntryQueryPath = '/who-we-are/' %}
      {% else %}
        {% set myEntryQueryPath = '/' %}
      {% endif %}

{{ sidebarEntry.title }}

{{ sidebarEntry.title }} text

  {% endfor %}


As far as I know there is no convertNumberToWords type method in twig or php. However, you could create your own. This could be done in several ways: twig macro, custom twig filter, or plugin variable.

Here is an example of a simple twig macro that uses a lookup table:

{% macro numberToWords(integer) %}

    {% digits = {
        0:  'zero',
        1:  'one',
        2:  'two',
        3:  'three',
        4:  'four',
        5:  'five',
        6:  'six',
        7:  'seven',
        8:  'eight',
        9:  'nine',
        10: 'ten',
        11: 'eleven',
        12: 'twelve',
        13: 'thirteen',
        14: 'fourteen',
        15: 'fifteen',
        16: 'sixteen',
        17: 'seventeen',
        18: 'eighteen',
        19: 'nineteen',
    } %}

    {{ digits[integer] }}

{% endmacro %}

{% import _self as macros %}

{% for i in 1..19 %}
    {{ macros.numberToWords(loop.index) }}
{% endfor %}

Creating a custom twig filter or a plugin would of course allow you to use php, which might provide a more robust solution. Doing a quick search I see there are a few examples that people have written, like this one.

If you want to do this via a plugin, you might try using lindseydiloreto's excellent craft-businesslogic as a starting point. Then just paste the php methods (from the example linked above) into the variables file (along with any dependency methods).


Radio button field no setting default checked

I've got a radio button field on Commerce products that is also not visibly showing as checked. Inspecting shows the correct input is actually showing checked="". Manually adjusting this to checked="checked" makes the radio button re-appear. Doesn't help us in the meantime, but perhaps it's as simple as that to fix the issue? Safari and Firefox on Mac.


_includes/forms documentation on field types

For anyone looking for more information, you can find all of the form macros for _includes/forms here:

/craft/app/templates/_includes/forms.html

and the child templates here:

/craft/app/templates/_includes/forms/<filename>


Best SEO plugin for Craft CMS - SEOmatic vs SEO plugin

I have used SEOmatic for years on Craft 2, but since it became a paid plugin on Craft 3 I trialled other SEO plugins.

I realised the extra work needed to make other plugins have a result like SEOmatic's wasn't worth the time over the extra cost to install SEOmatic and be on my way.

I'd recommend SEOmatic, but if you have the time to make a free SEO plugin do what you need it to do, then go for it.


Is it possible to use something like dropzone.js for file uploads with sprout forms?

You will have to upload the files and index them as assets, then return the asset id's to your form. You can then use these asset id's in your form so you can post them to the server, effectively creating the relations you want.

I've put up a little gist that does this for jQuery File Upload - you can use it as a reference for any other upload mechanisms: https://gist.github.com/boboldehampsink/2e645655d613574ec4b7


Email notifications with attachment when uploading files to s3

Sprout Forms v2.3.0 added support for S3 Asset uploads and file attachments.

--

OUTDATED: As of this post, Sprout Forms does not yet support email attachments using S3.

As a workaround, it is possible to override the email.html notification template using Template Overrides and link to or display S3 assets in the way you would provide a link to any asset:

{{ asset.getUrl() }}


In the Element API plugin, how can I get only tags that are related to a particular section?

The relatedTo parameter accepts either a single element ID or model, or an array of element IDs or models. It doesn't accept asset source handles, section handles, or a particular element type constant.

This means that in order to pull all tags related to a specific element type, you'll need to give the relatedTo parameter an array of all IDs for that particular element type.

You're not specific about what travelImages are, but assuming it's an Asset source, something like this should work:

'elementType' => ElementType::Tag,
'criteria' => [
    'relatedTo' => craft()->elements->getCriteria(ElementType::Asset, [
        'limit' => null,
    ])->ids(),
    'limit' => null,
],

Note that if travelImages isn't an Asset source, you'll need to change ElementType::Asset to the appropriate element type (e.g. ElementType::Entry, ElementType::Category etc).


It's not possible to do both an "and" and an "or" in a single query going though the ElementCriteriaModel.

Here are a few other posts that go into more detail and provide some potential workarounds.

How can I create an ElementCriteriaModel with 'and' and 'or'

How to fetch specific users OR admins with the ElementCriteriaModel?


Moving Craft assets from one S3 bucket to another

Yes that’s all you need to do. It also works the same if moving to/from a local directory or Google Cloud Storage, or even a subdirectory of any volume type. The index of file paths is relative to the root of the volume for the source, so if the volume changes it doesn’t matter.


Front-end entry form not updating custom fields in existing entry

You need to pass your custom fields in a fields array, try:
{{ input('text', 'fields[headline]', entry.headline, {
    required: true,
    class: entry.hasErrors('headline') ? 'text error' : 'text'
}) }}

See example here - https://craftcms.com/knowledge-base/entry-form


Converting array of entries to an array of ids

Simply append .ids() to your initial query...

{% set authorIds = craft.users.search('fullName:*' ~ query ~ '*').ids() %}

Without the .ids() method, you're actually working with an Element Criteria Model.

The behavior that you're seeing is the default... it's as if you had appended .find() to your initial query.

  [.find()] will be called automatically as soon as the ElementCriteriaModel is treated like an array (that is, as soon as you...  start looping through the elements)

So instead of allowing the default behavior to kick in, just apply .ids() to the initial query, and get a batch of entry IDs instead of a full array of entries


Probably you are caching the page. You can't cache a sprout form. The csrf will be the same for all the users.


Commerce discount promotions as a fieldtype?

That field type doesn’t currently exist, but it wouldn’t be hard to create it.

Here’s the relevant code you’d need if you want to take a stab at it:

use Craft;
use craft\base\ElementInterface;
use craft\commerce\models\Discount;
use craft\commerce\Plugin as Commerce;

// ...

public function normalizeValue($value, ElementInterface $element = null)
{
    if ($value !== null) {
        return Commerce::getInstance()->discounts->getDiscountById($value);
    }

    return $value;
}

public function getInputHtml($value, ElementInterface $element = null): string
{
    $options = [];
    foreach (Commerce::getInstance()->discounts->getAllDiscounts() as $discount) {
        $options[] = ['value' => $discount->id, 'label' => $discount->name];
    }

    /** @var Discount|null $value */
    return Craft::$app->view->renderTemplate('_includes/forms/select', [
        'id' => $this->handle,
        'name' => $this->handle,
        'options' => $options,
        'value' => $value->id ?? null,
    ]);
}

With that, the field type’s value would always either be a Discount model or null, so in your templates you could do this:

{% if entry.myDiscountField %}
    Code: {{ entry.myDiscountField.code }}
    ...
{% endif %}

Alternatively, you could pull this off with a simple Plain Text field that stores a discount code, and then fetch the discount manually from your template.

{% if entry.myDiscountCodeField %}
    {% set discount = craft.commerce.discounts.getDiscountByCode(entry.myDiscountCodeField) %}
{% else %}
    {% set discount = null %}
{% endif %}

{% if discount %}
    Code: {{ discount.code }}
    ...
{% endif %}


As per Brandon's request in the comments to the original question here are the steps I used to import. Below is copied from a blog post I wrote with screenshots.

NOt sure why but my code bits are not displaying even though I've used the code button in the wysiwyg here. To see the full code bits go to my blog.

First use a different plugin https://github.com/boboldehampsink/import

copy all files from original site
in the Craft CP click the gear icon on the top right, then Assets, New source and fill in the fields. both the path and url can be set to relative paths, but be sure to not use a leading slash.
After saving click the gear icon again and go to the lower left and update asset indexes.
The next step is to install the Import plugin by putting the files in /craft/plugins then in the CP click gear and plugins and finally install.
This plugin only imports content in CSV format. This requires a new template in ExpressionEngine which will need to be set wiht php turned on in order to force the browser to download the file directly.

The next bit of code contains all our fields and how we want them named. This is important to easily map the fields using the import plugin. Line 20 has entry_date with extra spaces this is due to my blog rendering it and not displaying the code correctly - remove extra spaces for it to work. When migrating images, be sure to only include the image name. My images currently reside in a Matrix field {photos} and a file cell. In order to get just the file name it is necessary to use the file tag pair like this {image}{file_name}{/image} where the outer tag pair is the file field/cell name.

   Title
    Url Title
    Entry Date
    Description
    Image

{exp:channel:entries channel='photoblog' limit='500' disable="categories|member_data|pagination|comments" status="not foo"}

            Migrating Content from ExpressionEngine to Craft
            {url_title}
            { entry_date }
            {description}
            {photos}{image}{file_name}{/image}{/photos}

{/exp:channel:entries}

After downloading the file open it in Excel, you may see a warning that the file format doesn't match the extension, open it anyhow. Now do a save as and choose CSV (comma delimited). My research indicated that this extra step is necessary as using the template to save as CSV with content that contains quotes may not work correctly.
Now to import, click Import in the Nav. Fill in the fields as required and upload your CSV file.
Go to the next page where we map the fields to Craft fields.


Create a single section that displays the channel entries so that I can link to it?

Are you trying to select the actual Channel itself? (like the News / Blog).

Trevor Davis' handy Listing Section fieldtype could work here.
If you want more control as to what is shown on that channle's "index" page (intro blurb, featured entries, etc), as you mentioned, just create a single that maps to the index page of the channel. Craft's routing is smart enough so when you go to /blog/ (for example) it'll route to the entry first.


Try adding square brackets around your object:

{% set testsByAllergenGroup = testsByAllergenGroup|merge([{ (group.title): entries }]) %}

Update:

First thing I'd change is to set the object keys to something unique (slug or id works better than title).

To feed the object with all properties you need (so you don't need to do further DB queries later), do the following.

The values of your object can be objects too, this allows you to assign more data to each individual key.
You could define a custom key for each property you need for your output (i.e. 'groupId': group.id) or
pass the whole category model (see example code below), which allows you to access all of its properties in the output loop.
With the entries you need to make sure to assign an array of entry models and not an ElementCriteriaModel! So make sure to
add the find() method to your craft.entries call.

{% for group in groups %}
    {% set entries = entries.relatedTo(group).find() %}
    {% set testsByAllergenGroup = testsByAllergenGroup|merge([{
        (group.slug): {
            'group': group,
            'entries': entries
        }
    }]) %}
{% endfor %}

{% for key, value in testsByAllergenGroup %}
    {{ value.group.id }}: {{ value.group.title }}
    {% for entry in value.entries %}
        {{ entry.title }}
    {% endfor %}
{% endfor %}


How to update cart.lineItems while specifying HTTP cache headers?

I do not think you can achieve this with browser caching - there's no concept of cache 'escaping' with this type of caching.  Indeed, there's currently no concept of cache escaping with Craft's {% cache %} tag either...which is a shame.

In general, even, caching at the page level when using Commerce carts is tough/impossible - e.g. you'll also need fresh CSRF tokens for cart operations etc.

Currently (without plugins anyway) - the best thing is probably to use Craft cache tags for static page elements and simply avoid caching things like your cart count and add to cart forms etc.  And put your site on a nice fast server :)


If you're looking to just output the value of the PositionSelect field, it's block.placement.

See here for more info: http://buildwithcraft.com/docs/position-select-fields#templating


Craft 2 to Craft 3 upgrade: User Photos not migrated to User Accounts

The migration should have taken care of that. The only scenario where it's not a bug I can imagine is if you ran the migration on a staging server that did not have the actual user photo files and then pushed the DB to live server. If that's not the case, can you get in touch via support@craftcms.com?


Does "verify email addresses?" have to be enabled in order to fire the users.onActivateUser event?

Use the onSaveUser event instead but check for the flag inside that event called isNewUser

http://buildwithcraft.com/docs/plugins/events-reference#users-onSaveUser


wp-login.php bloating log files every 20-30 seconds

So what I do is I just redirect anything requesting a WordPress-ish thing to WordPress.com (that's what they are looking for, after all...). You can see how to do that here if you're using Nginx:

https://github.com/nystudio107/nginx-craft/blob/master/sites-available/somedomain.com.conf#L67


HTTP 500 Error after trying to update to Craft 3.1.1

The error message indicates your php.ini file's memory_limit setting is still sitting at 256M (268435456).

Double check you've bumped it up to 512M and you're editing the correct php.ini file for the site.

From there, the quickest way to get the site back up and running is if you have Composer installed from the command line, to nuke your vendor folder and composer.lock file, then run composer update from your project's root to pull in a fresh set of Craft's dependencies.

To be safe, you'll probably also want to restore your database from a pre-update attempt database backup as well (you can't be sure at what point the original fatal error occurred during the update process).


Additional criteria to filter status of field passed into RelatedTo

This turned out to be a Craft bug. I’ve posted an issue for it at https://github.com/craftcms/cms/issues/5849, and fixed it for the next release (3.4.12).


Need to make a wish list / favourites system

I know this is a bit late for your specific question, but Shortlist for Craft is designed for exactly this.

(I'm the developer).

It's also available for EE


It's not documented, but UserGroupsService has a method assignUserToGroups($userId, int|array $groupIds). You'll have to save your user first, but once you have a user id, I believe you can just use that with something like this:

// Original code
$user = new UserModel;

$user->username = 'username';
$user->email = 'user@email.com';
$user->firstName = 'first name';
$user->lastName = 'last name';
$user->getContent()->setAttributes([ 'usersAddress' => 'Your face' ]);

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

// Add to single group
craft()->userGroups->assignUserToGroups($user->id, $groupId);

// OR, add to multiple groups
craft()->userGroups->assignUserToGroups($user->id, [$groupIdOne, $groupIdTwo]);


Neo: children won't display or I get all() deprecation notice

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

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

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

and then inside _moduleRow.twig

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

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

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


Checking for existence of a field within a Matrix block

Use brackets instead of dot notation for the field handle when you test for defined:

...
{% if block['test'] is defined %}
    ...
{% endif %}


Can Section access be restricted at Entry Type level?

When you mention new user group, is that a new group of admins/back end users or just people browsing on the front end?

If it's on the front end, just checking the logged in user's group in twig against a new restricted entry type could give you want you want.

{% if entry.type == "restrictedEntryType" and currentUser and currentUser.isInGroup('newUserGroup') %}

   {# let them through #}
   {% include "whatever/restricted_content.html" %}

{% else %}

Thou shall not pass! You need to log in to see this content.

{%endif%}

If it's the back end, like you said, you'd have to do a serious refactor to manage it properly. Put all the restricted content in one structure and only give access to admins/users you want to have edit the content.  You may end up doing that anyway just to keep everything sane, depending on how siphoned off your content is.

To move a structure from one section to another, check out Brandon Kelly's canonical answer.


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") %}


What is the difference between 'nav' and 'for' for looping?

for is part of the native Twig language.

for is for general usage... It's the basic, general looping structure that you'll use 99% of the time. You'll find that it closely mirrors for and foreach in other programming languages.

nav is defined by Craft, and doesn't exist natively in Twig.

nav is special... You'll only need it to loop through entries in a Structure section, or categories in a Category Group. The sole purpose of nav is to make it easier to create a menu or navigation.

One of the biggest benefits to using the nav tag is that you'll then be able to use ifchildren within it...

{% ifchildren %}
    <ul>
        {% children %}
    </ul>
{% endifchildren %}

The logical relationship between nav and its respective children is slightly complicated... and worthy of a separate post if you need further clarification. :)


Can I eager load data within a template?

No you can't with any build in Craft functions. I've added a feature request for this on Crafts feedback site.

What you can do for now is to use Mike Peppers excellent Plugin "Fetch" which pre-fetch relations for you.

Ser here https://github.com/mdcpepper/fetch


Is there a way to limit the Asset upload directory in Redactor?

No. You'll want to use a Matrix Field with an image block.

That said, it's possible you could create a Redactor button that does this via a plugin, but it'd probably be a bit of work.

Does anyone know the Redactor setting to set the default size of the editor?

The setting your looking for is minHeight.  Here's an example:

{
    buttons: ['html','formatting','bold','italic','unorderedlist','orderedlist','link','image','video'],
    plugins: ['fullscreen', 'pagebreak'],
    minHeight: 200
}

A longer discussion on custom Redactor toolbars and a few more examples can be found in this article: Custom Redactor Toolbars for the Rich Text Field in Craft CMS


Any way to turn cookies off for the front end?

That's PHP's session cookie and is how PHP keeps track of user data across different requests. It'll only get set if something in your template ultimately invokes any of the methods in Craft's UserSessionService or Yii's CWebUser.


How can I get a specific product via plugin?

I think you have direct access to the purchasable already via a simple

$lineItem->purchasable

E.g. I do things like this

foreach ($event->params['order']->lineItems as $item) {
    BusinessLogicPlugin::log($item->purchasable->title);
}

You should really just be able to access the fields directly on the purchasable via

$lineItem->purchasable->field

So I don't  think you need to use the snapshot side of things at all as long as you're doing this at this stage anyway - the snapshot is something you use if you're dealing with an order when the product data may have since changed etc. as I understand it.


Ignoring the obvious "use a Structure" answer, I suppose you could fake a "hierarchy" by placing a child and parent entry field on each of your Single sections and manually assigning entries as relationships.

Then your Twig template could would just be checking those fields and building the family tree based on the relationships.


What's the best way to set up a content-manageable 404 page?

I would create a Single with the URI set to "404", and also set its Template to "404". That entry will automatically get loaded if you go to http://example.com/404, and load your 404.html template, so at the top of the template you should add this to it:

{#
 #  Fetch the 404 Single entry, if we don’t already have it.
 #  (requests to /404 will already have it.)
 #}
{% if entry is not defined %}
    {% set entry = craft.entries.uri('404').first() %}
{% endif %}

Craft 3 note: As of Craft 3 the 404.html template is only loaded if devMode is disabled in the current environment. If devMode is enabled, you'll continue get a Yii error message.


In MySQL, there's a "max_connections" variable: https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_max_connections

In Apache (assuming you're using Apache) there's a "MaxClients" directive: http://web.archive.org/web/20160415001028/http://www.genericarticles.com/mediawiki/index.php?title=How_to_optimize_apache_web_server_for_maximum_concurrent_connections_or_increase_max_clients_in_apache

I'm not sure of your situation, but you may need to modify both of these to achieve what you need. These settings are not controlled through CraftCMS, but instead need to be controlled by editing your server environment configs.


Sort entries in a category or entries field?

To order the products you'd make the Products section into a structure and display the category you were sorting by in the listing as a table column.

You can then re-order all products to be in category order (using the table column), then re-order each product for each category.

You can then output each product grouped by category with something along the lines of:

{% for cat in categories %}

  {% set products = products.relatedTo( cat ) %}

  {% for product in products %}

    {{ product.title }}

  {% endfor %}

{% endfor %}


To answer just the initial question. "Is it possible to reorder fields with drag and drop?".

Yes, Settings > Fields > Set up as Matrix > You can then add/delete or reorder there using a drag method within the matrix you set-up. (See image below)

If what you are looking for is more control than this. While having some the same issues learning more about the use of Sections and Channels at http://buildwithcraft.com/docs/sections-and-entries has proven quite useful to me.


Currently, Craft doesn't expose the UID in any of its models.

Kind of a pain, but the only thing I can think of as as a workaround is to write a plugin that has a UserModel with the UID and mimics whatever methods from UsersService that you need.


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

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

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

{{ entry.title }}

{% endfor %}

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

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

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

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


Your <div class="cell small-12 medium-7 large-5 circle-container"> is well displayed in the source code, but not in the inspector; Try to remove and/or fix what interfere with this piece of HTML (JS?).

Edit: If I disable JavaScript on my browser, everything is fine on your site.


Can I use a Global Variable for date/time?

You never need to nest Twig tags. It looks like {{ glo... is all being processed (or attempted to process) as PHP date shorthand codes.

Try this instead...

{{ entry.postDate|date(global__siteMetadata.gv__articleDateFormat) }}


How to determine if there are events in a calendar?

Looking at the docs you can search for events for a certain calander by including the id or the handle in your query.

{% set calendars = craft.calendar.calendars({
    limit: 100,
    order: "name",
    sort: "asc"
}) %}

{% for calendar in calendars %}
    {% set events = craft.calendar.events({
        calendarId: calendar.id
    }) %}

    {% if events|length %}
        // there are events
    {% else %}
        // calendar has no events
    {% endif %}
{% endif %}


Listen for checkbox check event for assets table and modify action trigger menu item

Here is one approach: Whenever an asset is checked on or off, it triggers a manipulation of the hidden ul.menu. You could listen for that update to be complete, then you’ll be able to access and hide the link.

$('#main .elements:first').on('click', '.checkbox', function(evt) {

    // "View Asset" action is visible by default
    var isViewActionVisible = true;

    // If only one asset is selected and it is an image, set up to hide "View Asset"
    // Otherwise, stick with default behavior
    if ( $('#main .elements:first tr.sel').length == 1 &&
         $('#main .elements:first tr.sel td[data-attr="kind"]').html() == "Image" ) {
        isViewActionVisible = false;
    }

    // Wait for menu ul to finish updating, then show/hide "View Asset" action
    $(document).one('DOMNodeInserted', 'ul.menu', function() {
        $('a#View-actiontrigger').parent().toggle( isViewActionVisible );
    });

});


How to include a lightswitch for each related entry in the source element of a relationship

You are correct, you would not want to add those fields to the news items directly. Like you said, it would cause problems if you wanted a News item pinned on one service but not pinned on another one.

The best solution here (imo) is to utilize a Matrix field (or possibly a Table or SuperTable field, depends on your preference). So I would create a Matrix field for your service entries called News Items or whatever. Than each news item block would have several fields:

the actual related entry field where you would pull in the news entry
a lightswitch field for pinned
a lightswitch field for alert
a date field you could use to expire the news block
etc...

This would enable you to set these settings on each news block on the individual service entries, so you're not muddying up the news items themselves or contaminating other service pages where you may want a news item "pinned" or "alerted". And again, you could also use a SuperTable or maybe even a Table field instead of Matrix - just depends on what you prefer.


I don't think that Craft can do this natively, and would guess that it needs an AssetModel in order to determine where to create the image transforms, etc. Your best bet would be to add the images to Craft.

Assuming the images are stored locally, this is pretty easy:

create an asset source that points to the folder where your images are stored
go to settings and update asset indexes for the new asset source

If your filenames are all unique then you can reference the image by filename in your template:

{% set asset = craft.assets.filename('filename.jpg').first() %}
{% if asset is defined %}
    <img src="{{ asset.getUrl('medium') }}">
{% endif %}

Otherwise, you will need to add folderId to the criteria, or add the asset to the current entry via an assetField and reference through the assetField.

(Another option, although not recommended, would be to add the images to an asset source as above; update indexes; then create a template that just renders all images in the asset source (using source('assetSource') criteria), rendered with the given transform. You can then just hard code the path to the image using the image transform folder ('myimages/_medium' folder). But you could just as easily use photoshop for this.)


Can Garnish be extended to allow plugins to use custom keyboard shortcuts?

I'm not sure if there's an "official" way yet but I've looked through the source a little bit and I think the most Craft-like way I would do it, following plugin conventions, is to extend Garnish.Base with a new object that attaches the listener.

(function($) {

        var PluginName_KeyCapture = Garnish.Base.extend({

            init: function()
            {
                this.addListener(Garnish.$doc, 'keydown', function(ev)
                {
                    if ((ev.metaKey || ev.ctrlKey) && ev.keyCode == 66)
                    {
                        ev.preventDefault();
                        console.log('You hit CTRL + B! Good work.');
                    }
                });
            }
        });

        Craft.PluginName_KeyCapture = new PluginName_KeyCapture();
    })(jQuery);


Getting error when using bootstrap: Craft\WebApp::$request

Got testing working by requiring the tests/bootstrap.php  (not app/bootstrap) like here: https://github.com/selvinortiz/craft.loath/blob/master/tests/run.sh#L6


I think you're correct in how you currently do it. You can't merge Element Queries, you can merge IDs (or any array of anything, really).
The only thing you should remove, is the all when settings posts, because paginate expects an element query, not an array of elements.


Excluding Array of Entry Ids Not Busting Cache

The cache tag is somewhat misunderstood and it tends to trip up even the most seasoned Crafters.

The best way to explain about the {% cache %} tag is to think of it as a snapshot in time.

The first time the template runs, Craft saves the output to the database. It does not actually save queries.  On subsequent runs, Craft simply grabs the output from the cache. Again, it doesn't save state or variables, it simply saves the output.

Specifically, I see you have {% if %} tags inside {% cache %}. Those conditionals will only run once. The {% if %} tags won't re-execute and the output is going to be the same.

What you can do is something like:

{% if whatever %}
      {% cache %}
         {{ do some output stuff }}
      {%endcache%}
{% endif %}

For more info, check out Straight UP Craft as well as Andrew Welch's great piece on the subject.


How do I get different URL Format with parent/child structures & how do I display different templates?

To get different URL Format for parent & child pages, you need to go to the CP structure settings and edit the Entry URI Format. This is how your URI should look like:

{% if level == 1 %}features/{slug}{% else %}{parent.slug}/{slug}{% endif %}

For your templating question, if you want a different template for parents and children, you need an if statement in your template file for that structure. So in your CP structure settings, you will have one template file:  features/feature_entry.twig and inside that file you will have:

{% if entry.children|length %}

   <!-- If it has a child, it's a parent page -->
   {% include 'features/_parent.twig' %}

{% else %}<!-- it's a child page -->

   {% include 'features/_child.twig' %}

{% endif %}

Just like that... You now have 2 different templates in 2 different .twig files.


How to hide {{ entry.title }} on a {structure} page but show it on a {structure}/{category-slug} page

Figured it out.

    {% set categories = craft.categories.group('fellowsCat') %}

  {% nav category in craft.categories
    .group('fellowsCat')
    %}

      {{ category.title }}
      {% ifchildren %}

          {% children %}

      {% endifchildren %}

  {% endnav %}

{# --- this is the key line here ---#}
{% if category is defined %}

{% set entries = craft.entries({
  relatedTo:  category,

})
%}

{% if craft.entries.relatedTo(category) %}

      {% for entry in entries %}

  {{ entry.title }}

      {% endfor %}

     {% else %}
    nothing to see
     {% endif %}
     {% endif %}


Upload and crop profile photo in frontend

This is a very old question, but thanks to this example I was able to build quickly a profile picture form using Craft 3 and jQuery File Upload plugin (thank you!).

The action value and file input name have changed. You should write it like this now:

<input type="hidden" name="action" value="users/save-user">
<input id="image-upload" type="file" name="photo" style="display: none;">


First you create a function to send the data to a custom controller

var offset = 10
var getElements = function(){
    var data = new FormData();
    data.append('offset', offset);
    data.append('action', 'plugin-name/controller-name/function-name);
    data.append(window.csrfTokenName, window.csrfToken);

    var xhr = new XMLHttpRequest();
    xhr.open('POST', '', true);
    xhr.onload = function () {
        // check for errors
        if(this.status === 200){
            var response = {};
            try {
                response = JSON.parse(this.responseText);
            } catch(error) {
                throw Error("server did not return valid JSON: " + this.statusText + ' ' + this.status);
                return false;
            }
            // append your response to the object/container you like
            offset += response.elements;
        }
    }
    xhr.send(data);
}

Then in your controller just fetch the entries

public function actionGetElements(): Response
{
    $offset = Craft::$app->getRequest()->getBodyParam('offset');
    $query = Entry::find()->section(['whatever'])->limit(10)->offset($offset);
    $elements = $query->all();
    $html = Craft::$app->getView()->renderTemplate('path/to/template', [
        'elements' => $elements
    ]);
    $fetchedElements = \count($elements);
    $totalElements = $query->count();
    return $this->asJson(
        [
            'html' => $html,
            'success' => true,
            'elements' => $fetchedElements,
            // check if the number of fetched element + offset is equal to the number of total elements
            // if that's the case you can hide the button to load more since there are no more elements
            'hideButton' => $fetchedElements + $offset === $totalElements
        ]
    );
}

Keep in mind to include a CSRF token data.append(window.csrfTokenName, window.csrfToken); and to include an protected $allowAnonymous = [ 'actionGetElements']; to your controller


Triggering JavaScript from back-end event

When an entry is saved, an Entry saved. flash message is set and displayed by Craft. You could use the Control Panel JS plugin to write a script to detect this flash message and perform your desired action.

The flash message is set in a div with an id="notifications". When there is no notification present, this div is empty. When there is a notification present, the div contains another div like this:

Entry saved.

If you test for the presence of this inner div and also the specific notification content (i.e. Entry saved.) you should be able to trigger the actions you need to.


I found by just adding the code from the following site it will add slashes via a 301 redirect:

RewriteCond %{REQUEST_URI} /+[^\.]+$
RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L]

Now my .htaccess file looks like the following:

<IfModule mod_rewrite.c>
    RewriteEngine On

    # 301 redirect with trailing slash
    RewriteCond %{REQUEST_URI} /+[^\.]+$
    RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L]

    # Send would-be 404 requests to Craft
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
    RewriteRule (.+) index.php?p=$1 [QSA,L]

</IfModule>

And here is another version/option which seems to work as well:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*[^/])$ /$1/ [L,R=301]

Here is a third option which seems to work as well:

# Always append a trailing slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !/$
RewriteRule . %{REQUEST_URI}/ [R=301,L]

I'll update once I've researched and settled upon the best option.


composer.json file not updating when plugins are updated

If you have a caret icon infront of your version number, for example

"craftcms/cms": "^3.0.0",

These version numbers in composer.json will not change when you update.

The caret icon tells Composer it has free reign to update this package, but not to the next major version number. ^3.0.0 can update to 3.1.0, 3.2.0, 3.2.1 etc, but won't update to 4.0.0. As such, it does not need to write to composer.json because the caret icon is already giving it the instructions it needs.

You can read more about it in the Composer documentation.

Running composer update will (if there are updates to perform) write to composer.lock instead. If you are using version control, you can run a git diff to see what changes have been made to your lock file immediately after running an update.


Can I disable languages from the General Config Settings?

How about hiding the language switcher on the front-end?


How can I use multi-environment configuration to set each root URL?

Make sure to change the "Site URL" setting to {siteUrl} in your control panel settings...

  Control Panel > Settings > General > "Site URL"

Within your config file, you'll also want to put your siteUrl value inside of an Environment-Specific Variables sub-array:

'mynewcraftsite.dev' => array(
    'devMode' => true,
    'environmentVariables' => array(
        'siteUrl' => 'http://www.mynewcraftsite.dev/'
    )
),
'mynewcraftsite.com.au' => array(
    'environmentVariables' => array(
        'siteUrl' => 'http://www.mynewcraftsite.com.au/'
    )
)

Here's how Craft is compiling all of that...

Within each of your environment configurations, there are many config settings that you can apply to that specific environment. Additionally, each environment can have a sub-array called environmentVariables, which allows you to set whatever unique variables you want. The most common examples are siteUrl and fileSystemPath (great for setting up assets sources), but you can truly set whatever environment variables you want.

Once you've set the siteUrl value in your environment variables array, you now need to use that value... This is where the control panel settings page comes into play. Changing "Site URL" to simply {siteUrl} tells Craft to pull that value from your environment variables.

IMPORTANT: Notice the single set of curly braces, and the lack of spacing between the variable name and the braces. This is the syntax difference between environment variables and Twig variables.

That's it! When you create a path, Craft will use whatever is in the "Site URL" setting. And since that's pulling in your environment variable, that's what you'll get.

Lastly, allow me to point out a few things in your example which may also be stopping this from working for you (feel free to update the example in your question to fix these issues)...

Most importantly: You're combining data that should be stored in two separate files... craft/config/db.php and craft/config/general.php. While the multi-environment format is the same, you'll need to separate the data shown in your example. Put most of your settings into general.php, only the following belong in db.php:

server
user
password
database
tablePrefix

You also have an errant line of code in your example... This line should definitely be removed:

'localhost' or '127.0.0.1'.

Finally, you've left some crucial security information in your example... All of your database connection info is exposed (as well as your true domain names in your siteUrl examples).

Hope that helps... If you fix the bugs in your example code, I'll remove my corresponding notes from this answer. :)


Errors with Craft 2.3, Imagine and Imagick

I've tracked it down / fixed it by explictly selecting my 'imageDriver' in the config. The docs say this is a new setting in 2.3.

It seems the default of 'null' is calling 'imagick' but not working, whereas choosing 'imagick' in the config makes it work?


Oh my god I lost half the day on a syntax error !!

My general.php file had the line with true in quotes :

'autoLoginAfterAccountActivation' => 'true',

The correct line to have the parameter work is:

'autoLoginAfterAccountActivation' => true,


Make sure your fonts are TTF.
If you're loading them by remote URL, make sure the isRemoteEnabled is set to true.
If you're changing weights, make sure to use the named weights in your CSS (normal, bold) rather than numeric weights.

(These are limitations of the underlying DOMPDF library, which is used in Printmaker 1.x. The next release of Printmaker, for Craft 3, uses a much nicer rendering engine, which will eliminate these limitations.)


Craft 3: how to call methods in another plugin's service?

Assuming Plugin1 is their main plugin class file name, you could do:
\fully\qualified\namespace\Plugin1::getInstance()->myService->myMethod();

In order for this to work:

Craft must be installed.
Plugin1 must be installed and enabled in Craft.
Composer autoloading has to be working so that it knows where to find Plugin1

If you're doing this from a custom module, then you'll need to listen for the EVENT_INIT event, because plugins get instantiated after modules.
i.e.
Craft::$app->on(Application::EVENT_INIT, function() {
    \fully\qualified\namespace\Plugin1::getInstance()->myService->myMethod();
});


Hundreds or thousands of posts in a structured channel?

We've seen Craft installs running with several hundred thousands of users / assets / entries, etc.

But when you're getting into that range, there are several other things to take into account such as hardware resources and architectural designs, various caching methods (Varnish, memcached, Craft's template caching), etc.

Having said that, it makes more sense to me to have them as entries and if you need the ability to have them sortable, then a structured section is the ways to go.

But there is a known issue with the UI for structured sections in the control panel where it will bog down when you get into the thousands of entries range.  We're addressing that for the upcoming Craft 2.2 release, so it shouldn't be a problem for long.


Non-admins not authorized to create entry via frontend

Craft won't allow any anonymous entry creation at all.

You can use something like the Guest Entries plugin that simulates an "anonymous" entry because you select a user account ahead of time to assign all anonymously created entries to.


Okay I'm all set now. Turns out it was a production environment/MySQL issue, and it's cropped up before on Digital Ocean. See Brad's fix here.

I just added

'initSQLs' => array("SET SESSION sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';")

to my config/db.php and good to go.


You can get the parts of your URL using the getSegment() function. https://craftcms.com/docs/templating/craft.request#getSegment

Then use the slug parameter and the criteria model’s first() method to grab the entry. Global Sets are already preloaded, to access a set dynamically grab it from the _context variable.

{% set entryA = craft.entries.slug(craft.request.getSegment(1)).first() %}
{% set entryB = craft.entries.slug(craft.request.getSegment(2)).first() %}
{% set globalSet = _context[craft.request.getSegment(3)] ?? null %}

{% if not entryA or not entryB or not globalSet %}
    {% exit 404 %}
{% endif %}

{{ entryA.title }} - {{ globalSet.myField }}


You can create a custom plugin with Pluginfactory.io and check the box for Controllers but leave the name blank. Copy the downloaded files into your path/to/craft/craft/plugins/>>nameofyourplugin<</ directory and install it in your cp.

Then you'll insert a function like this in your controller

public function actionRenderTemplate(){
    $id = craft()->request->getParam('id');
    // do some checks if the id is valid or not here...

    $html = '';
    $success = false;
    $message = '';

    if($entry = craft()->entries->getEntryById($id)){
        // as example to render different templates based on entry type
        $entryType = $entry->getType()->handle;
        $html = craft()->templates->render('path/to/your/template/' . $entryType, array(
            'entry' => $entry
        ));
        if($html){
            $success = true;
        }
    }else{
        $message = Craft::t('could not find entry with id ' . $id);
    }

    $this->returnJson([
        'message'   => $message,
        'success'   => $success,
        'html'      => $html
    ]);
}

And your Javascript could be this

$('.load-instrument').click(function(){
    var data = {
        action: "pluginname/actionRenderTemplate",
        id: $(this).data('id')
    };
    $.ajax({
        type: "post",
        url: '',
        data: data,
        success: function(data){
            if(data.success === true){
                $("#idOfYourDiv").html(data.html);
            }else{
                // display error messages here
            }
        },
        error: function (XMLHttpRequest, textStatus) {
            console.log("Status: " + textStatus);
        }
    });
});

However I would recommend you to read the docs about Controllers and about templates to fully understand what you have to do here

edit: your html could be

<button data-id="{{instrument.id}}" class="load-instrument" value="click me">Click me</button>


Listing categories alphabetically & total post count

The relatedTo param will do the trick:

{% set entries = craft.entries.limit(null) %}
{% for category in craft.categories.relatedTo(entries).order('title asc') %}
    {% set entryCount = entries.relatedTo(category).total() %}
    {{ category }} ({{ entryCount }})
{% endfor %}


By default, when you query elements you get back an array of Elements. Craft assumes you are using find() to query your elements if you don't explicitly say otherwise. You can loop through those elements and display attributes of those elements like you are doing:

{% for entry in craft.entries.find() %}
    {{ entry.title }}
{% endfor %}

More generally, here an abstract example of what you are getting back from your query:

{# A query for several Entry elements #}
craft.entries.find()

{# Results are an array of Entry Models #}
array(
  EntryModel,
  EntryModel,
  EntryModel
)

And in the case, you are only querying a single entry, you still get it back in the format of an array when using the default find() behavior.

{# A query for a single Entry element using find() #}
craft.entries.id(11).find()

{# Results are an array of a single Entry Model #}
array(
  EntryModel
)

However, if you update your query to use first(), you get back the Model directly:

{# A query for a single Entry element using first() #}
craft.entries.id(11).first()

{# Results are the Entry Model itself (not within an array) #}
EntryModel

There is one more scenario to consider when using first(). If you happen to be Eager Loading Elements, the results that you get back for your Element fields are not ElementCriteriaModels, but just normal arrays. So, in the case of accessing the data returned from Eager Loaded Elements you will not be able to use first() as the first() method is only available when you interact with ElementCriteriaModels.

In these cases, or in cases where you are sharing a partial template between two pages, one which uses eager loading and one that doesn't, you will need to access your first entry in an array using array syntax.

{% set entry = entry.entryRelationsFieldHandle[0] ?? null %}

In the above example, since we are accessing the first element in the array directly [0], if it doesn't exist, we will get an error (The first first() method is a bit smarter and will not throw an error). So, in the above example we have to explicitly plan for the situation of having no results using the null-coalescing operator ?? and falling back to null.

A longer form discussion of this scenario can be found in the article Examples of Eager Loading Elements in Twig and PHP.


Get entries relatedTo multiple categories

The relatedTo parameter's targetElement property has to be an ElementCriteriaModel or a single category model:

{% set featured = craft.categories.group('myCatGroup').slug('featured').first() %}
{% set caseStudies = craft.categories.group('myCatGroup').slug('case-studies') %}

{% set entries = craft.users({
    group: 'resource',
    relatedTo: [
        'and',
        { targetElement: featured },
        { targetElement: caseStudies }
    ]
}) %}


Most efficient way to check if a section has any active entries

You can use {{ craft.entries.section('whatever').total() }} for that.


What is appropriate for a Global field in terms of site speed?

I can't speak on the speed impact of having lots of content in the Globals, but the use cases you have described don't really seem suitable for Globals.

I would instead recommend creating Sections for each of these (Testimonials, Awards, The Team) and have an entry for each item.

We use the Globals section (for example) for setting the clients phone number, contact address, email address etc. Just little pieces of information that can be re-used. Quite considerably different to the large content sections you have described.


Stop specific Twig template from rendering anything

Depending on what you exactly need to happen, the {% exit %} (docs) tag my be an option for you.


positionedAfter only applies to entries within a structure section (https://craftcms.com/docs/templating/craft.entries#positionedAfter). See this answer for how to get next and previous entries.


Using a matrix Date/Time field to sort entries

So you're not getting your matrix field's value properly. You're going to want to access it the same way you'd output the data:

{{ event.dates.type('date').first().startDate.getTimestamp() }}

So what we're doing here is getting the dates matrix field, selecting the blocks that have a type of date, getting the first of those blocks (should be our only block but .first is still needed), then get the startDate field in that block. During my testing I found you needed something like .getTimestamp() or .atom() to turn the date into a string that SuperSort could understand (not sure why the examples in our docs don't use that, will definitely look into that though).

So something like this should achieve what you're looking for:

{% set pageEntries = craft.entries.section('events') | supersort('sortAs', '{dates.type("date").first.startDate.getTimestamp}') %}
{% for event in pageEntries %}
    {# event data #}
{% endfor %}

Hopefully that helps!

  Fwiw, I work for TopShelfCraft (who made the SuperSort plugin)


Date fields saving the wrong date from front-end form

You need to include a timezone parameter to your form in order to get the correct one.

<input type="hidden" name="postDate[timezone]" value="America/Los_Angeles">

If you don't include something like this in your frontend chances are high you'll receive the wrong time because it adds/subtracts a certain amount of hours. As soon as you include a valid timezone it will calculate the correct time. Otherwise it will be set to the default system timezone which may differ from your local


How do I tell Craft not to automatically crop user profile images?

You could add a custom asset field for the users' profile images and hide the default one in the CP.

Here's a plugin to do this: Control Panel CSS by Lindsey D


Next in structure if lightswitch field off?

If you are really trying to get the next field in order on an entry type:

Field order can't be set on an entry type's field layout. Craft seems to set their order when you create them in Settings->Fields. Whatever you are trying to setup/accomplish this way I would recommend against.

If you are trying to retrieve entries that the lightswitch field is off:

{% for entry in craft.entries.section('sectionHandle').all().lightSwitchField('not 1') %}
{{ entry.field }}
...

If you are trying to get the sibling of an entry if the current entry's lightswitch field is off:

{% if not entry.lightswitchField %}
    {% set sibling = craft.entries().nextSiblingOf(entry).one() %}
{% endif %}

I tried to give you several examples/solutions as your question isn't explicit.


Return entries with startDate or endDate within a calendar year

You could do two queries to get the Ids of the desired entries, merge the Ids and then query the entries with these Ids:

{# Get Ids of desired entries #}
{% set startDateIds = craft.entries.startDate('and', '>= ' ~ unixbegins, '< ' ~ unixends).ids() %}
{% set endDateIds = craft.entries.endDate('and', '>= ' ~ unixbegins, '< ' ~ unixends).ids() %}

{# Merge queried Ids #}
{% set filteredIds = startDateIds|merge(endDateIds) %}

{# Get entries with Id paramenter #}
{% set filteredEntries = craft.entries.id(filteredIds) %}

.

Another idea is to query all potential entries, loop those and filter within the loop. This is probably the way to go if you need to combine your conditionals with other logic then the and operator:

{# Get all potential entries #}
{% set allEntries = craft.entries.section('events').limit(null).find() %}

{# Define array before loop #}
{% set filteredEntries = {} %}

{# Loop all entries #}
{% for key, entry in allEntries %}

    {# Set conditionals to filter for desired entries #}
    {% if ( entry.startDate >= unixbegins and entry.startDate < unixends ) and ( entry.endDate >= unixbegins and entry.endDate < unixends ) %}

        {# Merge entries #}
        {% set filteredEntries = filteredEntries|merge({ (key): entry }) %}
    {% endif %}

{% endfor %}


How can I pre-select a product variant based on user profile?

Checkboxes fields (and other multi-select fieldtypes) return a MultiOptionsFieldData instance, not an array.

This should work:

{% if currentUser.userField.contains(purchaseable.myCustomField) %}


Can I setup multiple sites under one Craft install?

you definitely can, both in Craft 2 and Craft 3. I would recommend using Craft 3 (3.1 beta if you can) so you use the latest improvements available.

On Craft 3 you can set different Groups for different pages and then different sites within each group for the different languages.

I recommend this video, it helps a lot with the set-up and understanding how it works.

Anyway, I am not sure if you might need different license type for setting more than one site on production.


How can I start a loop at a specific number?

You definitely don't need JS here.

I'm  a bit pushed for time, so this won't be an epic answer, but e.g. with your select, you should not be using a hidden field for the qty.

The select itself just sets the quantity value - either 1 if the option is chosen or no value if the option is not chosen....it really is as simple as:

<form>

  {# primary item - use whatever input you like for qty, or just do it in a hidden... #}
  <input type="hidden" name="items[9999][purchasableId" value="{{ mainproduct.purchasableId }}">
  <input type="hidden" name="items[9999][qty]" value="1">

  {# accessories #}
  {% for accessory in accessories %}
    <input type="hidden" name="items[loop.index][puchasableId]" value=="{{ accessory.purchasableId }}"
    <select name="items[loop.index][qty]">
      <option value="1">Yes Please</option>
      <option value="0">No Thanks</option>
    </select>
  {% endfor %}

</form>

This will cause the following to be posted -
items[0][purchasableId] = 45

and depending on the user choice, either

items[0][qty] = 1 or items[0][qty] = 0

...and multiAdd will just ignore this if the qty = 0.

The key thing to understand is the value of the index is totally irrelevant as long as it is the same for the purchasableId and the qty - it just acts to join the data together - you could literally send:

items['TrumpIsInsane'][purchasableId] = 45
items['TrumpIsInsane'][qty] = 1

...and it should still work.  So for the primary product I just use something like 9999 so that I am sure it won't conflict with any of the loop indexes (I'm not going to have 10000 accessories eh?) -> it's just a made up number.

For completeness, radios would only be slightly different:

<form>

  {# primary item - use whatever input you like for qty, or just do it in a hidden... #}
  <input type="hidden" name="items[9999][purchasableId" value="{{ mainproduct.purchasableId }}">
  <input type="hidden" name="items[9999][qty]" value="1">

  {# accessories #}
  {% for accessory in accessories %}
    <input type="hidden" name="items[loop.index][puchasableId]" value=="{{ accessory.purchasableId }}"
    <input type="radio" name="items[loop.index][qty]" value="1" checked> Yes Please

    <input type="radio" name="items[loop.index][qty]" value=""> No Thanks

  {% endfor %}
</form>


How can I get the same random array key?

You need to create a common reference to the random number you are creating. Otherwise, you are getting a random number twice - and it's just luck that they show up as expected.

Try this:

{# Get all of the matrix blocks for the global set #}
{% set globalSet = craft.globals.getSetByHandle('madLibs') %}

{% if globalSet|length %}

    {# Find out how many matrix blocks exist #}
    {% set madLibsCount = globalSet.madLib|length %} // 2

    {# Generate a random array key. Remember array is zero based #}
    {% set range = range(0, (madLibsCount - 1)) %}

    {# Capture a single (random) number #}
    {% set key = random(range) %}

{{ globalSet.madLib[key].actualRole }}

{{ globalSet.madLib[key].pretendRole }}

{% endif %}


Insert a url segment without creating sections

From what I gather from your question you want some sort of sub-categorisation of your entries.

Such that one entry can have the URL as:
    siteUrl/section/subject-1/entry-slug

while another entry can have a URL as:
    siteUrl/section/subject-2/entry-slug

If that is what you want to achieve then you have to look into Structures instead of Channels

Here is the link: http://buildwithcraft.com/docs/sections-and-entries#sections

You can basically have multiple entries with sub-urls in the same structure section.


In case anyone is interested this is how I solved the problem:

First load the matrix field:

$addressMatrix = craft()->fields->getFieldByHandle("addressMatrix");

Then get all of the blocks of the matrix field:

$addressMatrixBlocks = craft()->matrix->getBlockTypesByFieldId($addressMatrix->id);

Next iterate over the blocks looking for a specific handle:

foreach($addressMatrixBlocks as $key => $data){

    if($data->handle === "address"){

    $addressBlock = $data;
    break;

    };

};

Now you have your block. To get the ID just do this:

echo $addressBlock->id;


The {slug} token you’re using there is going to get replaced with Craft’s slug pattern:

(?:[\p{L}\p{N}\p{M}\.\_\-]+)

Since that’s not an optional pattern, the resulting regex isn’t going to match your example URL, which doesn’t have a slug after the custom_id.

I’d recommend you use two separate routes that both point to the same template:

'action/<custom_id:[a-zA-Z][0-9]{6}>' => ['template' => 'action/_member'],
'action/<custom_id:[a-zA-Z][0-9]{6}>/<entrySlug:{slug}>' => ['template' => 'action/_member'],

(And just in case it wasn’t intentional, worth pointing out that the slug is going to be called entrySlug as opposed to slug with that route, which is another change from your Craft 2 route. Use <slug:{slug}> if you didn’t mean to change the name.)


Craft won't create the join table for you when specifying a MANY_MANY relationship.  You'll still need to manually create a record for that join table.  See Craft's own craft/app/records/UserGroup_UserRecord.php as an example.

What it will do, as mentioned in the answer you linked to is keep the data up-to-date in the join table without having to specifically reference it in your queries.


Plugin field-type not getting javascript variable?

Keep in mind Craft parses the html of your field, it won't be used directly, thus the ID of your field can't be "#"+startDateFieldHandleunless you ignored Crafts methods or modified it in another way. Your fields ID will be more like

id="fields-{{the id you specified}}"

Thus you should make sure you used the correct selector like

jQuery("#fields-"+startDateFieldHandle)

usually your order should be fine.. If you want to pass certain variables to Javascript you should do that in Twig because Craft::$app->View->registerJs($js); won't pass variables in a global scope (you can't access them in your JS files in certain cases).

However you should avoid using those globals in Craft. It's better to create a custom Garnish object for the logic

Craft::$app->getView()->registerJs('new Garnish.MyAwesomeField(id, options)');

That will make sure everything is initialized and ready to use
Your js could look like this

Garnish.MyAwesomeField = Garnish.Base.extend(
    {
        $theOtherField: null,
        $field: null,
        options: {},
        init: function (fieldId, settings) {
            this.options = $.extend({}, Garnish.MyAwesomeField.defaults, settings);
            this.$theOtherField = $('#' + this.options.fieldSelector + this.options.theOtherFieldHandle);
            this.$field = $('#' + this.options.fieldSelector + fieldId);
            this.addListener(this.$field, 'click', $.proxy(this, 'clickEvent'));
        },
        clickEvent: function(){
            alert( this.$theOtherField.val() );

        }
    },
    {
        defaults:{
            fieldSelector: 'fields-',
            otherFieldHandle: ''
        }
    }
);


Any plugins to add drop down for selecting template?

Short answer – no, there isn't any way to add a dropdown for template selection to Sections without modifying the core (which is never a good idea).

Beyond that, its difficult to advice without a brief description on what you're attempting to build. Craft is generally perfect for flexible, modular content and layouts, and what you want to achieve is most likely very doable – but I suspect your approach may be a little misguided.

Sections in Craft are the basic containers for your content, and creating a whole new Section should never be part of the basic editorial workflow.

If the OP provides a little bit more context, I'll try update this answer with a suggested approach.

EDIT:

Your problem is that you're using Singles – one of three possible Section types – as entries in a stream of content (events). This is not a feasible workflow. Singles are meant as one-offs; completely unique bits of content that doesn't fit anywhere else and needs its own, unique field layout and/or template.

Any content that is part of a stream, such as a blog post, news item or event listing should be published as actual entries to either a Channel or a Structure Section (in your case I'd use Channels for both news and events; the latter is only appropriate if you need to nest entries or put them in a specific order).

Using a Channel or Structure means that whatever template you specified when you created the Section will be automatically loaded for all its individual entries, and your client will also not need to re-create the field layout every time they want to publish something.

Obviously, with Craft Personal edition, you're limited to only one Channel – and you specifically need two. You have two options:

Upgrade to Craft Client/Pro. If you want to test it out before purchasing, see this page for info.
Delete the News channel and create a new, generic channel called "Content" or the like. Create two different Entry Types for the channel, called "News" and "Events". This would enable you to create different field layouts for news and event entries. In your channel's entry template, you could then do something like this:

{% if entry.type == 'event' %}
    {% include 'event.html' %}
{% else %}
    {% include 'news.html' %}
{% endif %}

Note that this solution will not really scale well at all, and the editorial workflow would also be subpar compared to having separate channels. I'd strongly recommend the first approach :)

Finally, I'm not familiar with ProcessWire and couldn't advice which is better for your specific project, although your site would be a doozy to set up in Craft – as long as you apply its concepts and tools the way they're meant to be used. Obviously, if you're coming from ProcessWire or any other CMS (like Wordpress or ExpressionEngine) it can take a little time to adapt to a different terminology, toolset and workflow and to absorb platform best practices. I'd advise you to read through the basic docs (they're quite concise) for a better understanding of how Craft manages content, and to give Craft Client or Pro a test run before deciding.


How can you choose which group to output first when using the group filter?

Rather than changing the order of the actual array returned by the group filter, you can just assemble a new array that has the keys in the order you want:

{# Get the grouped entries #}
{% groups = entries|group('foo') %}

{# Create an array of the group keys in the desired order #}
{% set keys = ['foo']|merge(groups|keys|without('foo')) %}

{# Now loop through the keys, rather than the groups directly #}
{% for key in keys %}

    {# Get the group with this key #}
    {% set group = groups[key] ?? [] %}

    {# Loop through the entries #}
    {% for entry in group %}
        ...
    {% endfor %}

{% endfor %}

(Note that the ?? operator requires Craft 2.6.)


Old post, I know, but we've recently published a plugin to achieve this for a similar problem we were facing.

SessionExposer plugin can help you achieve this. To get the Session ID in the template you use

{{ craft.sessionExposer.sessionId }}


Have a look at the Parsedown plugin by P&T, it provides a line mode to not output any wrapping <p> tags.

{{ entry.title|parsedown('line') }}


Bulk moving asset folders, from one source to another

I did this with grunt, using the grunt-aws-s3 task. It worked beautifully. If you are a gulp person, I'm sure there is something similar for gulp.


siteUrl works with an array of locales if you're using the actual siteUrl config setting.  What you're currently doing is creating a separate 'siteUrl' environment variable, which places in the control panel aren't expecting to be in array format.

More good info on the different ways to set siteUrl here.


How to compute UK style VAT in Craft Commerce?

Try unticking the This tax is already included in the taxable subject checkbox.

I would imagine that with this checked, Commerce assumes that the prices entered for products already have tax applied, so the tax amount is calculated on that basis, hence it being 1/6 of the total rather than 1/5.


Asset with related entry field in Matrix block

You said it yourself, the problem is that an Entries field can link to multiple targets. So it is an array of Entry Models you're given here, or more correctly, an ElementCriteriaModel.

To get the first linked entry's Url, all you have to change is to add the first method.

But you said multiple links are allowed, so to show them all go through them in a loop.

{% for imageItem in block.images %}
    {% for linkedEntry in imageItem.imageLink %}

            {{ imageItem.imageTitle }}

    {% endfor %}
{% endfor %}


How to get entries related to current category only (not children)

Since Apples and Bananas are children of Fruit, all entires that are related to Apples or Bananas are also related to Fruit, which is why you are getting the the results you are getting. If you need to exclude entries related to the subcategories, you can do something like this:

{% set dontInclude = [] %}

{% for child in craft.categories.descendantOf(category) %}
    {% set dontInclude = dontInclude|merge(craft.entries.relatedTo(child).ids) %}
{% endfor %}

{% set str = dontInclude|join(', not ') %}

{% set fruitEntries =  craft.entries({
    relatedTo: category,
    id: 'and, not '~str
}) %}

The above code will loop through Fruit's categories (Apple, Banana) and retrieve all the related entires and merging them into one array. Using the expanded craft.entries, you can exclude the entries related to Apple or Banana using the id: 'and, not' code. Hope this helps!


Display an entry's level 1 categories only if the entry is not related to any of that category's children

Collecting all of the categories' ancestors is probably the way to go in that case. So the solution you already posted within your question is more or less the same as I was about to post.

Instead of having a conditional in the output loop, you could also prepare an array of your bottom level category models using Craft's without filter (I always try to separate output from query / logic blocks in my templates).

This works with any number of category levels.

{% set allCategories = craft.categories.relatedTo(entry) %}

{% set ancestorCatIds = [] %}
{% for category in allCategories %}
    {% set ancestorCatIds = ancestorCatIds|merge(category.ancestors.ids()) %}
{% endfor %}

{% set bottomCatIds = allCategories.ids()|without(ancestorCatIds) %}
{% set bottomCategories = craft.categories.id(bottomCatIds) %}

    {% for category in bottomCategories %}

{{ macros.catBreadcrumbs(category) }}

    {% endfor %}

I made a macro that outputs the category breadcrumbs, to have even less logic in the output block.

{% macro catBreadcrumbs(category) %}
    {% set ancestorCategories = category.ancestors.find() %}
    {% set ancestorCategories = ancestorCategories|merge([category]) %}
    {{ ancestorCategories|join(' > ') }}
{% endmacro %}


How to check if entry field value is already outputted, and prevent it again?

Craft has a group filter, that does just that:

{% for stad, events in craft.entries.section('events') | group('stad') %}
    <option value="{{ stad }}">{{ stad }}</option>
{% endfor %}


Just upgraded to Craft 3, environmentVariables changed or stopped working

Environment variables don't exist in Craft 3 in the same way that they existed in Craft 2. Instead, they have been replaced with system environment variables and aliases.

The Changes in Craft 3 docs explain what changes have been made and the Environmental Configuration explains how you can set these up and use them.


Why does field value get updated on $element->getContent()->fieldHandle but not when accessed directly $element->fieldHandle?

setContentFromPost() performs an operation on the attached ContentModel, not on the element model itself.

When you initialize a BaseElementModel, its content attributes are set from the associated ContentModel. ("Content attributes" means attributes from custom field data, a.k.a. the stuff you'll typically find in the craft_content DB table for a given element instance.)

However, later updating the properties of the content model does not immediately ripple into changing the attributes of the element model: You'll need to re-save the element after you do a setContentFromPost(), and then its magic attributes will reflect your newly set values.

When you setContentFromPost(), you're changing the data that will ultimately gets passed into each FieldType's prepValueFromPost() method. If you need to do additional processing later (after each FieldType has done its thing) — such as saving records in an third-party table during onAfterElementSave — your service can use getContent() to or getContentFromPost() to grab the values it needs, depending on whether you want to access the raw POST data the user submitted, or the values that got returned from each FieldType's prepValue() method.


Formatting postDate using the ElementAPI plugin

$entry->postDate will give you the postDate property of the EntryModel, which itself is a DateTime object.

The JSON transformer will do its best to convert that object to JSON by returning its visible properties, which produces the JSON object in your example.

Angular has built-in date filters, but it requires the input data to be in a recognized format. So, what you really want in your JSON - rather than a representation of the whole DateTime object - is a more primitive value that Angular knows how to interpret as a date: You need a timestamp.

Luckily, you can easily access the timestamp of the PHP DateTime object in your transformer, like this:

'postDate' => $entry->postDate->getTimestamp() * 1000

(We're multiplying the timestamp by 1000 because Angular wants the timestamp to represent milliseconds; PHP gives us the timestamp in seconds.)

Then, in Angular you can use the date filter to change the format as desired, which in your front-end code would look something like: {{ note.postDate | date:'medium' }}


It appears to be due to the angle brackets. Try:

<script>
    var homepageStandfirstAnchors = [{% for anchor in homepage.homepageStandfirstAnchors %}[{{ anchor.text }},{{ anchor.section.handle }},{{ anchor.anchorLink }}],{% endfor %}];
</script>


Output all translation strings to javascript object

Not that I'm aware of. You would have to create a plugin that scrapes all of your template files for translatable strings, that then also makes those strings available to twig templates.


Multi-Environment Config using port in database server

Try using a port variable:

'STAGING' => array(
    'server' => 'localhost',
    'port' => '3939',
    'user' => 'myusername',
    'password' => '***********',
    'database' => 'mydatabase',
),


Ajax User registration sometimes forbidden 403 error

Can I somehow solve this?

Yes by creating a custom Controller. Because the default UsersController does the following

// Don't validate required custom fields if it's public registration
if (!$thisIsPublicRegistration) {
    $user->setScenario(Element::SCENARIO_LIVE);
}

without SCENARIO_LIVE custom fields won't be stored


Twig has a replace filter for that. You can replace strings/vars with strings/vars:

{% set string = "I love apples" %}
{% set var = "like" %}
{% set string = string|replace({'apples': 'kiwis', 'love': var}) %}

{{ string }} {# Prints "I like kiwis" #}

Your example:

{% set rgb = "Red; Green; Blue" %}
{% set rgb = rgb|replace({';': ','}) %}

{{ rgb }} {# Prints "Red, Green, Blue" #}


You shouldn't need to use string concatenation here:

.eventStartDate('>= ' ~ 2014 ~ '-' ~ 09)

If you're hard coding the year and month, just use:

.eventStartDate('>= 2014-09-01')


How Do You Create A Navigation Of Entry Types?

First, get your section. The following code will return you a SectionModel:

{% set section = craft.sections.getSectionByHandle('mySectionHandle') %}

Next, get the Entry Types off it. This will return you an array of EntryTypeModel objects:

{% set entryTypes = section.getEntryTypes() %}

From there you can loop through them to create your nav:

{% for entryType in entryTypes %}
    {{ entryType.name }}
{% endfor %}

You’ll want to create a Route which accepts those dynamic URLs (e.g. types/(slug)), and point it to a template like “types/_type.html”.

From that _type template, you can fetch entries of the requested type like this:

{% set type = craft.request.getSegment(2) %}
{% set entries = craft.entries.type(type) %}


Craft doesn't have an entry-level (or even entry type-level) permissions system; it's only possible to define permissions for sections.

Of course, "anything" is possible with a custom plugin, but without knowing more about your use case (what's the criteria for excluding group A or B for a particular entry?) it's difficult to advise further.

If you can edit your question and elaborate on the use case/goal, I might be able to update this answer.


Not sure if you saw this, but you may also be able to use the Twig attribute function:

{{ attribute(array, item) }}

Pretty straightforward, here's the official docs page...


Two things:

Make sure you're using false the boolean and not 'false' the string.
After you change useFileLocks to false, clear the craft/storage/runtime/cache folder as I believe that setting is cached for whatever the cacheDuration config setting is set to.


Retour only works if the 404 actually is handled by Craft; my guess is that your Nginx config somehow is not passing along the 404 to Craft.


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

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


How can I pull my Username into the transformer of the ElementAPI plugin?

I was able to pass the $username data to the transformer. By doing this:

'transformer' => function(EntryModel $entry) use ($username)


After updating, getting "Could not resolve the subpath" error

If you're setting an dynamic upload folder location for an Assets field inside of a Matrix field, you need to preface things like {slug} with {owner.slug}.

See the note about dynamic subfolders on an Assets field inside of Matrix here: https://craftcms.com/docs/assets-fields#dynamic-subfolder-paths


It's not just editing the .env file; you also need to modify the config to make use of those options; which is part two of that article you linked to.
You could also try adding a PATH variable to your .env which includes "/usr/local/bin" in it.
Update:
The .env won't override an existing environment var by default. In most linux server setups this isn't a problem because the "www-data" or "apache" user doesn't have that set by default.
For MAMP, local dev or vagrant development; that path is likely set. If you want your .env settings to overwrite existing settings; change the web/index.php file to use Dotenv\Dotenv::create(CRAFT_BASE_PATH)->overload();
instead of
Dotenv\Dotenv::create(CRAFT_BASE_PATH)->load();


Return the current section type? (plugin)

The SectionModel has a type property, which return what you're after, "single", "channel" and "entry". In a template it can be accessed like this:

{{ entry.section.type }}

If this is in a plugin and you have the section, you access it like this:

$section->type

But I'm confused by the "current page" of your question. Maybe you can describe in a bit more detail what you're trying to achieve, and what your code looks like atm?


Craft3, Plugin Craft Commerce, Tax without percentages

It's not currently possible to charge a fixed tax fee natively, it needs to be a percentage. You can however implement your own tax adjuster within a plugin or module, which is what Craft is doing under the hood.
You can specify an amount on the adjuster with a type of tax and it will then show on orders within Craft.


Unfortunately, you can't use Craft's built in relations service for reverse relations lookup with Super Table. This is because there's actually a special case for nested relations, such as a Matrix field. Craft's own relations service has special handling for Matrix fields, which we also need to make use of.

Fortunately, Josh Angell (the star that he is) has submitted a fix for this, without having to hack the core. You'll just need to alter your code to use the following:

{% set reverseRelatedElements = craft.supertable.getRelatedElements({
  relatedTo: {
    targetElement: entry,
    field: 'specialisms.linkToPage'
  },
  section: 'barristers'
}) %}

{% for relatedEntry in reverseRelatedElements %}
  {{ relatedEntry.title }}
{% endfor %}


Worldpay Offsite Gateway not redirecting to Customer Order screen on successful transaction

It turns out this installation is working as it should.  When I uploaded the website to a staging server and tested on it, it worked as expected.
 Redirecting me back to my Craft website, and showing the Customer Order screen whilst sending out relevant emails.

Not sure if it has been documented anywhere, but seems that this doesn't play ball when working locally.


Pull DateTime field using alternate timezone?

100% untested, but something like this should work:

Have your model override BaseModel's populateModel.
Find the DateTime field you're interested in and get its value.
Create a new DateTime object and pass in the value from the timeZone attribute.
Set the new DateTime object back on the original DateTime field.
Call parent::populateModel($values).


Craft won't set the entry variable automatically unless the route matches a particular entry. If you're sharing a template between routes that may or may not correspond to an entry, you need to make sure that var gets set explicitly by you if not automatically by Craft:

{% if entry is not defined %}
    {% set entry = craft.entries.section('myStructure').slug('calendar').first %}
{% endif %}


Filtering list in CP index page for new ElementType

In case anyone else comes up against this, here's what I did to fix it.

In my PluginName_MyElementType class which inherits from BaseElementType, you need to override the defineSearchableAttributes method, returning an array containing all the names of the properties of your Model which need to be searchable. So in my case it's just name. The reason you don't need to worry about adding title is it's already done for you under the hood, it's just that I wasn't using it in this case.

public function defineSearchableAttributes()
{
     return array('name');
}


What does the error "Use of undefined constant CRAFT_BUILD - assumed 'CRAFT_BUILD'?" mean?

Had a plugin installed which had been using CRAFT_BUILD and as its been deprecated it was throwing the error, problem was could access admin to update plugin.

Manually, entered CRAFT_BUILD and other deprecated info into craft/app/Info.php and it let me login to fix.


I am building my first multi-language site with Craft as well. This is from a thread over at Google+, so I didn't come up with this myself but it works very well:

{% block locale__switch %}

    {# Loop through all of the site locales, except the current one #}
    {% set otherLocales = craft.i18n.getSiteLocaleIds()|without(craft.locale) %}
    {% for locale in otherLocales %}

        {# Find the current entry in the other locale #}
        {% set localeEntry = craft.entries.id(entry.id).locale(locale).first %}

        {# Make sure that it's actually localized to this locale #}
        {% if localeEntry.locale == locale %}

            {# Output a link to it #}
            {{ locale }}
        {% else %}

            {# Output a link to the hompage #}
            {{ locale }}
        {% endif %}

    {% endfor %}
{% endblock %}

I set this up in a block to implement the switch in various templates. It loops through all the languages minus the current one and outputs the links. It also matches the entries by ID which is why you can have different slugs. Hope it helps.

Yay for the craftcms.stackexchange site!


How can I filter/find on an ElementCriteriaModel?

Update
I may have found a better option for you. Looks like you were on the right track after all, but with some quotes misplaced.

{% set entries = craft.entries.section('mySection') %}
{% set entry = entries.find({myFieldHandle:'mySearchVariable'})[0] %}
{{ entry.title }}

Although looks like this hits the database again (thanks carlcs).

Maybe back to the orginal answer then, which was:

{% set entries = craft.entries.section('mySection') %}
{% for entry in entries if entry.myFieldHandle == 'myVariable' %}
    {{ entry.title }}
{% endfor %}


No, the isEditable property isn't supported for Global Sets.

The confusing thing is that the GlobalSetModel class does actually have an isEditable property, however it will always return false. The reason is that this property is inherited from the BaseElementModel class, where it will return false unless the element type overrides it to (potentially) return something else. An example of the latter is the EntryModel class, which also inherits BaseElementModel but overrides  isEditable to test if the current user is allowed to edit the entry.

It'd be interesting to hear P&T's reasoning for not "enabling" isEditable for Global Sets, although to be honest – needing to give users the ability to edit global variables from the frontend sounds like an edge case at best, and probably not a very good idea.

On that note, my best advice for a workaround would be to simply use a Single instead of a Global Set.

However, if you need/want to use a Global Set, you can easily work around the issue by creating a custom plugin exposing a isGlobalSetEditable template variable method. Something like this should work:

public function isGlobalSetEditable(GlobalSetModel $globalSet)
{
    return craft()->userSession->checkPermission('editGlobalSet:'.$globalSet->id);
}

In your template, you could then do something like this:

{% if craft.myPlugin.isGlobalSetEditable(headline) %}
    Edit me
{% endif %}

If you're not familiar with plugin development, I'd advice you to check out the official docs on the subject, and to download the excellent Business Logic Plugin as a starting point – it even has a Variable class where the above isGlobalSetEditable method could be dropped right in.


What's the difference between {{ siteUrl }} and url()?

The siteUrl global variable is actually set by calling url() without passing anything into it1, so if you're asking about the difference between siteUrl and url() without passing a path to it, you will always get the exact same result. The only difference is that it will be ever so slightly more efficient to use siteUrl since that is a variable that has already been defined for you, whereas Craft will have to go through a bit of logic each time url() is called.

As for where to use which, it's mostly a matter of taste. The only time when siteUrl~"some/path" might differ from url("some/path") is if Craft is not set up to hide index.php in URLS - url() will be smart about how to output URLs with index.php and the path appended after it (either in the query string or path info, depending on the usePathInfp config setting).

There is a greater difference between the two in CP templates, though: in that context url() will automatically add the CP trigger to the path for you.

One last thing worth noting is that url() also provides some arguments for changing the schema (http or https) and appending query string parameters to the URL, whether you pass in a relative site path or a full URL. We've documented those features here: http://buildwithcraft.com/docs/templating/functions#url

1 or more precisely, UrlHelper::getUrl(), the PHP function that url() maps to


How to set selected elements when creating modal with "createElementSelectorModal()"?

If I'm interpreting 'craft.js' correctly, there doesn't seem to be any way to do this, at least not via craft methods. Apart from passing in the initial settings parameter, everything else looks like protected methods.

You could potentially do it manually through javascript however by triggering a 'click' event on the elements directly. You would have to wait until the elements are loaded first however.

$('.elements tr[data-id="2201"]').trigger('click');


Order entries by custom date and time fields

You'll want to change that startTime to field_startTime.

Anything in the orderBy gets passed directly onto SQL and Craft is smart enough to do the replacement for startDate behind the scenes, but columns in methods (like time()) or aggregate functions need to be manually prefixed.  This should work:

{% set allEntries = craft.entries.section('sparkSchedule').limit(null).orderBy('startDate asc, time(field_startTime)').all() %}


Do tuples exist in twig? If so, how can I create one?

None that I'm aware of.  Since Twig ultimately gets compiled down to PHP and PHP doesn't have first-class citizen support for tuples, you're limited there.  You can quasi-fake them with arrays and the list function, but I don't think there is a Twig equivalent for list.


Is There a Way to Add Tabs in Global Fields?

As far as my knowledge goes there is not a way to do this without some though changes.
Wouldn't it just be better to add another global and just name it settings?

Something like:

globalSettings(option1)

globalSettings(option2)

globalSettings(option3)

So that you organize them like that? Only thing you have to keep in mind then is when you use it in your template you have to keep track of which setting is used for what but if you name them right that wouldn't be an issue.