Get Related Entries and then filter those by specific category in url segment

We’ve built a plugin called Router that solves exactly this use case.

For the URL structure you described – domain.com/photographers/john-doe/food – this can be solved by the following configuration for the Router plugin:

/* config/router.php */

return [
  'rules' => [

    // URI pattern with named subpatterns
    '<placeholder:photographers>/<photographerEntry:{slug}>/<foodCategory:{slug}>' => [

      // array of filters that are activated when
      // the key matches a subpattern variable declared in
      // the route's regular expression
      'criteria' => [
        'placeholder' => 'section:photographerPhotos', // Base section
        'photographerEntry' => 'entry:photographers',  // Find slug in section
        'foodCategory' => 'category:food',  // Find slug in group
      ],

      // template file
      'template' => 'photographerPhotos/_entry',
    ],

  ]
];

And in the template:

{# photographerPhotos/_entry #}

{{ entries }} {# array of photos (related to both the photographer and food category) #}
{{ photographerEntry }} {# photographer Entry object #}
{{ foodCategory }} {# food Category object #}


Fetching "Pending" Users Related To Entry Within Plugin

As always, spent hours trying to figure this out and came upon the answer within an hour after posting the question on Stack.

Here's the working code:

    // get entry
    $entry = craft()->entries->getEntryById($entryId);

    // get ALL users related to entry
    $users = craft()->elements->getCriteria(ElementType::User);
    $users->status = null;
    $users->relatedTo = [$entry];
    $userIds = $users->ids();


Global-only fields adding columns to content table?

A field is a field, no matter where you are using it. It doesn't matter to Craft whether you attach your field to a Global Set or a Section (or Users or Assets)... All fields are treated equally.

Your fields can be shared between Element Types, and often are.


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


Segment to filter through categories slug

Try removing the ' ' from segment in line 2

e.g.

{% set pageCats = craft.categories('photoCategories').slug(segment) %}


Is there a way to send offsite backups of the whole site to Amazon S3?

You're in luck... Backup Pro for Craft was released just this week:

  https://mithra62.com/projects/view/backup-pro


Are you setting the requireShippingAddressAtCheckout and requireShippingMethodSelectionAtCheckout config variables to true?

https://craftcommerce.com/docs/configuration#requireshippingaddressatcheckout


Craft 2 uses the PHPMailer library to send emails and the first thing its addAttachment() method does is take the first $path parameter that's passed in and run PHP's is_file() on it.

is_file() won't work on URLs like you're passing in, it expects the file to be on the local file system, so you'll need to download it locally and pass in that path.

It won't show up on the model as an error using $email->getErrors() because the library catches the exception, does some internal logging and returns false.  Craft doesn't have a change to add that particular error back on its EmailModel.


Image thumbnail generation (on S3/Cloudfront integration) returns blank when first generated

Got the solution through Craft support, as well as this similar question: Image Transforms - Image not processed until second page refresh

In summary, use the generateTransformsBeforePageLoad settings in Craft CMS.

e.g.
project>config>general.php

<?php
/**
 * General Configuration
 *
 * All of your system's general configuration settings go in here. You can see a
 * list of the available settings in vendor/craftcms/cms/src/config/GeneralConfig.php.
 *
 * @see craft\config\GeneralConfig
 */

return [
    // Global settings
    '*' => [
        // Default Week Start Day (0 = Sunday, 1 = Monday...)
        'defaultWeekStartDay'  => 0,

    // Enable CSRF Protection (recommended)
    'enableCsrfProtection' => true,

    // Whether generated URLs should omit "index.php"
    'omitScriptNameInUrls' => true,

    // Image variant be created on Asset save (aka BeforePageLoad)
    'generateTransformsBeforePageLoad' => true,

    // The secure key Craft will use for hashing and encrypting data
    'securityKey'                      => getenv('SECURITY_KEY'),
],

To set that in specific environment, e.g. in Live only, copy and paste

'generateTransformsBeforePageLoad' => true, into the desired environment

e.g.

// Live environment settings
    'live' => [
        'devMode' => false,
        'generateTransformsBeforePageLoad' => true,
        'enableTemplateCaching' => true,
        'allowAutoUpdates' => false,
    ],


Rich Text Field is returning an empty object over api of plugin json_expand

I just came across this problem and solved it by editing the JsonExpandService.php file (located in craft/plugins/jsonexpand/services/) in two places.

Change line 101 from this:

$relatedArray[$subHandle] = $subValue;

To this:

if($subField['type'] == "RichText") {
    // Rich Text field values need to be converted to a string
    $relatedArray[$subHandle] = (string)$subValue;
} else {
    $relatedArray[$subHandle] = $subValue;
}

And change line 115 from this:

$entryData[$handle] = $value;

To this:

if($field['type'] == "RichText") {
    $entryData[$handle] = (string)$value;
} else {
    $entryData[$handle] = $value;
}

This fixed Rich Text fields coming through as empty objects for me.

This plugin hasn't been updated in 3 years, so Craft probably changed something about how Rich Text fields are outputted and the plugin never adjusted. Just a guess.


GZIP seems to compress only HTML, not CSS or JavaScript

You can use .htaccess config from HTML Boilerplate for better configuration. There are a lot of useful config option there.

I use this config to enable gzip compression in my personal blog, and it's worked perfectly.

<IfModule mod_deflate.c>

    # Force compression for mangled `Accept-Encoding` request headers
    <IfModule mod_setenvif.c>
        <IfModule mod_headers.c>
            SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
            RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
        </IfModule>
    </IfModule>

    # Compress all output labeled with one of the following media types.
    <IfModule mod_filter.c>
        AddOutputFilterByType DEFLATE "application/atom+xml" \
                                      "application/javascript" \
                                      "application/json" \
                                      "application/ld+json" \
                                      "application/manifest+json" \
                                      "application/rdf+xml" \
                                      "application/rss+xml" \
                                      "application/schema+json" \
                                      "application/vnd.geo+json" \
                                      "application/vnd.ms-fontobject" \
                                      "application/x-font-ttf" \
                                      "application/x-javascript" \
                                      "application/x-web-app-manifest+json" \
                                      "application/xhtml+xml" \
                                      "application/xml" \
                                      "font/eot" \
                                      "font/opentype" \
                                      "image/bmp" \
                                      "image/svg+xml" \
                                      "image/vnd.microsoft.icon" \
                                      "image/x-icon" \
                                      "text/cache-manifest" \
                                      "text/css" \
                                      "text/html" \
                                      "text/javascript" \
                                      "text/plain" \
                                      "text/vcard" \
                                      "text/vnd.rim.location.xloc" \
                                      "text/vtt" \
                                      "text/x-component" \
                                      "text/x-cross-domain-policy" \
                                      "text/xml"

    </IfModule>

    <IfModule mod_mime.c>
        AddEncoding gzip              svgz
    </IfModule>

</IfModule>


How to add a custom button at the right section of an entry?

You can add custom HTML in exactly the spot you’re hoping to, using the (undocumented) cp.entries.edit.right-pane template hook.

To use it, add this to your plugin’s primary class:

public function init()
{
    craft()->templates->hook('cp.entries.edit.right-pane', function(&$context) {
        /** @var EntryModel $entry **/
        $entry = $context['entry'];

        // Make sure this is the correct section
        if ($entry->sectionId == 5) {
            // Return the button HTML
            $url = UrlHelper::getUrl('some/path/'.$entry->id);
            return 'My Button!';
        }
    });
}


How do I maintain paragraph formatting on textarea Guest Entries submission?

RichText fields make use of the Redactor plugin library, which if I understand correctly, essentially parses line-breaks and wraps lines in properly formatted html <p> tags via javascript. However, when you save from the front-end, it doesn't have a chance yet to parse the data. Only when you view the data on the back-end and re-save does redactor get a chance to do it's thing.

You could use redactor on the front-end, although this is not recommended for various reasons as described here.
Or you could change the fieldtype to a regular textField and wrap everything in a <pre> tag in your template. <pre>{{ entry.myTextField }}</pre>
Or you could parse the string yourself via javascript before submitting it, wrapping your own <p> tags (hopefully it won't get double encoded).

There might be other options as well.


Craft newbie : can anyone recommend a simple image slider?

There's quite a lot missing from your code / question. I'll make some assumptions.

Your slider is on a the Home page of your site (not a single entry page/template)
Your have a Section in Craft called "News"
Your slides consist of custom fields within News, called: 'news cover image', 'title' and 'sub title'
You have an Image Transform configured in Craft called "News Slide"

Your code could then, look like this:

    {# Find the most recent 3 entries in the News Section #}
    {% set newsEntries = craft.entries.section('news').limit(3) %}

    {% for entry in newsEntries %}

        {% set image = entry.newsCoverImage.first() %}
        {% if image %}

{{ entry.title }}

{{ entry.subTitle }}

        {% endif %}

    {% endfor %}

The first Set tag finds the most recent 3 News entries (More info here...)

The For loop contains the slides and will loop x3 times.

The Set-image tag grabs the first asset (image) assigned to the "news cover image" custom field.

Let us know how you get on...


This conditional should work:

{# Saison Trigger #}
{% set saison = now|date('m-d') %}

{# Check for each Season #}
{% if saison > '11-22' or saison <= '03-21' %}
    {% set currentSaison = 'winter' %}
{% elseif saison > '03-21' and saison <= '06-21' %}
    {% set currentSaison = 'fruehling' %}
{% elseif saison > '06-21' and saison <= '09-22' %}
    {% set currentSaison = 'sommer' %}
{% elseif saison > '09-22' and saison <= '11-22' %}
    {% set currentSaison = 'herbst' %}
{% endif %}

You're right, Twig does just compare the strings. But this is totally fine in this case. A string representing a date and formatted like so "01-13" (don't forget the leading zero) works nicely with the comparison operators.


Something like this should work. I've also cleaned up the code a bit to be correct PHP syntax as my assumption is that you''ll be doing this in a module/plugin.

// Get all people entries
$entries = Entry::find()->section('people')->all();

foreach ($entries as $entry) {
    // If this was a "featured" historical person
    if ($entry->historical == 'featured') {
        // Change to featuredPeople entry type
        $entry->typeId = $featuredPeopleEntryTypeId;

        // Save entry
        Craft::$app->elements->saveElement($entry);
    }
}


Forgot Password - Success Message/Flash Message after setting new password on the login screen

The way I handle this is by simply includeing the same template as the login page and passing a Twig variable along with it.
So more specifically, my setPasswordSuccessPath is set to a unique template called password-was-reset, which has the following code in it and nothing else:
{% include 'login' with { passwordWasReset: true } %}
You can then read that variable in your login template like this - as you can see I'm also doing the same thing with my account activation template:
    {% if passwordWasReset is defined and passwordWasReset and errorMessage is not defined %}

Your password was reset successfully. Please login below.

    {% endif %}

    {% if accountWasActivated is defined and accountWasActivated and errorMessage is not defined %}

Your account was activated successfully. Please login below.

    {% endif %}

    ...

    <login form here>


Impossible to invoke a method ("getUrl") on a string variable ("60")

I think your problem is here:

{% set assets = artwork.pictures.first() %}
{% if assets | length %}
  {% for asset in assets %}

This sets assets to the first artwork.pictures, not to a list of assets, and then you try to loop over that single asset.

If you want a figure for every pictures of every selectedArtwork of your entry, try this:

{% set artworkPicture = { width: 475 } %}
{% set artworkPictureRetina = { width: 930 } %}

{% for artwork in entry.selectedArtwork %}
  {% for asset in artwork.pictures %}

  {% endfor %}
{% endfor %}

set artworkPicture and artworkPictureRetina once, outside your loop.
no need to use {% if ...|length %}. If the length is 0, the for loop will run 0 times.

If you want a figure for the first picture of every selectedArtwork, try this:

{% set artworkPicture = { width: 475 } %}
{% set artworkPictureRetina = { width: 930 } %}

{% for artwork in entry.selectedArtwork %}
  {% set asset = artwork.pictures.first %}
  {% if asset %}

  {% endif %}
{% endfor %}

If you want a figure for the first picture of the first selectedArtwork, try this:

{% set artworkPicture = { width: 475 } %}
{% set artworkPictureRetina = { width: 930 } %}

{% set artwork = entry.selectedArtwork.first %}
{% if artwork %}
  {% set asset = artwork.pictures.first %}
  {% if asset %}

  {% endif %}
{% endif %}


Custom Category order in a Categories Field

No, it’s not possible to change the order of related categories.

(Think of the field as a big checkbox list; you can change which checkboxes are checked, but you can’t change their order. The only reason it’s not a simple checkbox list is to save visual space.)

If you really want to be able to set the order, you can put the Categories field inside a Matrix field, where each block selects a single category, and then you can reorder the blocks.


Connection between twig template and website content

Yes, I think what you're saying is completely correct.

Settings > Sections > Homepage > Edit entry type

The "layout" here is only meant for the back end. This is just how you assign fields you want entries in that section to use and what it will look like for admins to create and edit entries.

Settings > Sections > Homepage

Will show you what template is being called when there's a match for that URI.

In the file system, your template files will be located in either /craft/templates if you're using Craft 2, or just templates if your using Craft 3. It's probably worth noting that these directories are usually above the web root.

For example:

.
├── craft
├── templates
└── web <-- web root
    └── index.php

If you're afraid of breaking things on a live site, you could create a duplicate of the site and run it locally or on another server. That's a great way to sandbox changes and play with things to see what effect they have.

Another great way to learn how Craft works is to try out the "Happy Lager" demo site. It's a pretty simple Craft site and well organized. I've see live production sites that are incredibly complex or over-engineered. I can't imagine trying to learn Craft with one of those as my only example.


Entries field templating only when entry is added

You'll need to do something like this. entry is a How to videos entry.
{% set relatedProducts = entry.productsEntryField.all() %}

{% if relatedProducts|length %}
    {% for product in relatedProducts %}
        Click here to view
    {% endfor %}
{% endif %}

The Craft docs on Entries Fields has more info.


With $craftPath you set the path to the craft/ directory (containing the app/ folder etc.) whereby your index.php is the starting point if you set this as a relative path:

// Path to your craft/ folder
$craftPath = '../relative/path/to/craft_dir/';

As narration_sd pointed out, the craft/ directory should be above the web root for security reasons. But this doesn't mean that you cannot have your index.php at http://example.com/corp/index.php. Just configure $craftPath accordingly. For example:

Laravel at web root:
/var/www/laravel-site/public/index.php

Craft in a subdir:
/var/www/laravel-site/public/corp/index.php

Craft app above web root:
/var/www/craftsite/craft/app/index.php

Craft's path config:
$craftPath = '../../../craftsite/craft';

Remember to also update the paths to your assets in the Control Panel and the paths to your files linked to in your templates.


I fixed it - there was a stuck task preventing the stale template cache from being deleted.


Problem is: so far as I can tell, nobody's written the book.

That's partly our fault... we've never really documented the Attribute parts of Models and Records.  And it probably won't happen now since the majority of that has been stripped out of the upcoming Craft 3 making it much easier to follow Yii 2 conventions (which happens to be way more documented).

  What is the Name type used for?

In the context of a Record, it's a shortcut for saying you're going to get a varchar datatype set to 255 chars.  In the context of a Model, it'll just enforce the 255 character limit.

  What's the difference between Handle and Slug? Why choose one over the other?

A handle is a varchar(255) that has a few pre-defined reserve words.  id, dateCreated, dateUpdated, uid, title.  Currently used in Craft for defining the handles that things like Asset Sources, Global Sets, Asset Transforms, etc. uses.

There isn't a AttributeType::Slug.

  What exactly does Template do, and why does it need its own type?

It's just a shortcut for a varchar(500), currently used in Craft when defining a template path for Category and Section settings.

  What's the difference between Url and Uri? Is it just the validation?

Semantically, a URL is a subset of a URI: https://danielmiessler.com/study/url-uri/

In the context of Craft, yeah - the only practical difference is the validation.


So it seems the way to do this is actually by leaving the slug blank. If you happen to look down on the section setup screen prior to naming your section you'll see it clearly: Leave blank if this is the homepage. However since that field is automatically filled in with details from the Name/Handle fields I never actually saw the text by the time I was down there unless I completely cleared the field out.

Both fields need to remain empty from what I can tell, not just the slug.


This is highly dependant on how the fields and templates are set up.

You don't say how you are creating the link. Craft makes no assumptions as to how you are going to be entering content. It's entirely down to the developer to set up the fields and templates according to your needs.

Do you have a text field specifically for entering the link? If there is no accompanying field to add a title then it's most likely you will need to add one and then modify the template to output that field in the title attribute of the link.

If you are adding a link within a Rich Text field then you should be able to edit it from within there. Though if this were the case I don't know why you would have a default value being used.

Either way, it should be a very minor task for a developer to fix.


Craft Nitro PHP extension ext-zip * is missing

You'll want to run that composer create-project command from inside of your Nitro VM. If you run it on your host machine, it'll use whatever version of PHP your host machine has installed.
Do this:

Make sure Composer is installed in the VM by running nitro install composer from the host machine. https://craftcms.com/docs/nitro/commands.html#install-composer

SSH into the box by running nitro ssh. https://craftcms.com/docs/nitro/commands.html#ssh

Run composer create-project craftcms/craft to get a fresh new Craft project inside the VM.


Error sending email: Process could not be started [The system cannot find the path specified. craft cms

Error sending email: Process could not be started

That error means that you've got sendmail selected as the mail driver for Craft under Settings->Email in the Control Panel, but the sendmail executable is either not installed or configured properly on your server.

  Also, I don't see the file structure they mention on this article, I found the error log on storage/logs/web.txt.

That's correct... the article was written for Craft 2 and you're using Craft 3. The log paths changed a bit between the two versions.

  I've tried also changing my email to SMTP with Outlook credentials to no avail.

I'm guessing you got a different error then?  I'd suggest setting up Craft with a transactional email provider like https://postmarkapp.com/ or https://sendgrid.com/.

There are Craft plugins for each (https://plugins.craftcms.com/sendgrid and https://plugins.craftcms.com/postmark), they'll be more reliable than sendmail and easier to setup than SMTP.


Complex custom SQL query with multiple relationships (Craft DB)

I'll be happy to see the SQL answer if anybody posts it but I expect this is a very complex query to write manually for anyone without advanced SQL knowledge.

While this isn't an answer that solves the immediate question, I think a fair answer is that this type of query is complex enough that it probably makes sense to build a custom solution (as it sounds like you did) or wait until Sprout Reports (or another alternative exists) that makes it easier to extend the plugin to run more programmatic or memory-intensive queries for use cases like the one you describe.


Is it possible to allow a user choose tags in admin panel using checkboxes?

Any reason why you'd choose tags over categories?

Categories seem to be more of what you're describing:

  Eventually, every single required tag will be created at some point.

And since Craft 2.5, authors can easily create categories right in the Entry screen as well as pick the category they want if it's already created. No manual typing required if it already exists.

Tags are usually looser approximations of the content and are considered by content strategists to be more of a "folksonomy".

If you wanted to push forward with checkboxes as tags, you could probably create a custom field that spits out all the tags as checkboxes, along with a way to add new ones.


Check number against 2 seperate fields and return the entry that matches

Think you've just got a logic error in your Twig code.  This should work:

{% set userInputtedNumber = 3000 %}

{% set entries = craft.entries({
    section: 'channel',
    numStart: '<=' ~ userInputtedNumber,
    numEnd: '>=' ~ userInputtedNumber,
}) %}


In between borked update attempts, are you restoring the database to the pre-update state? By default, Craft will create a database backup and place it in the craft/storage/backups folder during an update that you can use.

If you look at your craft/storage/runtime/logs files you'll be able to 1) see the error that originally happened to cause the failed update and 2) see the error that's preventing the CP from loading.


Found it (at last). The thing was that the . before .htaccess was removed when copying the files to the /it/ folder on OSx


Take a look at the shuffle function provided by Craft: https://craftcms.com/docs/templating/functions#shuffle

This will shuffle the complete array and output them all in the new order:

{% set img = [
    { bildli: 'http://i.giphy.com/I0xDz0htjsiME.gif' },
    { bildli: 'https://i.giphy.com/fA3JALhIi5YVa.gif' }
] %}

{% set shuffledImages = shuffle(img) %}

{% for item in shuffledImages %}

{% endfor %}

If you want to just output one random image, then this should work:

{% set img = [
    { bildli: 'http://i.giphy.com/I0xDz0htjsiME.gif' },
    { bildli: 'https://i.giphy.com/fA3JALhIi5YVa.gif' }
] %}

{% set randomImage = shuffle(img) | first %}


So If you still have everything on your machine, the thing going wrong here is the composer install bit. It looks like you have installed composer locally inside the folder but not globally. You have a file called composer.phar inside you happylager.test folder.

The way you have composer at the moment (locally), you cannot do composer install in your terminal you have to do php composer.phar install from within you happylager.test.

This should sort it for you and you will get the vendor folder from it. Then, simply follow the other steps to installing the demo. I strongly recommend you install composer globally though, it'll be easier for you in the future :)


Commerce PDF error: Image not found or type unknown

Try setting:

'pdfAllowRemoteImages' => true,

in your commerce.php config file.


I would make this decision based on what makes the most sense for the client. You can realize both solutions on a technical level, so it's really just a question about the preferable CP user experience.

For me this sounds like "Big News" and "Small News" are quite similar, so I'd probably like to have them combined in a single channel. And your template conditional is a good way to handle the manually (accidential?) typed in URLs.

You could even add a dedicated source for the entry index views by making use of the modifyEntrySources hook and some lines of custom plugin code. See this Stack Exchange Q&A for how to do this: Filter entries by entry type in the CP?


Order entries, exclude 'the' from order criteria

Completely untested, but try something like this:

{% for entry in craft.entries.section('hotels').order('(CASE WHEN title LIKE 'The %' THEN SUBSTRING(title, 4) ELSE title END )') %}

MySQL's LTRIM isn't what you want because that just removes leading spaces.  SUBSTRING should do it, though.

Also, keep in mind this is a MySQL specific query.  If you ever planning on running on PostgreSQL (that the Craft 3 beta supports), it would have to be adjusted.


Exporting site configurations for import to new websites - separate databases

Sounds like a great use-case for Project Config!
It's a file-based representation of your site's settings and information architecture without the content.
Get your boilerplate Project Config setup, then copy the config/project files to a new site and use it as a starting point.


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


Craft 3 Redirect after login based on User field

I believe you could use Freeform's Element Connections to create a user registration form. In the form's Return URL setting it looks like there's some options to create some logic with {{ submission.id }}.


If you're worried about malicious characters in an uploaded file name, Craft already sanitizes them when uploading from the control panel.

Craft doesn't do this during Asset indexing because generally it's assumed that the files you're uploading are trusted files.

It sounds like that might not be true in your case, though. I can think of two options.

Write a Craft plugin that loops through all files in your upload folders and calls the same AssetsHelper and IOHelper sanitizing methods that Craft does.
Find some desktop application that does it before you upload the files. A quick Google search turned up this for OSX, and this for Windows.


Controller redirect not working in craft 3

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


Okay, so this is a really weird one. On a hunch the host decided to change all permissions to their default 755, and now everything works! I'm left scratching my head but there it is. Not quite sure how those permissions impact Craft security but at least it's not 777, which I was worried they'd need.


VAT not being removed when adding a number to businessTaxID

Commerce, by default, uses this library for VAT validation.

That library is just a wrapper for a European SOAP endpoint for these types of things at http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl

The error code MS_UNAVAILABLE that endpoint can return says:

  The Member State service is unavailable, try again later or with another Member State;

So I'm guessing an invalid member state was selected, or they are having some technical difficulties on their end.


I probably don't fully understand what you're trying to acchieve, but to get to the index page of your current locale, you'd simply use siteUrl().


The {% cache %} tag only caches the HTML output.  That's it.

In your example above, nothing is cached, and categoryProducts will be an empty set.

One thing you could do is to cache each entry individually:

{% set categoryProducts = craft.entries.section('products').relatedTo(category) %}
{% set categoryProducts = shuffle(categoryProducts) %}

{% for entry in categoryProducts %}
    {% cache globally using key 'product-' ~ entry.id %}
        ...
    {% endcache %}
{% endfor %}


What's the right way to create a simple blog in Craft?

A Channel called Blog as follows:

Entry URL Format: blog/{slug}
Entry Template: blog/_entry

In blog/_entry.html:

{% extends "_layout" %}
{% set title = "{{ entry.title }}" %}

{% block content %}

{{ entry.title }}

        {{ entry.body }}

Written by {{ entry.author }} on {{ entry.postDate|date('M d, Y') }}

{% endblock %}

You don't need to create a Single for the Blog index page.

You can just create a template file: blog/index.html with:

{% extends "_layout" %}
{% set title = "Blog" %}

{% block content %}
    {% for entry in craft.entries.section('blog').find() %}

{{ entry.title }}

            {{ entry.body }}

Written by {{ entry.author }} on {{ entry.postDate|date('M d, Y') }}

    {% endfor %}
{% endblock %}

EDIT:

If it is a requirement for end users to be able to publish and edit content, other than blog entries, appearing on Blog index page via the CP, then a Single is the way to go.

Create custom field(s).
Create Single called Blog Index, or Blog Homepage, or something other than Blog.
Add custom field(s) to Blog Single entry type.
Entry Template: blog/index

In blog/index.html:

{% extends "_layout" %}
{% set title = "Blog" %}

{% block content %}
    {{ entry.customField }}

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

{{ entry.title }}

            {{ entry.body }}

Written by {{ entry.author }} on {{ entry.postDate|date('M d, Y') }}

    {% endfor %}
{% endblock %}


You could create a "Matrix Block" and make 3 type of blocks in there:
Discovery task, Website task and Assets task. If you give these blocks the fields they should need they just add whatever block they need and fill it in the way they like. You can loop over these blocks so they get displayed.

They can be filled in differently for every "Client Portal"

You can find more info about matrix blocks here:
https://craftcms.com/docs/matrix-fields

The Craft CMS Documentation is really good especially if you are just starting its really helpfull as it got all the basics and even more you need to build a website with Craft.

There is also a "Craft CMS Slack" where alot of developers discuss craft and ask questions daily so you can have a more direct explanation and probably a faster response.

https://craftcms.com/community#slack


I know it's been a minute since you asked this question, but just in case - I encountered this same issue - the correct credentials but still not able to connect with the db.php config file. I changed "localhost" to "127.0.0.1" and that seemed to work, or at least get me to the next snag that I hit. Cheers!


Listing All tags - and linking them to list of entries with that tag

You don't have a setting in Craft to make Tags have their own pages automatically. So what you have to do instead, is to set up a dynamic route in Settings → Routes. Create a new route which routes these URIs: blog/tags/[slug] (drag the slug token into the URI field) to a template blog/_tags.html.

In your blog/_tags.html template you will now have a slug variable available, but you still need to query for the tag model / entry models.

{% set tag = craft.tags.slug(slug).first() %}
{% if not tag %}{% exit 404 %}{% endif %}

{% set entries = craft.entries.section('blog').relatedTo(tag).limit(null) %}

{{ tag.title }}

{% for entry in entries %}
{% endfor %}

I'd also modify the tag listing to only show tags that are actually related to an entry, and use the tags' (undocumented) slug property for SEO purposes:

{% set entries = craft.entries.section('blog').limit(null) %}
{% set tags = craft.tags.relatedTo(entries).limit(null) %}

{% for tag in tags %}
    {{ tag.title }}
{% endfor %}


Craft Commerce: Sub total before tax in cart?

As of Commerce 1.1.1212, cart.itemSubtotalWithSale is deprecated.

Use {{ cart.itemSubtotal|currency(cart.currency) }} instead.

{{ cart.itemSubtotalWithSale|currency(cart.currency) }}


Trouble with Restrict to Single Folder and Upload Location

Since you're inside the context of a Matrix block, you'll want to use:

{owner.slug}

instead of:

{slug}

More information on that http://buildwithcraft.com/docs/assets-fields#dynamic-subfolder-paths


First, you would need to create an app for your Facebook page. You are also going to need a Facebook developer account: developers.facebook.com. Once your app is created and you have a Facebook developer account, I would recommend starting with the Facebook open graph explorer: developers.facebook.com/tools/explorer. With the explorer, you can build/debug your URL to add to Placid. The documentation for the Graph API is here: developers.facebook.com/docs/graph-api


How to set base URL on the installation of Craft CMS on server

Create a new web server to host your Craft project. Its document root should point to your public HTML folder. If you’re using Craft’s Composer starter project, then it is the web/ directory by default, but it can be renamed to anything you want as long as your web server is configured to point to it.

If your web host already has a public HTML folder setup to for you that you cannot rename, then you can just copy the contents of Craft’s web folder to it and use your host’s default public HTML folder.


Problem saving new entry populated with setContentFromPost() while setContent() works

I believe that setContentFromPost can only be used to set the content of custom fields on an EntryModel, not standard fields such as title.

Instead, you need to use $entry->getContent()->title to set the title on the EntryModel.

So your code would look like this:

$movie = [
  'movieID'       => (int)$ctx_movie['MOVIE_ID'],
  'audioLanguage' => $ctx_movie['SPRACHVERSION'],
  'country'       => $ctx_movie['COUNTRY'],
  'director'      => $ctx_movie['DIRECTOR']
];

$entry = new EntryModel();
$entry->sectionId = craft()->sections->getSectionByHandle('movies')->id;
$entry->typeId    = craft()->sections->getSectionByHandle('movies')->type('movie')->id;
$entry->authorId  = craft()->userSession->getUser()->id;
$entry->enabled   = true;

// Set the title directly on the $entry
$entry->getContent()->title = $ctx_movie['VERANSTALTUNGSTITEL'];

// This should now work:
$entry->setContentFromPost($movie);

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


Grouping/sorting for easier view of Craft::log messages

Your plugin can keep its own log using MyPlugin::log('Message', LogLevel::Error);. A log method gets created automatically by extending BasePlugin. The plugin log will be located in craft/storage/runtime/logs/ along with the default logs.

As a side note: The log files can be watched from the command line using tail -F /full/path/to/log/file rather than having to constantly reload the log in a text editor. Although apparently some text editors also support live updates as well.


Could you add your own field to use as a slug?

When you edit an Asset Source in Settings you get the Field Layout tab same as you do for Entries. You could maybe add something there and then combine this with a Route somehow?


I wonder about efficiency.

You're right to worry.  Doing this from PHP (even if you break it up into multiple SQL queries to get the data you need) is going to be much faster and less resource intensive than doing it from Twig.

One thing I'd look at though, instead of querying data directly against the database, is to see if you can get what you need going through Craft's services in craft/app/services/.

That way you don't have to worry about your plugin breaking in the event that the underlying database structure changes during an update.


How long to wait until license modal stops appearing?

Your production website shouldn't have been complaining about a different website using the same license key, as long as the license key is bound to the production websites domain name...
To get rid of the error, you can clear your Data caches. You can do this by navigating to Utilities > Caches in your Control Panel, and there you can unselect all but Data caches. Once you clicked Clear Caches, you reload the page and the message(s) will be gone.


Categories field limit doesn't disable Add a Category button

The button is still there and enabled but if you try to add a second category, you'll find that it just replaces the initial one.


Sprout Email: Notification unable to create "Craft\WebApp.userGroups

This issue has been resolved in Sprout Email v1.0.4


onBeforeSaveEntry listener to add/modify data of some fields

See Brandon's post on this here:
What is getContent() / the ContentModel, and how do I use it to get and set custom field values?

Basically when you're setting new custom field values, you should use setContentFromPost

$entry->setContentFromPost(array(
    'latitude' => $json->results[0]->geometry->location->lat,
);


Sprout SEO: How to access meta fields assigned to globals?

To manage global meta data settings, we recommend using the Meta Defaults. They have all the supported fields and can be accessed by admins in the Control Panel.

The Sprout SEO Meta fields only work with Entries right now, so unfortunately, the data they store will not be usable if they are added to a Global Set.

While I understand these following items aren't exactly what you are looking to do, here are a few steps that could help customize the user experience:

Sprout SEO allows you to rename how the plugin is named in the interface. So you could update the plugin name to just use 'SEO' to help a client associate the SEO tab more specifically with the role of updating SEO meta data.
If you'd have various things setup in Globals and feel that you'd like to somehow tie in the Meta Defaults to that area of your Control Panel, the Sprout Fields plugin has a Notes Field that allows you to add a field that allows you to add more detailed documentation or links to a Global Set.


URL rewrites not working return Apache 404's

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

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

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


Adding more cell types to the Table Fields isn't possible without a plugin. Even with a plugin it's probably not possible to simply extend the default field. I tried to do this and couldn't find a way to extend upon the javascript necessary to add or delete rows.

So to make more cell types possible I ended up copying the complete Table Field code from Craft core into my plugin.

"Event Table"

Someone might ask what this is good for, you could use Matrix instead!
Sure, but sometimes you're in the need for another hierarchy level or you'd simply opt for the cleaner, more compact view of a table field for your date or time inputs.


How do you add tags to tag field when saving an entry?

Like other relational fields, Tags fields’ values need to be set to an array of the tags’ IDs.

It’s not possible to create tags during entry creation; you would just need to create it first using TagsService::saveTag().

$tag = new TagModel();
$tag->groupId = 1;
$tag->getContent()->title = 'My Tag';

$success = craft()->tags->saveTag($tag);

if ($success)
{
    $tagData = array($tag->id);
}
else
{
    $tagData = null;
}

// ...

$entry->setContentFromPost(array(
    // ...
    'myTagsField' => $tagData,
));

// ...

(Note that I’m setting the field value using setContentFromPost() instead of directly on the ContentModel. This is the recommended way to set your custom field values, although for relational fields it doesn’t really matter either way.)


How can I call a controller method from the front-end using ajax

Make sure to check out the documentation on routing. Pay special attention to the part about action request(s).

In this example, I want to call a controller method via ajax on page load.

MyPluginController.php

...

/**
 * Checks what the current status is RIGHT. NOW.
 *
 * @throws HttpException
 *
 */
public function actionCheckStatus()
{
    $this->requireAjaxRequest();

    $response = [
        'status' => 'open'
    ];

    $this->returnJson($response);
}

...

jquery

$.ajax({
    'type': 'post',
    'contentType': 'application/x-www-form-urlencoded; charset=UTF-8',
    'cache': false,
    'data': data,
    'url': '/actions/pluginHandle/checkStatus',
    'dataType': 'json',
    'timeout': 50000
}).done(function (response) {
    // Success
}).fail(function (error) {
   // Total fail.
});

The key part to note is the url attribute in the ajax request. It is prepended with 'actions'. As you will note in the docs you can change 'actions' to whatever you want.


There's not a native Craft way to do that.

You could setup a cron job that hit a plugin's controller and delete items in cache based on size/date created, etc.

My guess is you've got a plugin installed doing some heavy caching. You can try opening the largest cache files (it's all just serialized text data) and see if the type of data gives you a clue to where it's coming from.


Ordering homepage posts by date, but give customized ordering option in CP

For me this looks like a perfect fit for one structure with different entry types for each of your content types (text, video and recipes). Each entry type can have it's own set of fields, so there's no difference to individual channels (with one entry type each).

You can simply have the entry type's handle in your URIs, as the {type} tag is available in section URL settings (→ see help article), or you'd set up custom dynamic routes.

Via the entry's entry.type property you can include individual template partials for each entry type on your index page:

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

{{ entry.title }}

        {% include '/blog/_partials/' ~ entry.type %}

{% endfor %}

Same for your _entry.html file:

{% include '/blog/' ~ entry.type %}

And I've heard that structures with many hundreds or thousands of entries is no problem for the control panel. I think it was Craft 2.0 that had many optimizations in that respect.


Are you using PHP 5.5?  If so, opCache is enabled by default and that’s probably causing your issue.


Get entries whose title has a keyword or related to a category's title

You would have to create the relatedTo condition manually first and then pass it in to the orWhere method. This is untested, but should get you on the right track.

Reference the _applyRelatedToParam() method in the ElementQuery class:
https://github.com/craftcms/cms/blob/3.1.26/src/elements/db/ElementQuery.php#L1724-L1727

$keywordCategory = Category::find()->title($keyword)->all();

$parser = new ElementRelationParamParser();
$relatedTo = $parser->parse($keywordCategory);

$entries = Entry::find()
    ->where(['title' => $keyword])
    ->orWhere($relatedTo)
    ->all();


Changing the frontend sorting according to different fields

Use Categories for Teacher & Country.  Add inputs for those categories to your Section.

To create your select inputs:

{% set entryIds = craft.entries.section('events').ids() %}
{% set teachers = craft.categories.relatedTo({ sourceElement: entryIds }).group('teacher').find() %}
{% set countries = craft.categories.relatedTo({ sourceElement: entryIds }).group('country').find() %}
<select>
  {% for item in teachers %}
       <option value='{{ item.title }}'>{{ item.title }}</option>
  {% endfor %}
</select>
<select>
  {% for item in countries %}
       <option value='{{ item.title }}'>{{ item.title }}</option>
  {% endfor %}
</select>

Then when you submit these as a form or via javascript on your filtered page you would do something like this.

{% set filterId = craft.request.getParam('id') %}
{% set events = craft.entries.section('events').relatedTo({targetElement:filterId}).startDate('and', '>= ' ~ now) %}

If you needed to filter for more than one category group:

{% set entries = craft.entries({
    section: 'events',
    relatedTo: [
        'and',
        { targetElement: craft.request.getParam('teacherId') },
        { targetElement: craft.request.getParam('countryId') }
    ]
}) %}


how to output all images in an entry's loop

You should use .all(), but that will give you an array of Assets. You can't call .getUrl() on an array, so you'd have to loop that array:

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

        {% set images = entry.startbilder.all() %}

        {% if images |length %}
            {% for image in images %}

            {% endfor %}
        {% endif %}

{% endfor %}

If you'd want to eager load the images, this is how you'd do it:

{% for entry in craft.entries.section('projekte').with(['startbilder']).all() %}

        {% if entry.startbilder |length %}
            {% for image in entry.startbilder %}

            {% endfor %}
        {% endif %}

{% endfor %}


Is it possible to use useEmailAsUsername and see User Relations Fields display as First Name + Last Name?

Currently, there isn't a native way to do that, but I can see where it'd get confusing.  I'll add it to our list to look into.


Sort by MatrixBlock Field / Eager load Matrix Field

After digging through some code I found out, that the MatrixBlockElementType just returns a content table (which is necessary for the eager loading part), if a fieldId is given:

$criteria = craft()->elements->getCriteria(ElementType::MatrixBlock);
$criteria->type = 'mytype';
$criteria->fieldId = 90;
$criteria->order = 'field_mytype_myfield';

$blocks = $criteria->find();

Like this everything seems to work as expected and I'm again in love with crafts flexibility :)

Am I right that I have to pass in the id? I can't do it via the field handle 'mymatrixfieldhandle', correct?


Perhaps you could have a local/internal Craft install and then regularly run a script that crawls the site and saves all the pages as static HTML. Tools like HTTrack already do a pretty good job of this.

Or there are static cache plugins like Blitz that you might be able to utilise. They’re designed for caching, but if you warm the cache you might be able to export the static files for uploading to your host.

UPDATE: Blitz 3 makes this possible. Read the announcement at:
https://putyourlightson.com/articles/blitz-3-embracing-the-jamstack


How to add content to pages using a plugin?

If you are able to place a hook tag in all templates then you could register a new template hook method in your plugin.

Twig:

{% hook 'my-custom-hook-name' %}

Your plugin:

Craft::$app->view->hook('my-custom-hook-name', function(array &$context) {
    $context['foo'] = 'bar';
    return '
Hey!
';
});

For injecting CSS or JS you would use

\Craft::$app->getView()->registerCssFile("file.css");
\Craft::$app->getView()->registerJsFile("file.js");

If you can't modify the template files to place a hook tag there you could dynamically generate the markup in your JS file, depending on your use case.


Is there a way to add instructions directly on a entry index screen in the CP?

Check out this plugin, it allows you to add text (instructions) as a field:

https://github.com/thomasthesecond/EntryInstructions


Is it possible to compose a DateTime object from a string?

In Twig, the date_modify filter returns a DateTime object. Also, date is not just a filter, but also a function. The date function accepts any a DateTime object or a string in a supported format, and returns a DateTime object. Example:

{{ date("+2 years") }}

This should give you a DateTime object set for 2 years from when it's triggered.

Why is localeTime missing?

The now variable is not a regular DateTime object from PHP. It's actually an extended class ( \Craft\DateTime ). So it won't have all the convenience functions you get from now or a date field from an entry. Instead you would need to do it manually (I'm not sure if you can overwrite a function or filter in Twig). Fortunately, the locale's format string is available as a variable.

{% set myDatetimeString = '2014-06-24 23:40' %}
{% set format = craft.i18n.getTimepickerJsFormat() %}
{{ myDatetimeString|date(format) }}

You can even shorten it like this:

{% set myDatetimeString = '2014-06-24 23:40' %}
{{ myDatetimeString|date(craft.i18n.getTimepickerJsFormat()) }}

To replicate localeDate, use this:

{% set myDatetimeString = '2014-06-24 23:40' %}
{{ myDatetimeString|date(craft.i18n.getDatepickerJsFormat()) }}


Why will my custom "Entries" field not display anything?

You need to put the entry in a for loop. Because even if there's only one entry linked to, it could still potentially be multiple entries!

{% for entry95 in entry.story1995 %}
    {{ entry95.title }}
{% endfor %}


Allow anonymous submission on a custom element type?

Ok, so I finally figured it out. The trick was using the following two methods:

assembleLayoutFromPost()
setContentFromPost('fields')

The controller now looks like this:

public function actionSubmit()
{
// require POST
$this->requirePostRequest();

// assume new element type
$elementtype = new PluginName_ElementTypeModel();

// assign the attributes specific to the element type
$elementtype->formId    = craft()->request->getPost('formId');
$elementtype->fieldName1 = craft()->request->getPost('fieldName1');
$elementtype->fieldName2  = craft()->request->getPost('fieldName2');

// if form id does NOT exist
if (!$elementtype->formId)
{
    // @TODO figure out how to return errors/validation
    dd('need a form id');
}
// if form id exists but we can't find it in the system
elseif (craft()->elementtype_forms->getFormById($elementtype->formId) == null)
{
    // @TODO figure out how to return errors/validation
    dd('form does not exist');
}

// setup a new form model
$form = new PluginName_FormModel();

// shared attributes
$form->id = $elementtype->formId;

// set the field layout
$fieldLayout = craft()->fields->assembleLayoutFromPost();
$fieldLayout->type = ElementType::Asset;
$form->setFieldLayout($fieldLayout);

// set content from post with the fields namespace
$elementtype->setContentFromPost('fields');

// Save it
if (craft()->elementtype->save($elementtype))
{
    $this->redirectToPostedUrl($elementtype);
}
else
{
    dd('not saved');
}

}

The main difference was on the front-end where I namespaced the fields that were assigned via the field layout, so the template to submit looked like this:

<form id="plugin-form"guinname method="post" action="" accept-charset="UTF-8">
    <input type="hidden" name="action" value="pluginname/submit">
    <input type="hidden" name="redirect" value="pluginname?submit=success">
    <input type="hidden" name="formId" value="1">

<!-- Required Fields -->
<label>Field 1
    <input type="text" name="fieldName1" />
</label>
<label>Last Name
    <input type="text" name="fieldName2" />
</label>
<!-- End Required Fields -->

<!-- My Custom Fields -->
<textarea name="fields[body]" rows="8" cols="40">OMG IT WORKED</textarea>

<button type="submit">Submit Now</button>
</form>


There's a long discussion of all of this in the Handling Errors Gracefully in Craft CMS article, if it helps.


Commerce 2, currently in beta, does support subscriptions, but right now it's only when using the Commerce Stripe payment gateway plugin.

If you're using a different payment gateway that supports subscriptions, you'll have to write a custom Craft/Commerce plugin and you can use the Commerce Stripe one as a starting point.

The relevant Commerce subscription documentation lives here:
 https://docs.craftcms.com/commerce/v2/subscriptions.html


I want to know if I can interface Craft address details into DPD shipping site

Probably depends on exactly what you're looking to do, but it does look like DPD has some APIs you can integrate with: https://www.dpd.com/nl_en/business_customers/help_en_tools/labelprint_tools/dpd_integration_services

Assuming that's the case, you'd be able to write a Craft/Commerce plugin to pull the data out that you need and interface with their APIs.


Minimum database privileges for Craft front-end?

Short answer, no. You'll want to make sure that your DB user has all of the necessary privileges.

Just because you're not entering your data into the database doesn't mean that Craft isn't writing its own data into the database. There are several tables responsible for handling data which is automatically generated by Craft, and not managed directly by admins.

For example:

craft_sessions records user sessions, to know who is currently logged in.
craft_assettransformindex saves any image transforms which have already been triggered.
craft_templatecaches, craft_templatecachecriteria, and craft_templatecacheelements store data from templates which use the {% cache %} tag.

And there are probably others that I'm missing.

Bottom line... Craft needs to be able to write to the database just as much as you do.


URL Format of a nested structure with 3 or more layers

Set the Nested Entries URL format to:

{parent.uri}/{slug}


Getting a entry link created by current User

You need to fetch the entry with one() keep in mind in order to be able to be an author the user needs the permission to create entries in that section

{% set myEntry = craft.entries.section('userProfiles').authorId(currentUser.id).one() %}
My Profile

You should also consider to code defensively and check if there is a current user and if myEntry is not null


How do I set up the Rich Text Editor Field (Redactor) for code snippets?

Not sure if it helps, but I accomplished this using a plain text field (with multi-line enabled). Then I just used CSS to format the field in a way to make it look like a code snippet...

Screenshot of field in the Control Panel:

I used the Control Panel CSS plugin to add this CSS:

#fields-myfieldhandle textarea.nicetext {
    font-size: 13px;
    font-family: Menlo, Monaco, monospace, sans-serif;
    color: #cccccc;
    background-color: #222222;
    padding: 14px 16px;
}

Then, in my Twig template, I display it like this:

{{ block.code|e }}

May or may not be the solution you're looking for, but I've been very satisfied with it!


Is it possible to make Craft/Twig throw 404 if a template can't be found?

Here's one way to do it – not super elegant, but it works:

{% set template %}
    {{- include('sometemplatethatdoesntexist', ignore_missing = true) -}}
{% endset %}

{% if not template %}
    {% exit 404 %}
{% endif %}

{{ template }}


Default locale in console commands is always en_us rather than the site default

Turns out this is actually a bug, too.

It's going to end up being more involved to fix than a build release probably warrants, though, so it'll have to wait for the upcoming 2.3 release to get a proper fix.

In the meantime, you'll be able to get by with your workaround of manually setting it.

$c->locale = craft()->i18n->getPrimarySiteLocale();


hasDescendants() is only concerned with whether the entry actually has descendants; not whether they are enabled or not.

To determine in an entry has enabled descendants, you can do this:

{% set hasDescendants = entry.descendants.total() %}

Or in your case:

<li class="{% if nav_item.descendants.total() %}more{% endif %}">

entry.descendants is an alias for EntryModel::getDescendants(), which will return a new ElementCriteriaModel prepped to return descendants of entry. By default it will only return the enabled ones, like all ElementCriteriaModel’s.


Check if Assets Field Contains File of Type

See kind in the docs: https://craftcms.com/docs/templating/assetfilemodel

I haven't tried it but I suspect it's something like this:

{% set file = assetsField.first %}
{% if file.kind == 'image' %}
  // blah blah
{% endif %}

There's also extension but kind is probably better here.


How can I make a template output its own filename?

You can get the current template’s name like so:

{{ _self.getTemplateName() }}


What is the table `templatecachequeries` for?

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

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

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


Get the location and id of asset volumne

Of course it is. You can get the volume as you want, for example

{% set volume = craft.app.getVolumes().getVolumeByHandle('images') %}

Of if you have an asset

{% set asset = craft.assetFieldHandly.one() %}
{% set volume = asset.getVolume() %}

And output the information

{{ volume.path }}
{{ volume.id }}

if {{ volume.path }} contains an alias you can do {{ alias(volume.path) }} to display the resolved path


Craft.log showing Buggy iconv installed. Will fallback to mbstring

Iconv is a system C library that converts string encodings, and is generally preferable to PHP’s mb_convert_encoding() because it supports significantly more character encodings. However it’s not guaranteed that it will be available, and if it is, some versions of it have a bug that could put it into an infinite loop in certain circumstances. So Craft’s StringHelper::convertToUTF8() checks for those things before using it, and logs if it’s not available or a buggy version is installed, before falling back on mb_convert_encoding().


I would try adding the following to your feed-me.php config file:
<?php

return [
    '*' => [
        'clientOptions' => [
            'verify' => false,
        ],
    ],
];

c.f. https://github.com/craftcms/feed-me/issues/479
As noted here, this is generally not a very secure practice but should be fine if you're just wanting to import a local file.


Well I found the way lurking into source code. You can see a

{# Give plugins a chance to add other panes here #}
{% hook "cp.entries.edit.right-pane" %}

Even though this hook is not listed in official documentation, you can access using the craft()->on() syntax, so I did this inside my plugin class :

public function init() {

    parent::init();

    craft()->templates->hook('cp.entries.edit.right-pane', function(&$context) {

        // do stuff here
    });
}


Sure, you can do something like

{% if not craft.request.isAjax() %}
  {% redirect siteUrl %}
{% endif %}


proc_open() has been disabled for security reasons

Your host has likely added proc_open to your php.ini file's disable_functions setting.

If you have access to it, you can remove it from that setting.  If not, you'll have to ask your host to do it.

You can see that Craft requires the PHP proc_* methods to be able to perform some operations here: https://docs.craftcms.com/v3/requirements.html#optional-php-methods-and-configurations


Freeform allows you to send email notifications 5 different ways (all of them each being able to have their own notification templates, etc).

For setting up Admin Notifications specifically, follow these instructions:

  Email notifications can be sent to one or more admin email addresses. To setup:

  In Composer interface for the form, click on the Admin Notifications (envelope icon) tab at the top right.
  Select and/or add an email template.
  Specify admin email address(es) in the text area below. Separated multiples by line breaks only.

As for actually choosing between database-based notifications or HTML file-based notifications, setting them up, etc, you can check out the documentation here.


Whenever I've had a completely white screen from Craft I've traced it to a syntax error in one of the files in craft/config, so I'd double-check your db.php and general.php if they've been edited.


I might be wrong here, but I don't think a model can be used to save entries. You populate a model, then populate a record with that model and save it. Once saved, you get data from the db as a record, then populate a model with it to pass that to a view, for instance.

If everything works as it should, a record is never used outside the service.


Re-using entry types across multiple sections

Entry Types are unique to their Sections. You can't have one Entry type shared between multiple Sections. You can however use Field Groups to set your Field Layouts for each Entry Type. This will remove the need to add each and every field individually to each Entry Type.

More info on Field Layouts can be found on the docs.


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

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

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


You're using $criteria, but attempting to set the relatedTo property on $this->criteria.

Assuming that's not the issue, have you tried using $criteria->setAttribute('relatedTo', ['targetElement' => $category])?

I've found setAttribute to be more reliable than the ElementCriteriaModel magic methods.


Send email with dedicated SMTP settings from a Craft 2 plugin

So basically I solved it like this, but couldn’t apply other SMTP settings than the global ones. But we did a workaround with the replyTo-address, so practically we are fine. If someone knows how to apply other SMTP-settings, feel free to answer. Thanks!

namespace Craft;
$email = new EmailModel();
$emailSettings = craft()->email->getSettings();

$email->toEmail   = $_REQUEST['email'];
$email->replyTo = 'test@test.com';
$email->subject = "Subject";
$message = "...";

$email->body = $message;

craft()->email->sendEmail($email);


Well, you can do:

{# Get segment 2 from the URL #}
{% set company = craft.app.request.getSegment(2) %}

{# Get content where myCompanyField matches segment 2 #}
{% set entries = craft.entries.section('mySection').myCompanyField(company).all() %}

But I need to know more about the structure of your content.


How can I link to a controller and return/redirect with data?

$_SERVER['HTTP_REFERER'] should give you the url the request was coming from, which you can then pass in to the redirect function. You could add some URL parameters like ?message='Logged%20out!' and have your template check for the message existing and display it.

Be aware that this function comes with a small caveat from the PHP documentation:

  The address of the page (if any) which referred the user agent to the
  current page. This is set by the user agent. Not all user agents will
  set this, and some provide the ability to modify HTTP_REFERER as a
  feature. In short, it cannot really be trusted.

Here's the full documentation on the PHP $_SERVER array.

Edit: Other Option Using a Form

It might be a little bit clunky, but you would have the like to logout actually be a form submit. You could post the current URL to your controller and use craft()->urlManager->setRouteVariables(array('message' => $myMessageObject)); to send your message back to the user.

Form:

<form method="post" action="" accept-charset="UTF-8">
    <input type="hidden" name="action" value="{{ actionUrl('pluginHandle/controller/method', { return: 'this/page/url' }) }}">
    <input type="submit" value="{{ 'Log out'|t }}">
</form>

All you'll need is a little bit of CSS to style the submit link, or even somme javascript to trigger the form submit. If you wanted to get even fancier, you could AJAX the request and avoid the form all together.

Here's the documentation on posting to controller actions for reference.


{% requirePermission %} with OR condition

The {% requirePermission 'perm1' %} tag only supports a single permission. Behind the scenes it's effectively the same as:

{% if not currentUser.can('perm1') %}
    {% exit 403 %}
{% endif %}

So I think either what you already have, or this:

{% if not currentUser.can('perm1') and not currentUser.can('perm2') %}
    {% exit 403 %}
{% endif %}

<!-- Your page stuff -->

Is probably your best bet at the moment. Checking that the user doesn't have both permissions, is the same as checking they do have one or the other.


How to rearrange the order of blocks of a single matrix field using a frontend form?

Your sort order will change according to your HTML, so when you change your html, the sort order will change. You can use certain Javascript libraries to move your containers in your DOM, when you save the entry, your related entries will change.

As for every relation field in Craft, you only have to insert an array of ids to relate the elements.

<input type="hidden" name="fields[galleryBlock][{{ block.id }}][landscape]" value="{{ image.id }}">

Is wrong because you insert the id of an image, not an array

<input type="hidden" name="fields[galleryBlock][{{ block.id }}][landscape][]" value="{{ image.id }}">

is the correct way


Yeah... that won't work.

Craft currently uses the URI segments to determine special path like logging in, out, etc.

So when Craft sees account as the first segment in the URI, its going to treat that as a login request and execute what's in UsersController->actionLogin(), which will see that you're already logged in, and will eventually hit this if the user doesn't have CP access permissions:

// Otherwise send them wherever postLoginRedirect tells us
$postLoginRedirect = craft()->config->get('postLoginRedirect');
$returnUrl = UrlHelper::getSiteUrl($postLoginRedirect);

Which, you've got set to account, then it rinses and repeats given you the infinite redirect loop.


you cannot access the CP with that account

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


Filter locations by country in Smart Map

What I've done to do something very similar is to add a template variable to my BusinessLogic plugin, that takes the ElementCriteriaModel, prepared with all other parameters e.g. section, limit and SmartMap set. The plugin then translates the model into a Yii CDbCommand using buildElementsQuery, adds the additional conditions to the query and returns the further filtered entry models to the template.

Here's my service function with modifications for your country filtering needs. It#s untested but should probably work as is:

public function addCountryCriteria(ElementCriteriaModel $criteria, $country)
{
    $query = craft()->elements->buildElementsQuery($criteria);

    // Add where condition for country filter
    $params = array(':country' => $country);
    $conditions = array('smartmap_addresses.country = :country');

    $query->andWhere($conditions, $params);

    // Join addresses table to bring in the state
    $query->leftJoin('smartmap_addresses smartmap_addresses', 'smartmap_addresses.elementId = entries.id');

    // Get query results and populate entry models
    $results = $query->queryAll();

    return EntryModel::populateModels($results);
}

Also have a look at my other answers on how to add conditions to CDbCommand from the template:

How do I select entries that have a particular block type?
Filtering Matrix through field value and multiple relations


I know the problem here is solved, but I thought I'd just leave a link to a pretty decent intro to using Craft and Vue 2.0 for future reference...

Using Vue 2.0 with Craft CMS

And specifically the part addressing the problem above:

It’s all about the mustaches

NOTE: I'm not the author of the blog post, just found it useful.


Craft CMS Backing React FE using the element API

I created a react native app with Craft CMS (still version 2.6) as backend using the Element API. But you're right, user authentication is not supported by the Element API. However, I created my own plugin to get user authenticated. I even create user and update their details through the app.

But storing user sessions in React Native is another story. That has nothing to do with Craft or any other CMS system cause you can't get server session to React Native. You need to write your own session handler. I remember a good blog post about that topic: https://auth0.com/blog/adding-authentication-to-react-native-using-jwt/.

There also might be other solutions because this could be a little bit overkill.

Hope this helps you as a first start.


We solved it like this...

We created a Users field called “Article Authors”, for that Articles section. And there unlimited users could be selected as “Authors” of the entry (for search results, relatedTo, etc...). Each article typically multiple authors.

But we assigned only 1 author as the only one with real editorial access, as the “owner”, so: basic Craft behavior.

We thought this would be limiting, but actually it turns out, in practice, it’s pretty good to have only 1 person in-charge with end-responsability. It’s clear where it lies, and he/she will communicate with the team before changing things. This: in contrast with 5 authors being able to acccess and edit an article, which we thought would be a good plan, but in reality isn’t. This forces them to communication amongst themselves and it’s clear who’s responsible.

Plus with the custom Users field, you basically maintain all functionality you want related to the entry.

We have about 250 articles now running with over +1500 author members, and have not got any complaints.


Obviously it's going to depend on each specific project, and I can only talk from my own (store owning) perspective, but over the years I have evaluated and installed and played with just about every ecommerce system of significance on the planet today.  The ones I've spent most time with are BigCommerce (in it's self hosted form before it went SAAS), EE & CartThrob, and Craft Commerce.  I'm not going to slag off Magento as such or very specifically - although as I go through my points it should be clear I though about all of these with Magento, and found them lacking or painful...

Here are the reasons I chose Commerce, roughly in order of importance:

Pixel and Tonic - more than anything else, I think it was the considered, open and intelligent approach of Pixel and Tonic - that I carefully observed from 2012 to 2015 - that convinced me it was a solid, well thought our platform backed by some exceptional people.
Content driven ecommerce - basically, there are two types of systems in the world - either commerce systems that have a little CMS bolted on, or content systems with a little shop thingy bolted on.

For me it's essential that content, and absolutely great management of it, be the main thing.  BUT, I also do want a great shop on top of that - with integration between the two that feels completely transparent and natural.  This means, in essence, that a first party solution to both problems is ideal.  When you have separation between the two, it always feels bolted on and shoe-horned in (see CartThrob or WooCommerce as prime examples).

The fact is pretty much anyone can set up an online shop right now and if all you want are product grids with pretty pictures, and lots of discount options, and simple (but simplistic) integrations to popular shipping services, then Shopify or similar is your obvious option.  But if you want substantial, useful content (and anyone that wants to compete with Amazon etc really should!) - then you need a content driven approach.  Expertise & Service are the keys to successful long term commerce in a world of box moving mega-discounters.
The ExpressionEngine (i.e. Content Modelling) foundations  - before coming to Craft/Commerce, I was considering (and implementing) CartThrob with ExpressionEngine.  And if I am truthful it's the fact that Craft grew from this approach - but then vastly improved on it - that gave me the motivation to spend serious time evaluating it (credit where it's due - Craft, like everything else, stands on the shoulders of giants).

I fundamentally think structured content modelling is the key to excellent content management, which is fundamental to 'more-than-average' shops....see above.
Matrix - the problem with structured content is that it can be TOO structured for long form content - you simply can't have a dedicated field for absolutely everything - and so where you DO want to write longer form content, it tends (on lesser systems) to be that everything just gets dumped in a WYSIWYG.

Matrix (and Supertable/Neo/etc :) ) - is the (so far) best solution to this problem.  It gives you a structured-within-longform-content approach that is second to none.  You can build very flexible page assembly systems using structure where you really need it and freedom where you don't.  Which means you can build some wonderful content driven ecommerce stuff very quickly.
Cost & support.  Magento - while open source and sort of free in a community supported sense/version, superficially looks good value.  But if you add real support - the kind you need if livelihoods depend on things - it becomes fiercely expensive.  P & T support is fast, unlimited, generous and easy to access.
Ease of implementation.  Craft & Commerce, with Twig, is easy.  It's really, really simple and logical to write your templates, and Craft always seems to behave in natural, expected ways.  The more time you spend with it, the less gotchas you need to worry about.  It's that rare system that gets better with familiarity.  Magento has a reputation for being absolutely labyrinthe in scope and difficulty in terms of template implementation.  I've heard the term 'horror show' used more than once.
Flexibility - Whilst Commerce doesn't support a lot packaging, shipping stuff etc out of the box, and where it does the implementation can feel a bit basic, the inherent simplicity of Craft plugins (and V3 looks to improve on this further a lot!) - means you can implement just about anything you need easily.  In my experience for complex stores off the shelf things rarely meet real needs anyway - so what you really need is a well though out architecture for extension.
In terms of product & variation management, Commerce, like Craft itself, is wonderfully flexible and yet simple.  You can create elegant, responsive content entry systems for your editors with ease, and separate your data concerns in sensible, long term maintainable ways.  It nails content management as well as anything I've been able to find.

Personally, I think neither of them are good solutions for very simple stores - there are simply cheaper, polished, off the shelf things that do that well.  No - these systems are for complex, bespoke e-commerce, where a substantial investment of time and money is used, to make something a bit special.  For my money, Commerce is the flexible, powerful content driven approach that nails this problem.  And Magento (in my limited experience of it) is an over complex, over priced, frustrating to work with alternative.

Apologies, this is a bit of a ramble.  Someone should come along and write a 'The Commerce Advantage' to match the Craft one...but hopefully this helps a bit!


Assigning the right license to the right subdomain

Technically 3 separate Craft installations would require 3 separate/unique Craft licenses even if they share the same root domain (site.com) and live off in subdomains off of that (a.site.com, b.site.com, c.site.com).
If any of the sites are using the same config/license.key file, you could delete the duplicates and load the updates page in the control panel. A new one tied to Craft Solo will be generated and you can purchase Craft Pro updates for each individual site.

Not a problem as such, but the same domain for all seems a bit imprecise.

It's a bit ironic in your case because the reason we currently only track the root domain is to let all subdomains of that root domain be able to share a single config/license.key file for a single Craft installation in a multi-site setup.
Using the notes field in your Craft ID account is probably be best way to keep them sorted.


No.  Yii's extensions and Craft's plugins are different things, although it's not that difficult to port a Yii extension to a Craft plugin.


How to list all existing values for a field across site

To get better performance you need to switch to using PHP. All you need is a MyPluginVariable class
to do some logic in PHP and make the result available to your Twig templates. It's really not very complicated.

From your variable class you'd use Yii Query Builder to create your SQL statements. There's now two ways to approach this.

Start from fresh using craft()->db->createCommand() and add all the necessary parameters manually (section, locale, limit,...).
Pass a Craft criteria model with all parameters already set to the buildElementsQuery method to convert it.

I'll show you exampe code for the second approach. From your template prepare a criteria model as usual, set the section and other parameters. Then call the new template function we are going to create soon, which will take two parameters, a criteria model and a field handle.

{% set criteria = craft.entries.section('books').order('myYearsField desc').limit(null) %}
{% set years = craft.businessLogic.getDistinctValues(criteria, 'myYearsField') %}

Now we need to create this getDistinctValues method in our variable class.

public function getDistinctValues($criteria, $column)
{
    $query = craft()->elements->buildElementsQuery($criteria);

    // Modify query to select just our `$column` column, only distinct values
    $query->selectDistinct("field_{$column}");

    // Query for one column only and return the result
    return $query->queryColumn();
}

That selectDistinct parameter overrides the select set by Craft in the initial criteria model. Performance should be way better, you're querying for a single column only, only for distinct values and you don't populate entry models which you do not need anyways.


Re-downloaded manual update, and pushed to the server via ftp again fixed the issue. Download might have been corrupt is my only thought.


UPDATE:: I set the route for events/past BEFORE the route for events/{slug} and now the events/{slug} route does not interfere with the events/past route (that i did not even think should be necessary in the first place, nor did i know that the order mattered, is this intentional or a bug?

Update 2 I've resolved the issue by wrapping everything in a for loop instead of using set like so:

{% for entry in craft.entries.section('events').slug(slug).status('live', 'expired') %}

Doing the set as listed above did not work. So my pages are now working but i'd still like some clarification on the routing, the set, and the slug issues i was having regardless. Although everything is working it almost feels like i'm doing a work-around rather than how it's SUPPOSE to be done.


Permissions at field level. Can this be done?

Not natively, but there's the Control Panel Body Classes plugin, which would enable you to add the handle for your "eventeers" User Group as a CSS classname to the <body> tag (i.e. body.usergroup-eventeers, if "eventeers" is the handle for your User Group).

With that classname in place, you could add some CSS to the Control Panel (easiest done w/ the CPCSS plugin) to hide the particular field, e.g. w/ something like the following:

body.usergroup-eventeers #fields-yourFieldHandle-field {
    display: none;
}

...or, if it makes sense, you could flip it around and have your field hidden by default, and visible only if the <body> has the .userlevel-admin classname - which would in effect hide the field from everybody except people w/ admin accounts:

#fields-yourFieldHandle-field {
    display: none;
}

body.userlevel-admin #fields-yourFieldHandle-field {
    display: block;
}

(Obviously, you'll need to change the yourFieldHandle part for the field's selector to your field's actual handle.)

In any case, keep in mind that this will not be a secure solution in the sense that the field will still be there, and any tech-savvy "eventeer" user can easily make the field appear by removing the above CSS rule in their browser's dev tools. However, in the current iteration of Craft it's as close as you'll come to accomplish what you want.


How to apply a discount on cart weight ?

It would probably be best to make your own shipping adjuster. I have attached an example plugin here: http://jmp.sh/wC95ZPj

The adjuster plugin I have linked can look at the weight of the cart, it's line item contents, and then reduce (or add to) the shipping costs after the regular shipping calculations are run.


This isn't the appropriate place for such a request. You can however register for the Craft CMS Slack where there is a #jobs channel.


Is it possible to use an existing field into a matrix?

You can use the neo Plugin or you can copy and paste the field settings manually from one field to your matrix field in your database interface. In your craft_fields table there is a column settings you can search for your field handle and copy the settings to your new field.

You'll not be able to do this without a custom plugin or copy pasting the values via SQL in any way


How can I force a request type (HttpRequestService::isCpRequest vs. HttpRequestService::isSiteRequest)?

There's no setRequestType() method or the like, no. The HttpRequestService will consider any request with the cpTrigger in its URL a control panel request, and I don't see any easy way around that.

It's a bit convoluted, but what you could do is to wrap whatever code you're currently executing in your entries.onSaveEntry in a controller action method, and then use Guzzle in your onSaveEntry event handler to trigger a site request (i.e. a request without the cpTrigger in the URL) to that action.

Here's how your controller action could look:

<?
namespace Craft;

class MyPluginController extends BaseController
{

    protected $allowAnonymous = ['actionGenerateIndex'];

    public function actionGenerateIndex ()
    {

        // Get entry (based on a ?entryId URL parameter
        $entryId = craft()->request->getParam('entryId');
        $entry = craft()->elements->getCriteria(ElementType::Entry, [
            'id' => $entryId,
        ])->first();

        // ...your code to generate the index data here

    }
}

Here's how you could fire off a request to this action using Guzzle, stripping the cpTrigger from the action URL to make sure Craft treats the action as a site request:

craft()->on('entries.onSaveEntry', function (Event $e) {

    // Get entry
    $entry = $e->params['entry'];

    // Get action URL, strip the `cpTrigger` segment
    $actionUrl = UrlHelper::getActionUrl('myPlugin/generateIndex', [
        'entryId' => $entry->id,
    ]);
    $actionUrl = str_replace(craft()->config->get('cpTrigger').'/', '', $actionUrl);

    // Request action
    $client = new Guzzle\Http\Client();
    $request = $client->get($actionUrl, [], [
      'headers' => [
        'X-Requested-With' => 'XMLHttpRequest',
      ],
    ]);
    $request->send();

});


Method for pulling entries that have a specific image linked?

You can use relatedTo for that:

{% set entries = craft.entries.section('mySection').relatedTo(myAsset) %}

Or

{% set entries = craft.entries({ section: 'mySection', relatedTo: myAsset }) %}

Check out the documentation on relationships.


Prevent craftcms caching CMS page with dynamic template

The {% cache %} tag does not exclude dynamic data.

What it does, is to basically make note of any element criteria (i.e. any code relating to pulling entries, categories, assets, tags or users) contained in the Twig code inside the {% cache %}{% endcache %} pair.

Then, whenever something triggers a change to the related element criteria (e.g. if an entry is edited, published or deleted), the cache will automatically be cleared.

This is all related to elements, though – so any other dynamic data you may have in your template, such as session variables, will not trigger the same behaviour.

If your entry or form templates doesn't have any {% cache %} tags, I'm guessing you do have some in a base template wrapping your entry and form templates? If so, you'll need to take a more granular approach to your caching, e.g. by caching components separately and avoid {% cache %} tag nesting. To that end, your unless statement should work nicely for escaping dynamic data caching, as long as the component you're caching isn't wrapped by a higher-level {% cache %} tag.


Currently, the template {% cache %} tag can only cache to the database.

See Brandon's comment here ("Template caches always go to the database").


Integrity constraint violation - Not null violation

there's a sequence being created for entrydrafts but not for drafts.

That's your issue.

I did a fresh Craft 3.3. install on PostgreSQL and there should be a drafts_id_seq sequence created for the drafts table that you're missing.


I've managed to get it working via the following steps:

Create a new field and give it the preparse field type
Duplicate only the twig variable code from the template into the input box in the field page.
In Craft Settings, go to the page template, and add the new preparse field to the available fields (this doesn't show up in the content editor).
The twig template stayed the same.
The responsive images are then generated when the user saves the entry in Craft instead of when the page is loaded by the end user.


The file system path has to be an absolute path from the root of your filesystem, like /Users/myuser/webserver/myproject/public/assets/images.

For portability between different environments, it's a good idea to make an environment variable that holds the path to your project, which you can then use in the assets file system path. This is described very nicely in the "Environment-Specific Variables" section of the "Multi-Environment Config" part of the docs.


Fatal error: Class 'Craft\FileCache' not found when trying to install

After checking out the craft/app/etc folder, I noticed the cache folder was missing. It turns out that the problem was with my FTP client ignoring folders named "cache". So really a dumb mistake on my part.

Thanks for your help @BradBell!


How can I add a RichText-Field to my plugin's CP-section?

To do this you'll need to take a few steps:

Load the necessary resources which include the redactor.css and redactor.js file.  And if you are using Craft's macros for your fields, the form macro file.

{% includeCssResource "lib/redactor/redactor.css" %}
{% includeJsResource "lib/redactor/redactor.js" %}

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

Add a class to your field that you will use to initialize your Redactor toolbar.  Here's a simplified textarea macro:

{{ forms.textareaField({
    class: 'myFieldsRedactorClass',
    name: name,
    value: (value is defined) ? value : ''
}) }}

Initialize the redactor field type with your desired toolbar.

(function() {
    $('.myFieldsRedactorClass').redactor({
        buttons: ['bold', 'italic']
    });
})();

Here's a related article on customizing Redactor toolbars from Straight Up Craft:
Custom Redactor Toolbars for the Rich Text Field in Craft CMS

Note:
One thing to be mindful of, which I'm not sure what to say about, is that if you have other Rich Text fields in your section with you custom field type, Craft is probably already loading these resources. I don't know if there is some way to check to see if these are loaded and only load the redactor css and js assets if they are not being loaded elsewhere.


How should I include my custom enums class in my plugin?

I suppose it depends on what the code is going to be doing.  If it's standard "business logic" code related to your plugin, then it would make more sense to add it to your plugin's services, which is where we recommend that type of logic goes.  There, it handles the interactions with the database and returns the appropriate models back to your plugin's controllers and/or template variables.

Adding it to your service layer will also get you the added benefit of Craft auto-uploading the classes for you as well and attaching them to the global craft() instance as craft()->pluginHandle

Update

If we're talking about enums, I'd follow Craft's example and create an enums folder for your plugin.  From your plugin's init() method, simply import your custom enums:

public function init()
{
    Craft::import('plugins.yourPluginHandle.enums.MyCustomEnum');
}


User confirmation email not being received by hotmail?

Turns out it was being rejected by Hotmail. Not appearing in junk mail being bounced at server level. Switched to using SMTP and problem solved. Possibly due to over testing with emails to the same address.


Namespace issues when calling a plugin variable

I think you can only have one variable class. So the solution you posted is the only way that works.


When downloading from the Github releases tab be sure that you are downloading the latest plugin release for the version of Craft you are using.

In the case of Sprout Reports:

v0.x releases are for Craft 2
v1.x releases are for Craft 3

When in doubt you can look at the files within the plugin folder and try to determine which version of Craft the plugin is for. Most Craft 3 plugins will have a composer.json file and src/ folder.


Sorting categories into list put single one at end of it

Is there a reason why you don’t just drag the “Others” category to the end in the CP? The sort order will be the same for the front-end with your code:

{% set entryIds = craft.entries.section('toys').ids() %}
{% set categories = craft.categories({
    relatedTo: { sourceElement: entryIds },
    group: 'brands',
}) %}

I corrected your code, you never append another .craft.categories criteria model to a criteria model. Have a look at the docs for the allowed syntax:

https://craftcms.com/docs/templating/elementcriteriamodel

Update:

Here’s example code that should work to list the categories alphabetically with the special “Others” category listed at the end.

{% set entryIds = craft.entries.section('toys').ids() %}

{% set categories = craft.categories({
    relatedTo: { sourceElement: entryIds },
    group: 'brands',
    order: 'title',
}) %}

{% set otherCategory = null %}

{% for category in categories %}
    {% if category.id == 72 %}
        {% set otherCategory = category %}
    {% else %}
        {{ category.title }}
    {% endif %}
{% endfor %}

{% if otherCategory %}
    {{ otherCategory.title }}
{% endif %}


Something like this should get you going in the right direction:

Craft.createElementSelectorModal('Asset', {
    multiSelect: true,
    criteria: { locale: this.elementLocale, kind: 'image' }
});

See Brandon's answer here for more information and documentation:
Is it possible to use the ElementType Modal UI for a custom Field Type Plugin?


Getting Invalid Type Error with no Key Path Value

EDIT

This is a case of staring at your computer for too long. The sections needs to be an array so it should've been

$this->addMetadata("links.sections", ["https://news-api.apple.com/sections/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"]);

and not

$this->addMetadata("links.sections", "https://news-api.apple.com/sections/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx");


How can I loop through a collection in the index file?

To set up a section (or check the one you are referring to), in your control panel, go to Settings then Sections.

To loop through entries on a template, for this service section for example, you do:

{% for entry in craft.entries.section('services').all() %}
    {{ entry.title }} <br>
{% endfor %}

Hope that helps :)


A while since you asked, so in case you haven't figured it out yet, here goes:

To attach to a plugin hook, you need to create your own plugin. So in your plugins folder, add a new folder called SearchPlusItemMapping or whatever you want to call your plugin. In that folder you'll need to create a php file called SearchPlusItemMappingPlugin (change whatever comes before Plugin if you gave your plugin a different name. In this file, add the following lines:
    namespace Craft;

class SearchPlusMappingPlugin extends BasePlugin
{
    public function getName()
    {
        return Craft::t('Search Plus Item Mapping');
    }

    public function getVersion()
    {
        return '1.0';
    }

    public function getDeveloper()
    {
        return 'Your Name';
    }

    public function getDeveloperUrl()
    {
        return 'https://somesite.com';
    }

    public function searchPlus_alterBasicItemMapping(){}
}

And then at the bottom you add your function.


What's the most efficient way to handle a redirect of the home page?

.htaccess should always be faster because it doesn't involve PHP or Craft at all.

But on top of that the {% redirect %} tag should be pretty darn quick.

Upon hitting it, Craft immediately calls Yii's CHttpRequest->redirect(), which sets the redirect header and terminates the current request.


The plugin doesn't come with Craft. You have to manually install it with a Craft plugin, but luckily this is easy to do:

Set up your new Craft plugin (→ "Plugin Development - Setting Things Up")
Download the Redactor plugin and copy it to craft/plugins/myplugin/resources/
Load the Redactor plugin JS file from the init function:
craft()->templates->includeJsResource('myplugin/redactorplugin.js');


How do I "register" a service in a Craft 3 plugin?

It turns out there's a handy method for manually registering your services, or in Yii2 parlance, just "components":

namespace example\myplugin;

use example\myplugin\services\Example as ExampleService;

use Craft;
use craft\base\Plugin as BasePlugin;

class MyPlugin extends BasePlugin
{
    public static $plugin;

    public function init()
    {
        parent::init();
        self::$plugin = $this;

        $this->setComponents([
            'example' => ExampleService::class
        ]);
    }
}

Then, somewhere else in your plugin, your service is immediately available as:

MyPlugin::$plugin->example->myMethod();

…where example is the key in the hash of classes you passed to $this->setComponents().


Is there a way to return asset data along with entry data?

Yes - you can access it exactly the same way you do in the templates; you just need to use PHP syntax (e.g. -> for accessing sub-properties rather than .).

'transformer' => function(EntryModel $entry) {
    // Begin defining the response data for this entry
    $data = [
        'excerpt' => $entry->excerpt,
    ];

    // Get the first asset in a "heroImage" Assets field (if there is one)
    $heroImage = $entry->heroImage->first();

    if ($heroImage) {
        $data['heroImage'] = $heroImage->url;
    }

    return $data;
})


How to search children with relatedTo param

It appears the preferred way is by using getDescendants() — In fact, the children property is actually an alias for getDescendants(1). (The parameter specifies a maximum distance (i.e. number of levels) of the child from the parent.)


A field in Craft can belong to any element (entry, tag, category, user, etc.).

If you want to get the ID of the element the field may or may not be currently attached to, you can do this from your Field Type class:

$elementId = isset($this->element) ? $this->element->id : null;

if ($elementId)
{
    ...
}


Prevent Rich Text editor from removing code tags?

You've probably got "Purify HTML" checked under your Rich Text field's settings and that's stripping code.

You should really only have that checked if you're accepting input from untrusted sources using the Rich Text field on the front-end of your site. Presumably all users using the control panel are trusted enough not to input malicious code into the site.


Yes, you can pass in a variable into the parameters and to get the query string values use craft.request.getQuery().

I can recommend this blog post by Jérôme Coupé for a great introduction to setting up the form and the criteria model filters:

Combined searches and filters using Craft

You should also have a look at other questions tagged with "form".