Smart Map - pass options into markers individually

OK So without being too verbose about this, here is how I managed to attach information to each marker.

It is important to remember that each marker has an ID which corresponds to the entry / user that it is derived from. Using javascript, I created a small function that when given a numeric ID, it creates the smartmap ID by prepending adn appending characters to the ID. So 43 would return smartmap-mapcanvas-1.43.memberAddress in my case.
Using that function as a building block, I was able to create a craft loop on my template that queries the user, gets their id, gets the relevant information, and then using javascript to apply it to the matching id marker.
Google markers are just javascript objects. So you can add anything to them.... Strings, Arrays, Objects, whatever... Then use javascript to query that extra

If anyone needs help, hit me up and I'll happily share my code.


How do I conditionally set active state in category navigation?

You don't need the quotes or braces in twig tags to reference variables.

{% for category in categories %}

{{ category.title }}

{% endfor %}

You could also use ternary operators:

{% for category in categories %}

{{ category.title }}

{% endfor %}


Does Craft have built-in queue handling for outbound mail?

I guess the answer is no

Correct... Craft is just the middle-man between creating the email and using whatever selected service is used to send it.


Cannot edit entries after Redactor 2.0.1 upgrade

I have an unfair advantage since I got to look at your logs from your support ticket, but here's the error from the logs:

  [error][yii\base\InvalidConfigException] yii\base\InvalidConfigException: Redactor plugin not found: source

If you look at the Changelog for Redactor 2.0.0, you'll see the "Source" plugin is no longer needed.

The upgrade from Redactor 1.x to 2.0 should have tried to clean up any craft/config/redactor/*.json config files you might have removing references to the "Source" plugin, but something might have went wrong (permission errors are the most common cause of that).

Regardless, if you update those Redactor config files, the error should go away.


"Unknown error" constantly, seems tied to user preferences

This was apparently caused by an almost complete but failed deployment of the app folder. Only a few files were missing/corrupted so Craft still worked other than the issue described.

I replaced the entire craft/app folder (deleted it, unzipped Craft on the server and used mv) and updated the permissions. At this point I got the same error. The error continued to show up after disabling all plugins other than Commerce. But when I disabled Commerce I was able to check for updates again (Craft was already up to date), and under the limited user the errors no longer appear. Oddly, re-enabling Commerce changes nothing. I did encounter a PHP error when navigating within Commerce, so I followed similar steps to upload a fresh copy. Everything appears to be working correctly now.


Craft 3: Cache element query or variable assignment

The request makes sense, but I thought that Craft did some magic to make sure that a duplicate query/variable-assignment wasn't an issue by re-using the query internally. I have no idea why I think that though.


Ok, this works, the backslash behind "...language>" was wrong:

'(?P<title>[-\w\d]+)\.(?P<papayaId>\d+)\.(?P<language>[\w]{2})\.html' => array('action' => 'jpk/rerouteOldPages'),


How do you only show children of “active” parent using categories?

I think you don't need or want the {% nav %} tag. This should work with your current nav:

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

  {% for category in categories %}
    {% set thisIsActiveCategory = (category.slug == craft.request.segment(2)) %}

      {{ category.title }}
      {% if thisIsActiveCategory %}
        {# loop over the subcategories #}
        {% set subCategories = craft.categories.descendantOf(category) %}

          {% for subCat in subCategories %}

{{subCat.title}}

          {% endfor %}

      {% endif %}

  {% endfor %}


dev- branch plugin forks being prompted for update

I experience the same with https://github.com/Saboteur777/craft-support forked from https://github.com/jasonmccallister/craft-support (which is a fork of https://github.com/lukeyouell/craft-support).
Using composer update will not change "tracks" to the original plugin, so you are safe to update, the notification is a minor annoyance, though.


How to recreate symlinks to path-based plugins after moving to live server?

Symlinks won't transfer over FTP and I'm like 98% sure there isn't a way to get Craft to re-create those symlinks natively.

So you'd need SSH access to the box with Composer installed in the terminal.  Then you could upload your custom plugins, composer.json and run composer update or upload composer.json and composer.lock and run composer install to have the dependencies pulled down and the symlinks re-created.

Alternatively, and this is probably cleaner, you can setup a vcs type of repository in your composer.json file, along side your path repository.  https://getcomposer.org/doc/05-repositories.md#loading-a-package-from-a-vcs-repository

They'd both point to the same plugin.  When you deploy to production, Composer should see that the path repo doesn't resolve to a valid path on the production file system and move onto the vcs repo for the same plugin and pull the files down that way.

It's compatible with private repositories, too: https://getcomposer.org/doc/05-repositories.md#using-private-repositories and you can setup Github access tokens if you'd rather go that way: https://www.previousnext.com.au/blog/managing-composer-github-access-personal-access-tokens


Matrix block Element API call on null error

I figured it out. Not every entry uses the matrix block, the error appears when the script hits that empty/non-existing block (null) it can't go looking for something inside it. Adding a conditional around the foreach solves it.

<?php

use craft\elements\Entry;

return [
  'endpoints' => [
    'discproj.json' => function() {
      return [
        'elementType' => Entry::class,
        'criteria' => ['section' => 'dPs'],
        'transformer' => function(Entry $entry) {

          $linkBlocks = null;
          if ($entry->proLinks) {
            foreach ($entry->proLinks->all() as $block) {
              switch ($block->type->handle) {
                case 'external':
                $linkBlocks[] = [
                  'externalTitle' => $block->externalTitle,
                  'externalLink' => $block->externalLink,
                ];
                break;
              }
            }
          }

          return [
            'projectLinks' => $linkBlocks,
          ];
        },
      ];
    },
  ]
];


Let user add a message when selecting shipping method

Create a text field and add it you field layout for Orders in Commerce settings.

Then in any updateCart form you can simply place a value in this by using <input name="fields[fieldHandle]" etc>


Craft SeoMatic GTM  disable on 404 pages

SEOmatic author here -- what version of SEOmatic are you using? I think the best way to do this would be to just disable the container from being included in your 404 Twig template:

{% do seomatic.script.get('googleTagManager').include(false) %}

As per: https://github.com/nystudio107/craft-seomatic#google-tag-manager


This should do it:

{# Grab all the entries for the section #}
{% set entries = craft.entries.section('news').find() %}

{# Group by the authorId #}
{% set entriesByAuthor = entries|group('authorId') %}

{# Grab all of the users with the userIds in entriesByAuthor #}
{% set authors = craft.users.id(entriesByAuthor|keys) %}

<ul>
    {% for author in authors %}
        <li>{{ author.username }}
    {%  endfor %}
</ul>


I am unable to render new entries on the browser (demo version)

I figured it out. I went with the default template file which did not exist, hence the error.


Craft does already support .twig as a template file extension option by default (see the defaultTemplateExtensions config setting docs). If you want to allow .html.twig as well, just open craft/config/general.php and add this to the config array:

'defaultTemplateExtensions' => array('html', 'twig', 'html.twig'),

(Note that this will only affect front-end templates. The Control Panel is locked to .html and .twig for plugins.)


Sort entries by best match to multiple categories

Have a look at the Similar plugin https://github.com/aelvan/Similar-Craft, it should do exactly what you’re looking for.

{% set baseCriteria = craft.entries({
    order: 'postDate desc',
    limit: 5,
}) %}

{% set similarEntries = craft.similar.find({
    element: entry,
    context: entry.myCategoriesField,
    criteria: baseCriteria,
}) %}


Expected performance benefit of using a non-file CacheMethod (Redis, Memcache)

As with most performance related questions, the answer is "it depends". :)

Apps like Redis and Memcache store their key => value stores in memory as opposed to disk-based file caching.

Accessing data from memory is usually orders of magnitude faster than accessing data from disk.

All of these fall under "General purpose data caching" and Craft will use them internally for its own operations and plugins can certainly make use of them as well.

If you have a plugin that makes extensive use of data caching and/or you've got a heavily trafficked site, then you will likely see some tangible performance benefits.

If you're just doing a basic stock Craft install on a low trafficked site, then you likely won't see much of a difference at all.


You can alter the index.php file and add [set_time_limit][1](300); anywhere below the <?php tag.

You can also try to set it by ini_set('max_execution_time', 300);

For the reason why it returns a 500 Internal Server Error, the server does not support the php_value and php_flag parameters through the htaccess file or it doesnt use the php5 module. You can try setting the php_value directly and check again for errors, or contact your hosting provider for support


A more economical method of building an archive menu?

If you know which years should appear, and there are no breaks in the timeline, perhaps it would make more sense to do a simple numeric loop instead...

{% for year in (now.year)..2009 %}
    {{ year }}
{% endfor %}

That will count backwards from the current year to 2009.


Hide (or disable) an entry field in CP depending on user group permission?

OK so here is my solution :
1/ define a custom permission for user groups

public function registerUserPermissions()
{
    return array(
        'updateTopNews' => array('label' => Craft::t('Update Top News')),
    );
}

2/ simply add css to hide the field when user has not the permission in my plugin init function

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

    $user = craft()->userSession->getUser();
    if ( craft()->request->isCpRequest() && $user ) {

        if ( !$user->can('updateTopNews') ) {
            craft()->templates->includeCss('#fields-topNews-field { display: none; }');
        }
    }


Redactor fields not saving more than 252 characters?

The cause of this ended up being that the field_introduction column for the Redactor field in the craft_content table was set to varchar(255), which means it can only hold 255 characters.

No idea how it got that way. The Redactor field (under its advanced settings) has never had an option to be varchar(255), only text and mediumtext.

Regardless, going through all of the Redactor field settings and re-saving them correct adjusted the column data type back to text and resolved the issue.


How to order categories in key/value for loop?

Using the group filter you will always end up with the sort order of your entries. So you would need to sort the entries by your categories field, but this probably doesn't work.

But you can do the following:

{# Get the categories related to my "entrySection" entries in custom order #}
{% set entries = craft.entries.section('entrySection') %}
{% set relatedCats = craft.categories.relatedTo(entries).order('customCatField desc') %}

{# Loop the categories #}
{% for category in relatedCats %}

    {# Get and loop through the 6 most recent entries related to this cat #}
    {% set relatedEntries = craft.entries.relatedTo(category).limit('6') %}
    {% for entry in relatedEntries %}
        ...
    {% endfor %}

{% endfor %}


Separate time settings from user locale?

No, there's currently no setting to choose your preferred date and time format. What you can do though, is to hack your craft/app/framework/i18n/data/en_us.php

'dateFormats' => array (
    'full' => 'EEEE, d. MMMM y',
    'long' => 'd. MMMM y',
    'medium' => 'dd.MM.y',
    'short' => 'dd.MM.yy',
),
'timeFormats' => array (
    'full' => 'HH:mm:ss zzzz',
    'long' => 'HH:mm:ss z',
    'medium' => 'HH:mm:ss',
    'short' => 'HH:mm',
),


Charge: Update subscription card details

In the end I worked out the card is related to a customer, not a subscription.

I couldn't see any public endpoint to update a customer's card, so I added this method in charge/controllers/ChargeController.php (not ideal to update the plugin directly I know):

public function actionUpdateCard()
{
  $this->requirePostRequest();
  $customer = craft()->charge_customer->find();
  $cardToken = craft()->request->getRequiredPost('cardToken');

  if ($customer->addCard($cardToken)) {
    $this->returnJson(['success' => true]);
  } else {
    $this->returnJson(['success' => false]);
  }
}

and then can make requests to the charge/updateCard endpoint:

getStripeToken(cardToken => {
  post({
    params: {
      action: 'charge/updateCard',
      cardToken
    },
    then: ({ success }) => console.log(`Card updated: ${success}`)
    url: '/'
  })
})


public vs public_html for git workflow deployment in apache?

Generally, you can make the Craft public folder whatever you want it to be. That allows you to deploy to any folder you like.

For example, I deploy to a public_html on one server, public on another and web on another server. Each of those directories are the web root of their respective site.

The only thing(s) within the public (or whatever you call it) directory is/are the index.php file (and whatever other js/css etc type files) you may have. As long as you can tell that file where the craft directory is (usually one level above the web root) - you should be golden!


Plugin RegisterUrlRulesEvent - Regex URL-Routing gives 404

Update I was able to solve half of my Problem:

Seems the Regex didn't like the "pure" slashes / in the URL between the parameters, once I escaped those, through backslashes like this: \/ it no longer gave me a yii\base\InvalidRouteException.

The new Problem I have now is that it can't find the action I'm referring to, see below:

// Path of File: ./src/Expedweather.php; in EVENT_REGISTER_SITE_URL_RULES

$map_page = 'data\/<range:\w+>\/<peak:\w+>\/<view:\w+>\/<parameter:\w+>';
$event->rules[$map_page] = 'expedweather/forecast-panel';

// Exert from ./src/controllers/DefaultController:
protected $allowAnonymous = ['index', 'forecast-panel'];
...
public function actionForecastPanel() {...}

An additional piece of info: I'm able to route to the DefaultController's index Function by removing /forecast-panel from the target action.


It's been a while since I was in Craft 2, but I'd suggest checking out this page in the docs:
https://craftcms.com/docs/2.x/folder-structure.html
Do all of the directories mentioned on that page exist on your site? Specifically, I'd confirm that you have the craft/storage folder created in your installation. If it's not there, make it and try to load the page again.


How to use a Numeric Field with a Default Value

You can:

1) Write a plugin that extends Craft's native Number field type and adds the functionality you're looking for.

2) Make a feature request for a default value for the native Number field type.

3) Potentially fake it using something like the CP CSS plugin.


Is it possible to create category for only one site in a multisite setup?

While this was originaly scheduled for Craft 3.2 (https://github.com/craftcms/cms/issues/2122) this was not in the 3.2 release. Brandon mentioned on Discord (link) that categories will be going away altogether in Craft 4.0:

Here is his comment:

  tags and categories are both going away in Craft 4.
  3.x (maybe as early as 3.2) will see a big update to Entries fields, where they will be able to behave more like current Categories and
  Tags fields, if desired and 4.0 will just convert all existing
  categories & tags over to entries

So as it stand, I wouldn't use categories anymore and use structures instead.


Craft 3 add Simple Map in entry through plugin

I think what you are running into is the getField() method on #147 of the MapService. What this does is return a model based on whether this is an existing record or a post request and if neither return an empty model.

if (
        // Is this a Post request and isnt there a console request AND is there a value
        !\Craft::$app->request->isConsoleRequest
        && \Craft::$app->request->isPost
        && $value
    ) {

        // Create a new map model with the $value param - creating a model that takes the $value into account
        $model = new Map($value);
    } else if ($record) {

        // Is there a record? Create a model that takes these record params into account
        $model = new Map($record->getAttributes());
    } else {

        // We havent got a post request.or a record. This is what is happening to your input.
        $model = new Map();
    }
EDIT---------------------------------------------
If you Edit $model = new Map(); TO $model = new Map($value); Your above code works fine.

I am not sure as to the inner workings of Simple Map - have only used the C2 version. The best way to fix this for the long term is probably to create an issue on SimpleMap's github page. My recommendation is to replace the above else{} method, with what i described below. Maybe there is some way to get around this that doesnt involve source edits - like i said i dont know Simple map inside out - i might just be missing something obvious. In case there isn't i would recommend fixing the MapService with something like the below:

else {

    Didnt meet the satisfied conditions. Is $value an array and does it exist?
    if(!$value || !is_array($value)){

        // Not happy with this input - create a blank map.
        $model = new Map();
    }

        We're happy with the sended value - it isnt a post request. Lets take the value into account
        $model = new Map($value);
    }

I ran the above code with your example and it ran just fine.

I think it goes without saying that it is a terrible idea to just edit just your MapService file with the above code as a permanent solution as that will give you instability/incompatibility problems. What i would recommend is editing the method temporarily to test if this solves your problem - just to make sure. If it does it's probably wise to open an issue. Either if it does or doesn't - probably smart to open a github issue to see what the devs themselves say.

P.S - your code example is missing one array brackets at the end - probably smart to edit that before pasting it back.

Hope i was able to help in someway :)


Show events in month by specific category - Solspace Calendar

Figured it out. For anyone else seeing this later on:

{% set regionCategory = craft.categories.group('eventRegions').slug(region).one() %}

{% set month = craft.calendar.month({ relatedTo: regionCategory }) %}


Thought I would add this as an answer instead as it should solve your issue.

I think the issue with writing it like batch('{{ nr }}') is that twig sees whatever is in '' as a string, so is seeing {{ nr }} as it is.

You also don't need to echo a variable as a function parameter i.e batch({{ nr }}), you just need to reference the variable itself.

So by just writing

{% for batch in craft.entries.section('xy')|batch(nr) %}
 {{ batch.title }}
{% endfor %

Twig will take the value for nr set above and use it as the parameter :)


Loop through categories and get bottom-most category for each tree

Have a look at Craft’s nav tag, which allows to recursively iterate through
an array of element models. Only output the category title if the category has no descendants.

{% nav category in categories %}
    {% if not category.getDescendants().total() %}
        {{ category.title }}
    {% endif %}

    {% ifchildren %}
        {% children %}
    {% endifchildren %}
{% endnav %}

Another option would be to write a self-calling macro to recursively traverse the tree.

{% macro getBottomMostElements(elements) %}
    {% import _self as self %}

    {% for element in elements %}
        {% if element.getDescendants().total() %}
            {{ self.getBottomMostElements(element.getDescendants(1)) }}
        {% else %}
            {{ element.title }}
        {% endif %}
    {% endfor %}
{% endmacro %}

{% import _self as macros %}
{{ macros.getBottomMostElements(categories.level(1)) }}


Defining elements of a research project as assets or entries?

Actually, there's a brilliant plugin called Embedded Assets, which lets you manage YouTube links and other embeddable media like first rate citizen Assets in Craft. I highly recommend it.

As for the more general question of whether to go with Entries or Assets – it's difficult to give a solid recommendation without knowing more about your project and its requirements, and it'll also probably come down to choice and preference a little bit.

I'm also not totally sure where you're going in regards to relatedTo, but again – Assets are first rate citizens in Craft, and they aren't limited in their capabilities compared to other types of content like Entries or Categories – certainly not when it comes to relations. Assets can be related to Entries, Categories, other Assets – sky's the limit.

Anyway – based on what you're describing, I would probably go for an Assets-only solution, rather than having Entries wrapping Assets. When the actual content is a file, and everything else is basically metadata, this is probably far the more elegant and effective solution.

Depending on your requirements, the only thing you may have to work around is the fact that Assets have no URLs (beyond the actual file URL, of course), nor can Asset sources be assigned a default entry template like e.g. Entries or Categories. For listing templates, search results etc. you can always rely on Craft routing your template filenames as URIs and then just create a craft.assets template query to fetch the Assets you need, but if you need to link to an individual Asset, you'll probably need to create a custom route.


Text cut off after migration in some fields

Found the issue with the awesome Craft support.

There seems to be a server related issue where db tables change from TEXT to VARCHAR.

So the solution is to change those fields back to TEXT directly in the db.


Display entries by current entry author?

In order to display all other entries by an author except the current one, you will need to perform another step — either by filtering out the current entry from the query or adding a conditional.

{% set authorId = entry.author.id %}
{% set allEntryIds = craft.entries.section('blog').authorId(authorId).limit(null).ids() %}
{% set otherEntryIds = allEntryIds|without(entry.id) %}
{% set otherEntries = craft.entries.section('blog').id(otherEntryIds) %}

    {% for entry in otherEntries %}

{{ entry.title }}

    {% endfor %}

or

{% set authorId = entry.author.id %}
{% set authorEntries = craft.entries.section('blog').authorId(authorId).limit(null) %}

    {% for authorEntry in authorEntries %}
        {% if not authorEntry.id == entry.id %}

{{ entry.title }}

        {% endif %}
    {% endfor %}


The Variable {{ siteUrl }} Produces Two /es/es/ On Multisite

I figured out what was wrong, though I'm confused on why some of it was working fine... Maybe if it broke more fully I would have found it easier, haha. Mats was right, it was the Base URL in the Sites area of the admin control panel. I had entered @web/es thinking that I want it to be the root of the primary site, but that wasn't correct, I needed to just put @web/ because I already told it that it lived at /es through the index.php of that site folder.


Both the craft/ folder name in Craft 2, and the craft executable in Craft 3, can be renamed.

Since the craft executable is user-facing (when SSH’d in), I’d recommend leaving that alone and rename your craft/ folder to something else, maybe craft2/. Then in public_html/index.php, update your $craftPath variable to point to the new location:

$craftPath = '../craft2';


What is the max # of version history for any given entry?

There is no set maximum number of versions an entry can have, assuming you have unlimited database space.

Take a look at the source code in the EntryRevisionsService for more information: https://github.com/craftcms/cms/tree/master-v2/src/services/EntryRevisionsService.php#L148


Can you get the HTTP status code in twig templates?

Since this is the top hit in Google, I'll guess it's handy to mention that craft.app.response.statusCode will display the statuscode in Craft v3 and up.


Global is not really the best option for dynamic navigation, because by definition it is designed to contain just one of something — and while it supports multiple fields, it only supports one instance of each field. Technically you could use a field within the global that supports multiple items (i.e. table fieldtype or matrix fieldtype), but none of the fieldTypes support hierarchical structures natively, so I don't see the advantage. Or you could simply paste static HTML into a text field, but I wouldn't really classify that as dynamic. Overall, not a particularly good option.

You should probably be looking into using a 'structure' (or to a lesser extent 'categoryGroup'), where each entry would represent a page or nav item, organized hierarchically. In this way you can reuse the same field within each entry (i.e. 'title') and loop through the entries to dynamically generate the nav, with the added benefit of being able to reorganize the nav easily using drag-and-drop.

For more information, see:

Documentation on using the nav tag.
Documentation on giving each Entry Type it's own template.
Answers from previous questions, such as here and here.
Check out some of the dedicated nav building plugins, such as a&m navigation or craft nav.


Yep, postLogoutRedirect can be set to a function instead of a static value. So for example, in your template you can generate a hidden field in your logout form (or append a querystring parameter to the logout URL) that contains the path of the current page. Then set this in your general.php:
'postLogoutRedirect' => function($siteHandle) {
  return Craft::$app->request->getParam('myLogoutPathParameterName', '/');
}

This defaults to the homepage ('/') if the parameter is not found.


Paypal Express shows a 404 error when returning to Commerce's completePayment endpoint

You have a variable name collision. You must change your Craft token name to something else, as per documentation


How can I use slim templates with Craft?

To answer your question: I think you CAN, but it will not be easy.

Craft is built on top of the Yii framework. It lets you override things (settings, classes) in the config/app.php file that gets installed by default. So, you should be able to change the view renderer to anything you want:

<?php

return [
    'components' => [
        'view' => [
            'class' => 'craft\web\View',
            'renderers' => [
                'slim' => [
                    'class' => 'path\to\your\slim\ViewRenderer',
                ],
            ],
        ],
    ],
];

Of course, this would require a Yii ViewRenderer based on Slim, which I don't think is  available (yet). You could build it yourself, based on the Twig ViewRenderer used by Craft.

The reason I would not do it, is that Craft has several Twig filters en functions that make your templating life easier. You'd have to create wrappers for those, to be able to use them. I don't think the added complexity of all this weighs up to the advantage of using Slim.


Dynamic entry template not loading on staging site but works on local.dev

I'm guessing staging has a case sensitive file system and your local dev site doesn't.

i.e. the section handle in your screenshot is called availableHomes, but the template folder you're referencing is availablehomes.


How to redirect a url with a query to one that does not have a query

You could add this to the homepage template.

{% if craft.request.getParam('post_type') == "testimonials" %}
   {% redirect "/about-us" %}
{% endif %}


Copy the Entry Type along with its field layout

After hours I managed to fix it. I'm assuming I made an error where I was trying to copy the Fields in the Entry Type I literally just created. So it was copying over 0 fields.

I built the functions from scratch again and finally found the working code. For future reference or to help others, here is the snippet in question.

private function CopyEntryTypes($savedSection, $baseSection)
{
    $baseSectionEntryTypes = $baseSection->getEntryTypes();

    foreach ($baseSectionEntryTypes as $baseSectionEntryType) {
        $newEntryType = $this->createNewEntryType($baseSectionEntryType, $savedSection->id);
        //oke so the New Entry Type is saved, we should get a return statement from the function
        //now loop through the tabs/fields of the baseSection Entry Type.

        $currentLayout = $baseSectionEntryType->getFieldLayout();
        $currentTabs = $currentLayout->getTabs();

        // This will the array passed to assembleLayout
        $postedFieldLayout = array();

        // Loop through each tab and build our array
        foreach ($currentTabs as $tab) {
            $fields = $tab->getFields();
            foreach ($fields as $field) {
                $postedFieldLayout[$tab->name][] = $field->fieldId;
            }
        }

        //so now we have a collection of entry types, each of them have a tab-name which we can use to identify
        //the goal is to get 'all' the tabs into the new entry type.
        $requiredFields = array();

        // Assemble the layout
        $fieldLayout = craft()->fields->assembleLayout($postedFieldLayout, $requiredFields);
        $fieldLayout->type = ElementType::Entry;
        $newEntryType->setFieldLayout($fieldLayout);

        // Save it
        if (craft()->sections->saveEntryType($newEntryType))
        {
            Craft::log('Successfully appended fields.');
        }
        else
        {
            Craft::log('Could not append the fields.', LogLevel::Warning);
        }
    }
}

private function createNewEntryType($baseSectionEntryType, $savedSectionId)
{
    $newEntryType = new EntryTypeModel();
    $baseSectionEntryType->id = null;
    $baseSectionEntryType->sectionId = $savedSectionId;
    $values = $baseSectionEntryType->attributes;
    $newEntryType->setAttributes($values);

    if (craft()->sections->saveEntryType($newEntryType))
    {
        var_dump('Successfully saved Entry Type.');
    }
    else
    {
        var_dump('Could not save the Entry Type.');
    }

    return $newEntryType;
}

I'm also using code that I modified from: How can I programmatically add a tab to entry type? so this guy deserves the credit.


project.yaml stopped syncing changes in the staging process

P&T recently released an update with a new console command:

project-config/rebuild

This does exactly what it sounds like, it rebuilds the config ...


Craft 3 redirect of existing and non-existing URLs

Based on your comments, I'd recommend creating a new entry type in your section.

Create a "Redirect" entry type which only contains a URL link (or an Entry field) so the page knows how to handle the redirect. For any entries that need to be converted to a redirect, simply swap the entry type to use this instead.

Then you can simply map that entry type to a redirect template:

{% redirect entry.newUrl %}

I've done this, and it works well.


calculating average ratings from a series of review fields

Something like this should work:

{% set reviews = craft.entries.section('reviews').relatedto(entry) %}
{% set value = 0 %}
{% set condition = 0 %}
{% set reception = 0 %}
{% set count = 0 %}
{% for review in reviews %}
    {% set value = value + review.value %}
    {% set condition = condition + review.condition %}
    {% set reception = reception + review.reception %}
    {% set count = loop.index %}
{% endfor %}
{% set averageValue = (value / count)|round(1, 'floor') %}
{% set averageCondition = (condition / count)|round(1, 'floor') %}
{% set averageReception = (reception / count)|round(1, 'floor') %}


If I understand properly, you should be able to do this:
$entries = \craft\elements\Entry::find()
    ->section('yourSection')
    ->category(['and', 695])
    ->relatedTo([698,698])->all();

Assuming category is the name of your relational field, you can use that to pass the and condition (though with one element only it wouldn't be needed) then relatedTo is an or by default (docs)
And as per your edit, pass and condition to your custom fied and or conditions to your relatedTo.
It would be pretty much the same in Twig.


Not exactly. But if you're looking for stats, devMode does some query profiling right in the console:

I'm not sure if you're looking for a 1-1 correlation but you can obtain whether or not the server supports gzip with the Server variable HTTP_ACCEPT_ENCODING (kind of useless IMO). Craft also will display its version number at the bottom of the CP when you're logged in, so I don't really see value there either but you can get it via your templates (see below).

If you need more than that, you could always make a simple plugin (I like to start with Lindsey D's Business Logic  boilerplate variable class) and then just grab the data you need.

To only display the data to admins when they're logged in, you can do so like:

{% if currentUser and currentUser.admin %}
  Craft {{ craft.app.getEditionName()}} {{ craft.app.getVersion() }}.{{ craft.app.getBuild() }}
    ... do other stuff
{% endif %}


How to add Image or any field on Calendars section for Solspace Calendar?

You'd do it from the Calendar's field layout page (https://solspace.com/craft/calendar/docs/calendars/), just like Craft entries, users, categories, etc.


How can I set the isCompleted status of an order from within a custom module?

This can be achieved with

Event::on(
            Order::class,
            Order::EVENT_AFTER_COMPLETE_ORDER,
            function(Event $e) {

                $order = $e->sender;

                $order->isCompleted = false;
                Craft::$app->getElements()->saveElement($order, false);

            }
        );

But I'm not sure it's actually a good idea anyway.


Checking submission from the Contact Form plugin

Based on that code I see on github (I'm assuming you're referring to this plugin) I'm afraid they're not saved to the database.

However craft logs each mail succesfully sent with its internal mailer so you could check your log files to see if any are missing.

The log messages look like

  Successfully sent email with subject: xyz

That should give you an indication of how many are missing, as for the actual content, there I'm afraid you're out of luck as far as I know.


I'd be inclined to use the public methods for this.
$user->detail->getRawContent();
or
$user->detail->getParsedContent();
etc.


How to create menu in backend using Craft 3

For Craft 2, a number of plugins exist that assist with building navigational structures. None of those has been made available for Craft 3 (yet), but one plugin-less option (thanks to Ben Parizek, who let me in on this) would be, to create a 'navigation' section (structure), in which you can create navigation entries (= navigation items) that you can than drag and drop to get the right navigational structure.

Each entry in this section has, for example:

A field that connects it to another entry
A field that let's the user add a url to navigate to
Any other field that would let the user alter the navigation's behaviour (color, open in new window, etc)

After that, it would be up to you to translate this structure to a navigation in your template(s).


If there are any problems with your submission, Craft sets an entry route variable1, which you can use to retrieve the previously-posted form data.

Here's an example of how you might do that:

<input
    id="title"
    type="text"
    name="title"
    value="{{ entry is defined ? entry.title : '' }}",
>

You can also retrieve the errors from the entry variable:

{% if (entry is defined) and (entry.hasErrors('title')) %}
    {{ entry.getError('title') }}
{% endif %}

If you want to learn more about the validation-related methods available on the entry object (such as the difference between getError and getErrors), I've written a blog post on the subject.

Stephen

Take a look at line 477 of craft/app/controllers/EntriesController.php


Saving related entry in a Matrix block programmaticially

Possibly a duplicate of this one here but hey, here is where I think you are going wrong:

Change this part:

$block->getContent()->setAttributes(array(
  'contentRss' => array($entry->id)
));

To this:

$block->getContent()->contentRss = array($entry->id);


It sounds like you're missing permission on a folder in the /craft directory. Best thing to do, is just retrace your steps by following the official install guide.

I don't use MAMP though, so there might be extra stuff you need to do, but if you scroll down to the bottom of that page to the Additional Resources section. There are some other links to articles which might help, in particular this one:

Installing Craft CMS on Mac OS X Using MAMP & Sequel Pro

If you do want to start again then you should be safe to delete the /craft folder and try again. Although unless you're missing files, you shouldn't really need to start again.


Combine entries query, but filter one section by field

{% set blogIds = craft.entries({
   section: 'blog',
   search: '-location:*',
   limit: null
}).ids() %}

{% set recipeIds = craft.entries({
   section: 'recipes',
   limit: null
}).ids() %}

{% set entries = craft.entries({
   id: blogIds|merge(recipeIds),
   limit: 12,
})

Limit null is only there incase you're paginating, can be removed else.

This is the easiest way I've found for effectively combining element queries.


Unable to access login page or my website

One small detail that can cause the front-end and back-end of your site to result in a blank white page, is if you have a syntax error in your general.php file, such as a missing comma at the end of a line.  If you've just made a recent edit to your config files, take a closer look at them and make sure that you don't have any small errors.

For example, the following multi-environment config is missing a comma at the end of the omitScriptNameInUrls setting, and that minor detail would make both the front-end and back-end of a site result in a blank white page:

return array(
    '*' => array(
        'omitScriptNameInUrls' => true
        'devMode' => false
    )
);


How do I fetch all categories under a category group using the Element API?

UPDATE
Figured it out based on another answer from ElementAPI handling CategoryModel and returning a heirachical object

I wrote the query like this:

'api/categories/<entryCat:[\w-]+>' => function ($entryCat) {
  return array_merge(apiConfig(), [
      'elementType' => Category::class, 'criteria' => ['group' => $entryCat, 'level' => 1, 'with' => ['children.children.children']],
      'transformer' => function (Category $category) {
        $data = ['title' => $category->title];
        $children = $category->getChildren();
        if ($children) {
            $data['children'] = [];
            foreach ($children as $child) {
              $data['children'][] = ['title' => $child->title];
            }
        }
        return $data;
      },
  ]);
},

where apiConfig() is just common settings such as pg and paginate


Donations are like anything else, and can be bought along side regular products so they are a part of normal orders.

You can use the event below to inspect the order and choose youre own default status if you want.

use craft\commerce\events\DefaultOrderStatusEvent;
use craft\commerce\services\OrderStatuses;
use yii\base\Event;

Event::on(OrderStatuses::class, OrderStatuses::EVENT_DEFAULT_ORDER_STATUS, function(DefaultOrderStatusEvent $e) {
 // Do something - perhaps figure out a better default order statues than the one set in CP
 // $e->order
 // $e->orderStatus (the order status to set as the default for this order)
});


When looping through Matrix rows, you can use {{ loop.index }} or {{ loop.index0 }} to see which row you're at.

With loop.index, you could create html for each row number, or (for instance) create different html for even/uneven:

{% for row in entry.matrixFieldHandle %}
    {% if loop.index is divisible by(2) %}

{{ row.text }}

    {% else %}

{{ row.text }}

    {% endif %}
{% endfor %}


Single titles are not translatable in the control panel since Craft version 2, they need to be set in your translations file.


Include CSS file inline rather than as a link

To simple insert raw CSS into a template from a file, you'll want to use Twig's source function. So:

<style>{{ source('file.css') }}</style>

For that file to be located somewhere outside of the templates folder, you'll have two options.

Create a symlink to the file or its folder in the templates folder. Twig will be none the wiser.
Add a Path to the existing template loader in Craft. This will require a custom plugin, and some digging to see how the loader is referenced in Craft. But in the end, your command will look something like this:

$loader->addPath('path/to/other/files');

The really cool part is that paths can have namespaces in Twig. You can do this:

$loader->addPath('path/to/public', 'public');

And that let's you do this in your templates:

{{ source('@public/css/site.css') }}


Organizing Entry, Section, and Category hierarchies

This is Craft CMS, so there is no 'correct' way of doing it. With the routing and slug manipulation you can achieve this is many ways.

However, to me it feels like 'Categories' would be the way to go. To get your URL hierarchy that you have suggested, you'd need to set the following for the Category URI format in Settings > Categories:

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


Loading related entries by category using a select menu

You can do this using the relatedTo param.

{# Get the selected category ID from a 'catId' query string param #}
{% set catId = craft.request.getQuery('catId') %}

{# Define the 'relatedTo' param value, depending on if there is a category #}
{% if catId %}
    {% set relatedToParam = {
        targetElement: catId,
        field: 'categoriesFieldHandle'
    } %}
{% else %}
    {% set relatedToParam = null %}
{% endif %}

{# Define the ElementCriteriaModel for people #}
{% set people = craft.entries({
    section: 'people',
    relatedTo: relatedToParam,
    limit: null,
    order: 'title asc'
}) %}

{# Output the people #}
{% for person in people %}

{{ person.title }}

{% endfor %}

With this code in place, you just need to update your view so that when a category is selected, this template is re-loaded with a ?catId=X query string, where X is the selected category ID.

The simplest example of that would be with a list of category links:

{% for cat in craft.categories.group('myGroupHandle') %}
    {% set url = url(craft.request.path, { catId: cat.id }) %}

{{ cat.title }}

{% endfor %}


Error on homepage of local server no changes made since last working?

Ok I have resolved this by deleting all the cache files in the craft|storage|runtime|cache folder. But whilst this has worked my question is now why did it happen. Not something I want to experience on a live site?


Currently not possible, but I really like the idea of a plugin being able to swap out what craft()->search points to, whether it's ElasticSearch, Lucene, etc.

I'll add it to our internal list, but you might want to submit a public feature request for this as well.


Is there a way to reset the focal point in Craft?

if you're referring to an image focal point then...

How do image focal points work in Craft 3?

help out somewhat...


Is it possible to create fields in a Matrix block from frontend?

There's a lengthy rundown about this in this ticket if you need a detailed explanation.

In short, you'll want to check out P&T's Guest Entries plugin to populate entries on the back-end from front-end input.

I highly suggest paying very close attention to how you should set up your form fields' name attributes from this StraightUpCraft post (scroll to the very bottom for Matrix fields): https://straightupcraft.com/articles/craft-cms-field-guide-twig?view=input


How to re-populate form with old values when submitted from a controller?

There are several things you may need to dig into more to get the full picture here but here's a general idea of how you can approach this in Craft 3.

Flash errors are useful to display a message in the Control Panel, but you'll need to prepare a model with errors and signal to the controller that the form submission has failed to return errors to your template. Also, it's not necessary to use the redirect method in this situation as the Controller request can return your errors to the template simply by preparing them using setRouteParams and returning null.

A common pattern that Craft and several plugins use to do this is as follows. The method below would be the method in your controller that receives the form submission:

public function actionMyControllerAction()
{
    $this->requirePostRequest();

    // Build a model of the data you are submitting
    $model = new MyModel();
    $model->someOptionalAttribute = Craft::$app->getRequest()->getBodyParam('someOptionalAttribute');

    // The `getRequiredBodyParam` method can help validate required fields
    $model->someRequiredAttribute = Craft::$app->getRequest()->getRequiredBodyParam('someRequiredAttribute');

    // After you prepare the model, hand things off to a service
    // to validate and/or save things to the database
    // The "saveThisModel" method can run any additional
    // validation you need to run, add errors to the model,
    // and return `false` if validation fails
    if (!Plugin::getInstance()->myService->saveThisModel($model)) {

        Craft::$app->getSession()->setError(Craft::t('my-plugin', 'Unable to save item.'));

        // This is where you name the thing you are returning to your template with errors.
        // In this example, the 'myModel' variable would be available to your submitted template
        Craft::$app->getUrlManager()->setRouteParams([
            'myModel' => $model
        ]);

        return null;
    }

    Craft::$app->getSession()->setNotice(Craft::t('my-plugin', 'Item saved.'));

    // Redirects to wherever the submitted 'redirect' input points to
    return $this->redirectToPostedUrl();
}

If validation fails, in your template, the myModel variable will be available and you can access all errors as an array, or an array of errors for an individual field. You'll need to loop through this in your template. For simplicity here, I'm just dumping them:

All Errors:

{{ dump(myModel.getErrors()) }}

Errors for a specific field:

{{ dump(myModel.getError('someOptionalAttribute')) }}

You may also have to add some conditional logic around checking if the myModel variable exists or has errors. You can use Craft's form macros in your template to help with this. Search the Craft codebase templates folder for forms. and you'll find several examples. Here's a simplified Text Field macro that would display an error for the Categories title field.

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

{{ forms.textField({
    label: "Title"|t('app'),
    siteId: category.siteId,
    id: 'title',
    name: 'title',
    value: category.title,
    errors: category.getErrors('title'),
    required: true,
    maxlength: 255
}) }}

In this case, the Craft Categories controller the actionSaveCategory is returning the category variable to the template using the same pattern that is described above:

if (!Craft::$app->getElements()->saveElement($category)) {

    // ...

    Craft::$app->getSession()->setError(Craft::t('app', 'Couldn’t save category.'));

    // Send the category back to the template
    Craft::$app->getUrlManager()->setRouteParams([
        'category' => $category
    ]);

    return null;
}


I ended up using the suggestion of Robin Schambach, in front-end templates using the {{ site.group.name }}
E-mail contents can be changed in the admin section, using {{currentSite.group.name}}
Craft 2:
settings -> email -> Messages
Craft 3.0:
settings -> email -> Messages
Craft 3.1:
Utilities -> System Messages


Multi sites: should I use Craft 2 locales, or go with Craft 3 alpha?

Brandon has stated (on the CraftCMS Slack channel, so, sadly, not easily linkable here) that custom locales will automatically translate to sites when upgrading from Craft 2 to Craft 3.

At this point, Craft 3 is still in developer preview and not recommended for production sites, so I would recommend developing in Craft 2 and updating when a stable, final version of Craft 3 is released, along with any compatible versions of plugins that you need for the site(s).

Due to the changes in Craft 3 (many of which are still in flux) plugins will need to be re-written to be compatible with it. Depending on the developer and the complexity of the plugin, this may take some time.


You can use negative numbers as the parameter for segment which then counts from right to left.

So {{ craft.app.request.segment(-1) }} will get the last segment.

And... {{ craft.app.request.segment(-2) }} will get the next to last segment


Interpret TWIG's {% js %} as  in PHPStorm

You can do this using PhpStorm’s Language Injections feature.
In fact, as of PhpStorm 2017.3, it has included support for {% script %} tags out of the box.
To extend that to {% js %} tags, go to Preferences → Editor → Language Injections, and search for “twig: custom statement javascript”. Double-click on it to edit it, and add the following line to the Places Patterns setting:
+ twigCustomStatement("js")

Click OK and then Apply to save.
You can also add support for interpreting {% css %} tag contents as CSS by duplicating that language injection, setting its Language ID to CSS, and setting its Places Pattern to:
+ twigCustomStatement("css")


Craft Commerce Order Notifications from customer email and name

You'd need to write a small plugin that listened to Commerce's EVENT_BEFORE_SEND_MAIL event, so you could override the from address of the email to the customer's order.


Live Preview: Hide tabs from live preview

There is currently no out-of-the-box way to do that.

You might be able to pull it off with something like the CP-CSS plugin, but I'm not sure how you'd just target the tab when the Live Preview pane is open.

Otherwise, you can always make a feature request!


Mandrill integration not sending email for front-end registration form

Emails only send out when you're not logged in as admin from the front-end registration form.


How do I call a service from my controller in a plugin?

Try it with a lowercase f in the middle...

craft()->fulcrumDonation_fulcrumCyberSource->exampleService();


Dropdown template URI breaks on language switch

UPDATE:
Mats you were right - I didnt have any data in the french menus or i had random custom url data. Once corrected the entry model came back whole. Phew


Getting entries from different structures and level

If you explicitly need only the entries at level 3, and those at level 1, I think combining two queries works best:

{# Get ids for all entries from the different structures and levels #}
{% set entriesAtLevelThree = craft.entries.section('level-3-section').level(3).limit(6).ids() %}
{% set entriesAtLevelOne = craft.entries.section(['level-1-section-1', 'level-1-section-2']).level(1).limit(6).ids() %}

{# Combine those IDs #}
{% set entryIdsCombined = entriesAtLevelThree | merge(entriesAtLevelOne) %}

{# Get all entries (so, no IDs this time), using your IDs #}
{% set allEntries = craft.entries.id(entryIdsCombined).limit(6).order('postDate DESC') %}

{% for entry in allEntries %}
    {# do your thing #}
{% endfor %}

You can, of course, cache this by wrapping it in {% cache %} tags.


Is there a JavaScript event that is triggered when a field type's settings html is displayed within Matrix?

There’s no event for it, but any JS you include using craft()->templates->includeJs() from your field type's getSettingsHtml() method will get fired each time a new Matrix sub-field is created, so if you code your field type correctly with properly namespaced inputs] IDs/names, no event will be needed.

The thing about Matrix is, there’s no way to predict what the actual input IDs/names are going to be when they are added to the DOM, as they will be run through TemplatesService::namespaceInputs() with the namespace blockTypes[__BLOCK_TYPE__][fields][__FIELD__][typesettings], and those “__BLOCK_TYPE__” and “__FIELD__” placeholders are replaced dynamically by MatrixConfigurator’s Javascript before adding the settings HTML to the DOM.

Regular field settings get namespaced too, but in a more predictable way (their namespace will always be types[FieldTypeClassHandle]), so it can be tempting to just hard-code the namespaced IDs directly into your Javascript, like this:

$js = "\$('#types-FieldTypeClassHandle-myInputId')" // ...

Matrix’s unpredictability shows why it’s important to not do that, and instead always use TemplatesService::namespaceInputId() and namespaceInputName() whenever you need to reference an input’s ID or name from your Javascript:

$namespacedId = craft()->templates->namespaceInputId('myInputId');

$js = "\$('#{$namespacedId}')" // ...

When you let TemplatesService generate the namespaced IDs/names for you, you can be sure that it will always give you an ID/name that will match whatever the actual ID/name will be in the DOM.


How do I reorder Structure entries on the front-end?

The place to do that sort of thing is StructuresService.

If we’re just talking about reordering a flat list of entries (no hierarchy), the only methods you need to worry about are moveAfter() (if an entry is being dragged after another one) and prependToRoot() (if an entry is being dragged to the first position in the structure).

$entry = craft()->entries->getEntryById(1);
$prevEntry = craft()->entries->getEntryById(2);
$structureId = $entry->getSection()->structureId;

craft()->structures->moveAfter($structureId, $entry, $prevEntry);


How does Craft regard a Lightswitch field when it's set to Required in the Fields layout?

Currently it has no affect on the Lightswitch field at all, which I think is the right call.

However, you do have a valid use-case for either making a setting on the field that forced it to be "on" if required is set or maybe even a separate "Require On" field type all-together.

Regardless, probably worth putting up on http://feedback.buildwithcraft.com


Do temporary files stored in craft/storage/runtime/temp get automatically deleted?

The only two times Craft clears that folder is 1) at the end of an automatic or manual update and 2) when you have the "Temp files" checkbox checked under the "Clear Caches Tool" under Settings->Tools.


You can achieve this using the extraFileKinds config setting like this:
'extraFileKinds' => [
    'svg' => [
        'label' => 'SVG',
        'extensions' => ['svg'],
    ],
],

On your Asset field, check the "Restrict allowed file types?" checkbox, and select "SVG" from the list.


Since all asset transforms are saved in a sub-directory starting with an underscore, you could simply test for that.

  Original:
  /assets/folder/house.png

  Transforms:
  /assets/folder/_900x500/house.png
  /assets/folder/_thumb/house.png

Plugin:

If your asset-folder is above public_html, and the request is routed through Craft, you could create a plugin, which checks for the underscore:

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

    //Is resource request?
    if (craft()->request->isResourceRequest()) {

        //Parent directory
        $parent_dir = dirname(craft()->request->getUrl());

        //Check if parent dir doesn't beginns with an underscore
        if (!preg_match('/^[\/\\]*([_]+)/U', $parent_dir)) {
            exit(403);
        }
    }
}

.htaccess:

If your assets can be accessed directly, you'd have to use .htaccess to deny the request. I'm really bad at RewriteConditions, so this would possible be a question for StackOverflow.


Eager loading EntryElementType from custom ElementType in a plugin

The article on StraightUpCraft should be able to point you in the right direction. PHP stuff is towards the bottom of the article.

Examples of Eager Loading Elements in Twig and PHP

Also this Craft hangout is worth watching, it gives a lot of detail on Eager loading. It's over an hour long though, so set yourself some time aside to watch it.

Eager loading Elements


Additions to extraAllowedFileExtensions not showing up in the checkbox list

It's not "restrictable", because you just added it. Why would you then go back and restrict it?

Using extraAllowedFileExtensions doesn't change the checkbox list at all. It simply allows you to upload files in addition to what is available on that list.


Problems exporting entries from ExpressionEngine 3 with Feed Me 2 beta plugin

Just some additional context here, we're referring to the guide for Feed Me 2 here, which leads to the Gist here. This Gist has not been tested with EE3, but should work just fine for EE2.

That Gist is really just a guide to get you started quickly with an export. It's in no way a requirement, as you can simply create your own JSON or XML templates in Expression Engine to output your content. Once that's done, its over to Feed Me to continue as normal.

You might like to refer to https://github.com/rsanchez/json or simply write your own JSON/XML templates.


Craft 3 multi-lingual multi-sites setup with shared assets

You could create 2 site groups. One group for site A and one group for site B.

Sitegroup A will contain contain 2 sites, the other one only one site.
Your setup will look like this

SiteGroup A
    - Site A - language NL
    - Site A - language Fr
SiteGroup B
    - Site B - language Fr

Let's imagine your Site A - language Fr is your primary site. So it will have the base url /. Your Site A - language NL have the base url /nl.

Your Site B - language Fr will have the url whatever.you.like.fr.
You don't need multiple web folders at all because Craft will route every request to web/index.php and sets the currentSite depending on the url structure.

Now you have multiple ways to setup your asset structure. You can either create multiple Asset Bundles in a plugin and load the assets you need or you can just check in your template

{% if currentSite.id == 1 %}
    load these assets
{% else %}
    load other assets
{% endif %}


Can I output the Placeholder Text of a plain text matrix block?

The "docs" means only on the admin form. For outputing a default text on empty fields in frontend you can use the following code in you template:

{{block.FIELDNAME | default("Placeholdertext") }}


What's a Craft way to achieve extra info on specific relationships?

One solution I've come up with is to add a Matrix field that has two fields:

Text Input
Entries Field

Add that field to the "Services" field layout. Then you could add a lookup on the "Boston, MA" page when you iterate over related Services. Do a lookup and say, do they have a Matrix entry that is associated with this entry, and pull in the Extra Info as appropriate.


My Entry URL Format needs are too long for the field restrictions

You could refactor it using ternary syntax and see if it fits. Otherwise you could also do it with a plugin and listen to beforeSaveEntry events.


Evaluating the if statement in entryType

When you do:

entry.type('entryTypeHandleA')

What you're given is an instance of an EntryTypeModel.

So when you do:

entry.type('entryTypeHandleA')|length

EntryTypeModel's __toString() method will be called, which returns the handle of the entry type ('entryTypeHandleA') and |length tells you how long that handle is (16 characters).

So essentially what you're saying is:

{% if 16 > 0 %}

Which is always true.

However, I'm still not clear exactly what you're trying to compare against.

If you're just looking to see if the handle of an entry type is equal to something, then you'd use this:

{% if entry.type.handle == 'entryTypeHandleA' %}
    a
{% elseif entry.type.handle == 'entryTypeHandleB' %}
    b
{% endif %}


Get related entry data within a plugin (ElementCriteriaModel) without extra queries

I fixed this now by using the method buildElementsQuery, like so:

    $query = craft()->elements->buildElementsQuery($criteria, $contentTable, $fieldColumns);

After that, I was able to add custom joins to the query:

$query
    ->addSelect('sport.title sportTitle')
    ->leftJoin('relations sportRelation', 'sportRelation.sourceId = elements.id AND sportRelation.fieldId = 71')
    ->leftJoin('content sport', 'sport.elementId = sportRelation.targetId')

This gave me access to the data I need, without running extra queries. Thanks go out to Bob Olde Hampsink for showing me this.

I'd love to hear though if there is a simpler way that won't require custom SQL, but for now this will do the trick.


Create different types of Donation purchasable? (for Gift Aid etc)

Maybe a bit late but we've implemented gift aid for a client's donations site and whilst in Craft2 and using the Charge plugin it might help a bit.

We added a field to the Charge order which is a lightswitch of GiftAid on or off. As August suggested this could be done in the line item as an options[giftaid] value of Craft Commerce

We then created a couple of twig templates restricted to admin users only. The first one is an index file that lists the calendar months as links to another twig template that lists the details of that months orders as a CSV file for GiftAid reporting.

The code for the css twig template looks like this:

{% set month = craft.request.getParam('d') %}
{% set year = craft.request.getParam('y') %}
{% set firstDay = date(year ~ '-' ~ month ~ '-01') %}
{% set lastDay = firstDay|date_modify('first day of next month') %}
{% header "Content-Type: application/csv" %}
{% header "Content-Disposition: attachment; filename=" ~ month ~ "-" ~ year ~ "-GiftAidReport.csv" %}
{% set postDateParam = ['and', '>= ' ~ firstDay|date('c'), '< ' ~ lastDay|date('c')] %}
{% set charges = craft.charge.charges({
    giftAid: 1,
    dateCreated: postDateParam,
    refunded: false
})%}
CharityNumber, CharityName, ProjectName, FundraisingCampaign, DonorTitle,DonorFirstName,DonorLastName,DonorAddress,DonorPostcode, Description, DonatonDate, DonationAmount, DonationCurrency, GiftAidValue
{% for charge in charges %}
{% set thisName = charge.customer.name|split(' ') %}
<this is your list of CSV fields>
{% endfor %}

I'm sure there is a much nicer way of doing this all in a plugin within the backend but this was a nice quick and easy way to do it.


This has been fixed for the next release. Only affects environments where the web server is not sending missing resource requests (like /cpresources/XXXXXX/logo.svg) to index.php.


So the way Twig works is that it populates a Twig Environment with a context of global variables.

Then any time a template includes another template, the context is passed down to it.

So if you want something to be globally available you have to insert it into the Twig environment before Twig is used, for it to be truly globally available.

You can do that via a Twig extension that implements GlobalsInterface like this:

https://github.com/nystudio107/craft-seomatic/blob/v3/src/twigextensions/SeomaticTwigExtension.php#L36

So you might need to revise how you're doing it actually, and instead of using View::EVENT_BEGIN_PAGE you can just do whatever you need to do inside your Twig extension.


How can I loop through all different Product Types in Craft Commerce?

Hoping this is what you are looking to do?

{% for productType in craft.commerce.productTypes %}

  {{ productType.name }}

{% for product in craft.commerce.products.type(productType.handle).find() %}

  {{ product.title }}

{% endfor %}

{% endfor %}


How to reprocess image transforms that already exist in the database

You can run ./craft clear-caches/transform-indexes to clear your transform indexes.


URI with multiple URL formats (after slug)

You can achieve this by writing a module and using the UrlManager::EVENT_REGISTER_SITE_URL_RULES event.
Basic example:
<?php

use craft\elements\Entry;
use craft\events\RegisterUrlRulesEvent;
use craft\web\UrlManager;
use yii\base\Event;

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

        Event::on(
            UrlManager::class,
            UrlManager::EVENT_REGISTER_SITE_URL_RULES,
            static function (RegisterUrlRulesEvent $event) {
                $artistEntries = Entry::find()->section('artists')->all();

                foreach ($artistEntries as $artistEntry) {
                    $event->rules[$artistEntry->uri] = ['template' => '_pages/artists/news'];
                }
            }
        );
    }
}

Then, in the _pages/artists/news.twig template, you'll need to extract the artist's slug from craft.app.request.url and use it to get the Entry corresponding to your artist.


There is a great tutorial over at Straight Up Craft for handling this (it is however very similar to what you have - it may speed things up a tad though).

  First, we want to grab all of the entry ids from the Section of
  content which we want to display categories for.

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

  Next, we will use the craft.categories tags relatedTo() method to only
  return categories that have a relationship with one of our entry ids.

  {% set categories = craft.categories.relatedTo({ sourceElement:
  entryIds }).groupId(1).find() %}

  Once we have our list of categories that are in use, we can loop
  through those categories and display them in our template:

{% for category in categories %}

{{ category.title }}

{% endfor %}


Store it in a plaintext field, then when you output it, do: {{ entry.myfield | raw }}


Craft 3 redirecting me 404 after fill up registration form

I had made a small mistake to add action in the form tag. its 'users/saveUser' needs to be updated to 'users/save-user'.


Can I change which 'Format' options are available in my Rich Text field?

You certainly can using the Redactor Formatting config.

Locate the config file for the Redactor setting you want to edit in craft/config/redactor and add this line:

"formatting": ["h1", "h2", "h3"],

Or any combination of elements you want to be made available.

For those reading this who can't see the Formatting option for their Redactor field, it's also worth mentioning you need to have the Formatting button set up in the same config file:

"buttons": ["format"],


There is no predefined 'index' page for channels. Channels are simply a collection of entries. If you want an index page then you will need to create it: either as a single, as an entry within another structure, or as a stand alone template in your templates directory (i.e. craft/templates/news/index.html or craft/templates/news.html). In any case, the url (or uri) is going to be whatever you have defined it as. (i.e. mysite.com/news/). See craft's routing documentation for more info on how requests are routed.


Server respond is very long (25s). Is there a way to optimize the perfomance?

Let me try to turn this into a more valuable StackExchange for others who will find it, since the original poster apparently got help and solved his problem without participating here. We can see so on the linked site, which is now running as expected for Craft, quite rapidly.

What I'd like to do is suggest a less awkward way to approach his task. We can do that much more nicely due to Craft's actual abilities, and then there will be no need for index counters, full table scans of data, and so forth as in the original code. The site will then also be more efficient, offering something to the original question, while also having some convenient extra features.

The data involved is naturally hierarchic - Seminar 'plenums' with sessions within them. The sessions are run by speakers, whose information pages are linked. Speakers might be in more than one session, and it's possible that sessions would also be repeated in other plenums, so both should be independent data sets. By using Matrix variables, we can make it very easy to organize plenums, and provide per-plenum information such as times.

Thus in Craft terms, we should have a Channel of plenums, a Channel of sessions, and a Channel of speakers. To give the ordering flexibility, own times etc., and ease of relations, the plenums channel should have a Matrix variable for sessions scheduling. The sessions channel can even more easily use an Entries variable to hold details of the speakers for each session. Otherwise, the channels will contain simple Craft types for each of their data fields.

Such a design will replace the originally posted code with something like the following, which is much more simple and direct:

{% foreach plenum in plenums %}
  ...print plenum fields information
  {% foreach session in plenum.sessions %}
    ...print general session fields information
    ...print plenum-session-specific information, such as location and times
    {{ speaker.speaker_name }}
     {% if not loop.last %}// {% endif %}
  {% endfor %}
{% endfor %}

Note that highly efficient database queries will eliminate table scans and index variables, with the Craft-Twig loop variable supporting clean formatting of single or multiple speakers.

The Craft control panel will let us just pull around sessions within plenums to reorder them, while entering  any changed times or places very easily. Simple variations on this design would allow us as easily to change speakers when necessary for instances of a session, for example.

Since the sessions are only related to plenums, they can appear in multiple plenums just by adding them to the Matrix variable for each. Not much extra work would allow the Matrix variables to hold or over-ride date-times, locations, or even alternate speakers, etc., adding flexibility.

The original poster's site presentation design was appreciated as quite nice for its type, and this picture should show that Craft makes an appropriate data and code design for it just as nice and clean.


My first step to troubleshooting this is to confirm that the Asset Source URL is correct in the source settings.


EDIT:
In the first version of the answer I forgot the /admin part of all the example URLs. Added now.

TL;DR version:

To get to the point first before explaining more in-depth: You need to convert the names from camelCase (with capitalisation in the name) to kebab-case (with dashes instead). I would suggest renaming your controller to simply DataCaptureController, since it's within the Gated Content plugin anyways, and you should be able to use:

https://craftcms.localhost/admin/gated-content/data-capture/index

Full answer:

So, the structure is basically plugin-name/controller-name/method-name, all in kebab case, meaning that what is someName should be some-name, as not all servers are case sensitive (althouth URLs technically are, if I'm correct). Also, the Controller and action parts of the class/method name is implied, as you've already correctly done, but as far as I know, not adding the plugin name to the front of your controller (I have not checked this specifically).

So in your case it should be something like this:

https://craftcms.localhost/admin/index.php?p=actions/gated-content/gated-content_data-capture/index

I am honestly not quite sure how underscores are treated in kebab-case, so it could be that this is the correct form:

https://craftcms.localhost/admin/index.php?p=actions/gated-content/gated-content-data-capture/index

Also, you should be able to use the url like this:

https://craftcms.localhost/admin/gated-content/gated-content-data-capture/index

(Or, if you really prefer for some reason, with /actions in the URL:)

https://craftcms.localhost/admin/actions/gated-content/gated-content-data-capture/index


What criteria can the Element API plugin accept?

The $entry variable that is passed to your endpoint’s transformer function will be an EntryModel object - the same type of object you use when interacting with entries in your templates. So everything you can do in your templates you can also do from this function.

The easiest way to get a Structure section entry’s children is with the getChildren() function, which will actually give you a new ElementCriteriaModel object with the descendantOf and descendantDist params pre-set for you. So here’s what your transformer function might look like:

'transformer' => function(EntryModel $state) {
  $locations = $state->getChildren()->type('location')->find();
  $locationsInfo = [];

  foreach ($locations as $location) {
    $locationsInfo[] = [
      'title' => $location->title,
      'url' => $location->url,
      // ...
    ];
  }

  return [
    'title' => $state->title,
    'url' => $state->url,
    'latitude' => $state->latitude,
    'longitude' => $state->longitude,
    'jsonUrl' => UrlHelper::getUrl("locations/{$state->id}.json"),
    'locations' => $locationsInfo
  ];
},

(Since you’re dealing with multiple entries within your transformer function, I also went ahead and renamed $entry to $state, just so it didn’t get confusing.)


It is actually possible but it's a little bit difficult for beginners. You'll need make use of Service Locators and overwrite craft\web\Response to change this method

foreach ($this->getCookies() as $cookie) {
    $value = $cookie->value;
    if ($cookie->expire != 1 && isset($validationKey)) {
        $value = Yii::$app->getSecurity()->hashData(serialize([$cookie->name, $value]), $validationKey);
    }
    setcookie($cookie->name, $value, $cookie->expire, $cookie->path, $cookie->domain, $cookie->secure, $cookie->httpOnly);
}

setcookie is the key here, because if you use it like that, you can't really include the parameter, so you need call it accordingly with options

setcookie ( string $name [, string $value = "" [, array $options = [] ]] ) : bool

Each yii\web\Cookie only has the following Attributes

public $name;
public $value = '';
public $domain = '';
public $expire = 0;
public $path = '/';
public $secure = false;
public $httpOnly = true;

Since there is no sameSite attribut you have to think about an intelligent way to set it. There is already a feature request for it. Maybe it's easier to ask about the current status.


Perhaps instead of trying to get a template name, use the entry type as the template name, similar to the method that you linked to. In the link, it doesn't check which template is assigned to an entry, but instead, uses the entry type to load a template with the same name. In your example that might look like this:

craft()->templates->render('path/to/template/' . $entry.type, [
  'entry' => $entry
])

Where your template would be named the same as the handle for your entry type. Does that make sense?


What are the best practices for the development setup?

That's the setup we use here. It's ok, but local development runs slowly because the database is off-site - we'll be moving to an internal database server in the new year because of that.

Image transforms we just deal with by manually syncing the folders every now and then. I believe Andrew Welch has a script to help manage that - I've not tried it https://github.com/nystudio107/craft-scripts

But I wish there was a way to tell Craft, in dev mode, that a missing image file is not a "stop everything" error.


How do I italicize words in an entry title?

I would have the user enter the title with markdown formatting: So they would enter
"Title with *italics*" in the title field, and in the template you would display it with: {{entry.title|md}}


Propagate entries manually between sites

i think one solution is new propagation method 'Let each entry choose which sites it should be saved to', introduced in Craft 3.5.
see this issue for more information.


There's nothing that says you have to go through Craft's EmailModel/EmailService for this.

Craft ultimately uses the PHPMailer library, so you can instantiate it directly and use whatever settings you need (or use a completely different library).

I assume you don't want to cram everyone into to "To Address", so is the plan to set the "To Address" to yourself and BCC the recipient list?

Depending on the number of emails you need to send, I'd probably just have your plugin read from the file and insert into a database table.  Then you could setup a cron job to hit your plugin's controller action to send out (one at a time) X emails over Y time period and delete those from the table until its empty.

As far as not getting flagged as a SMTP relay, in addition to throttling email rates, there are definitely other things you can do to reduce your chances.


I don't believe there is a way to minify javascript when it is output to the page.  If there is it would make for increased load time. My suggestion is to use a preprocessor like Gulpjs or Gruntjs.

The basic workflow is when you update your JS file/s the preprocessor can detect the change and concatenate and minify your files into a production file.

You will need to install Node.  An easy way to do that is to use Homebrew.

brew install node

I am including links to a couple files to help you start. One is the package.json file that NPM uses to install the node components.  The other gulpfile.js is a starter file for using Gulpjs, to give you an idea of how to setup the tasks.


Assuming you have an assets field with the fieldHandle teamImage1 then the following should work.

{% if entry.teamImage1|length %}
    {% set asset = entry.teamImage1.first() %}
    {{ asset.url }}
{% endif %}


An unknown error has occurred in asset reindex

Try to call the json file in the browser. There are chance of showing unknown error when the path of the json file is missing in Asset Index.


Can slug and title changes be propagated to multiple sites?

At the moment I believe this can only be achieved with the site-sync plugin: https://github.com/timkelty/craftcms-site-sync


Pass last segment to solspace freeform field

You can use the overrideValues parameter to set field values automatically and dynamically. E.g.

{{ craft.freeform.form("composerForm", {
    labelClass: "form-label",
    inputClass: "form-control",
    overrideValues: {
        myFieldHandle: entry.title,
        myOtherField: craft.app.request.getSegment(3),
    }
}).render() }}


How can I return the number of users registered after a specified date?

Something like this should do it:

craft.users.status('active,pending').dateCreated('> 2015-06-22').total()


How to remove a Super Table row on the front end?

I got a solution!

<input class="remove" type="hidden" name="fields[{{ fieldHandle }}][{{ row.id }}][type]" value="{{ blocktype }}">

So the output will be "1" if you change it to "0" and safe your page the row is deleted! Really simple.


How can I add programmatically a Tag after SAVE_ON event in case of Assets types

A Tag field is like every other relation field. Just insert an array of ids in the field and save the element

$element->setFieldValue('fieldHandle', [1,2,3,4,5,6]);
Craft::$app->getElements()->saveElement($element);

In order to get the current ids and add one, just do

$ids = $element->getFieldValue('fieldHandle')->ids();
$ids[] = 'yourNewTagId';
$element->setFieldValue('fieldHandle', $ids);
Craft::$app->getElements()->saveElement($element);

To Create a new Tag do

$tag = new Tag();
$tag->title = "your new tag name";
$tag->groupId = 1;
Craft::$app->getElements()->saveElement($tag);

// and add it to the element
$element = Craft::$app->getElements()->getElementById(2);
$ids = $element->getFieldValue('fieldHandle')->ids();
$ids[] = $tag->id;
$element->setFieldValue('fieldHandle', $ids);
Craft::$app->getElements()->saveElement($element);

Edit:

Note that I'm using the setFieldValue directly instead of the magic __get and __set methods for a better performance.


Live Preview not showing content, Craft 3

According to Brandon, in live preview, you can no longer use entry.id, you have to use entry.sourceId to get the current draft.

https://github.com/craftcms/cms/issues/5087#issuecomment-541243645


I've had issues before where I was getting logged out and could not fathom why: it turned out (after weeks) that when I was using Inspector Tools' Responsive Design mode, Chrome sends different UA strings... which by default causes Craft to log the user out.

It's a long shot; but see if you're only experiencing the issue when you've got your inspector open and in mobile device simulation / responsive design modes.

The fix for me was to add the following to config/general.php

'requireMatchingUserAgentForSession' => false, // stop Craft logging you out of the CMS while using Chrome's "Device Mode" view for responsive development


It looks like you might have the Smart Maps plugin installed.  There was a bug with earlier versions of it that had a similar error message.  Update to the latest version and it should be resolved.


Access Matrix field that is assigned to a user

You need to use 'currentUser' to access the field. So;

{% for block in currentUser.myMatrix %}
  {{ block.myMatrixField1 }}
  {{ block.myMatrixField2 }}
{% endfor %}

As for creating a new record in the matrix (I'm guessing you mean from the front end) then you need to create a form that submits the current matrix data alongside your new block data. This isn't super straight forward, but basically you need to create a user profile form that submits the current matrix data alongside the new data.


Host your image assets outside of the templates directory. A more appropriate place for UI assets is in the /public directory.

Craft is attempting to parse the image like it is a template, which is causing the Unexpected Character error.


stream_socket_enable_crypto() error when sending email via SMTP

The fix for the specific error was to switch the port number within email settings to 2525 - that took a lot of finding out, but crucially avoids hacking PHPMailer.


Why does {{ user.getPhotoUrl(64) }} point towards storage/runtime and not to storage/userprofiles?

I don't think the /Applications/MAMP/htdocs/craft/storage/runtime/assets/sources/ log entries are related to the request when getResourceUrl() is called.  Of if they are, they are elsewhere in the request and not as a direct result of calling getResourceUrl()`.

The error in the console seems like the one to investigate.  Based on net::ERR_CONNECTION_REFUSED, I'd check to make sure that craft/storage is recursively writable by PHP as a starting point.


Output number of children in a structure

If you want all the descendent too you can use:

{% set totalDescendents = entry.getDescendants().count() %}

https://buildwithcraft.com/docs/templating/entrymodel#getDescendants


Thanks to Brad Bell who solved this for me. There was data in my craft_templatecache* tables. When I cleared them out the issue went away.


The proper way to do this would be to use ElementAPI, however you could create an alternative template with a JSON header coupled with a route.


There are some issues with your PHP syntax – I didn't test this (not sure how the data model returned by craft()->shopify->getProductById() looks, and you'll need to verify that $entry->shopifyProduct returns a Shopify product ID), but at least the syntax errors should be fixed:

return [
    'endpoints' => [
        'api.json' => [
            'elementType' => 'Entry',
            'criteria' => [
                'section' => 'product',
            ],
            'transformer' => function (EntryModel $entry) {
                $shopify = craft()->shopify->getProductById([ 'id' => $entry->shopifyProduct ]);
                return [
                    'id' => $entry->id,
                    'title' => $entry->title,
                    'url' => $entry->url,
                    'shopifyId' => $shopify ? $shopify->id : null,
                ];
            },
        ]
    ]
];


Uploading PDFs with Imagick extension enabled seems to rasterize and compress the PDFs

Got the same problem with Craft3 (3.0.0-beta.19). Had to change the imageDriver to GD.

Add 'imageDriver' => 'gd', to config/general.php and replace/reupload the files in Craft.


Change the fill or stroke colour of an SVG using a field value?

Because you are wrapping {{ entry.myCustomFieldValue }} in ', you are passing it as a string instead of its value, that's why you then see it as is in your result. Try:
{{ svg('@webroot/_dist/stat/link-arrow.svg')|attr({
    stroke: entry.myCustomFieldValue
}) }}


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

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

Should do the trick.


This may be a bug, and is probably worth reporting to P&T.

However, it's very difficult (if not impossible) for them to account for every potential ASCII character mapping for every possible language. For that reason, there is a customAsciiCharMappings config setting, which you can use as a workaround.


I think we need more information to be able to consider possible solutions. I personally wouldn't do anything in Craft, rewriting this URL before it hits the application would be cleaner. I don't know if it's possible to configure the 'action' parameter name in Craft so let's assume not.
Are the referring URLs always the same? In other words, is the visitor always returned to the same URL on your site (which contains &action=something)? If so, a fairly simple Apache/nginx rewrite URL could be written to remove the parameter from the request.
If not, it may still be achievable with a rewrite rule if you're willing to trust the HTTP_REFERER variable.


Redactor fields are not meant to process twig both for security reasons (as they can be changed by any user) and for usability (you cannot expect authors to remember / preserve twig tags).

In your specific example, the site url is probably not necessary (starting a URL with / will link to the current domain just fine) - so you would not actually need twig.

However I cannot think of one good reason to build a menu in a redactor field. I would either include it directly in the page templates (.twig files) or use a matrix field as a content builder.


Not receiving emails from contact us and job application plugin to all email addresses on our domain

As replied to the support ticket: Is the web server setup to handle emails locally for the domain (local delivery)? Your mail servers seem to live elsewhere so that could explain why you don't receive them yet gmail works fine.


Can't duplicate a product in Craft Commerce?

Update:

Added in Craft Commerce 1.1.1196.

There currently isn't a native way, but it sounds like a great feature request!


How can I check if a plugin is installed and enabled, in Craft 3?

PHP

\Craft::$app->plugins->isPluginInstalled('plugin-handle')

Twig

{% set installed = craft.app.plugins.isPluginInstalled('plugin-handle') %}

There is also a isPluginDisabled and a isPluginEnabled function.
Here is a class reference craft\services\Plugins


How do I change the default front-end language in Craft Personal?

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


There isn't a builtin way to manually sort the entries as you can in a structure.

When calling the entries in your templates, you can make use of the 'order' parameter to order the entries returned. From the documentation:

  The order the entries should be returned in. Possible values include
  'title', 'id', 'authorId', 'sectionId', 'slug', 'uri', 'postDate',
  'expiryDate', 'dateCreated', and 'dateUpdated', as well as any textual
  custom field handles. If you want the entries to be sorted in
  descending order, add “desc” after the property name (ex: 'postDate
  desc'). The default value is 'postDate desc'.

For example:

{% entries = craft.entries.section('news').order('postDate').limit(10) %}


{% cache %} tag creates duplicate entries

Correct... by default the {% cache %} tag will use the current page's URI (including querystring) for the cache key.  If you want to change that behavior you'll need to specify the using key parameter and supply a unique key.  Although you might want to make something more unique than just block.id as that will be an integer and could potentially easily be overwritten.


Is it possible to use a lightswitch (or something similar) for different post types?

I think your answer is in the post you referenced. Create two entry types in a single section, each of which contains different fields (and/or some in common). Then loop through all the entries and test for entry type in the output.

{% set entries = craft.entries.section('blog').find() %}

{% for entry in entries %}
    {% if entry.type ==  'linklist' %}

{{ entry.title }}

    {% else %}

{{ entry.title }}

    {% endif %}

    {{entry.body }

{% endfor %}

The user will have to understand how to change the entry type in Craft's UI (it's the dropdown in the right column, but it's pretty clear once they've been shown how to do it once).


Unfortunately not. To do that kind of change your best bet would be to use CPCSS. It's a plugin but really only just provides you with a way to inject custom styles or a stylesheet for use in the control panel. It's well maintained by a responsible author so I don't see any reason to worry about that one.


Craft Commerce: Agree to Terms Checkbox?

We've implemented this using front end JS, simply don't allow submission until it is ticked, but you could (and/or) in theory add a field to your orders and then validate it as set during the onBeforeSaveOrder event I guess?  If not set, you'd set $event->performAction to false to stop the order being saved and show an error in your template.

https://craftcommerce.com/docs/events-reference#commerce_orders.onbeforesaveorder

...but frond end JS is probably going to be the easier route here.


The url's are always bound to entries. And with your current code, you're getting all entries in the 'contact' section, not the section itself.

But if this is a single, what you want is the url of the entry in the 'contact' section. Try this:

{% set contactPage = craft.entries.section('contact').first() %}
{{ contactPage.getUrl() }}


Check which locales of an Entry are active

After doing a quick search through the Craft app folder I found this method:

craft()->elements->getEnabledLocalesForElement($variables['entry']->id)

You can probably use this and send the EntryModel's id as the parameter


Custom environment variable to main assets folder

The easiest way to do this would be to just use root-relative resource URLs:

<link rel="stylesheet" type="text/css" href="/assets/css/styles.css">
<script type="text/javascript src="/assets/js/scripts.js"></script>

The only disadvantage of that is it makes your site slightly less portable – you wouldn’t be able to run it from a subdirectory on a web server without updating all your URLs in the templates.

So a better option would be to define a custom config variable that holds the value of your site’s base URL in craft/config/general.php;

return array(
    'omitScriptNameInUrls' => true,

    'siteUrl' => array(
        'nl' => 'http://krycer.be/nl/',
        'fr' => 'http://krycer.be/fr/',
    ),

    'baseUrl' => 'http://krycer.be/',
),

And then access that config setting from your templates via craft.config:

<link rel="stylesheet" type="text/css" href="{{ craft.config.baseUrl }}assets/css/styles.css">
<script type="text/javascript src="{{ craft.config.baseUrl }}assets/js/scripts.js"></script>

Note that there’s no reason to place that custom config variable within the environmentVariables config setting. The top level of the config array will work just fine for this.


Localhost can't connect to plugin store or updates (WAMP Server)

You need to download the CA certificate for curl and add it to your php.ini


How to include twig in the editor? e.g. Shortcodes for dynamic content

The typical 'Craft' way of doing this would be via a Matrix field instead of a single text block field, so that editors can sandwich the dynamic content (which would be its own block type) in between whatever other block types they select. That way is very powerful, flexible, extensible, and clean...

However, assuming migrating your content to a Matrix setup would be too onerous or undesirable for other reasons, there's nothing to stop you creating your own basic shortcode replacement functionality via Twig's replace filter. For example, in your body field you might insert arbitrary markers like [list-of-entries]... then in the template that outputs the field, you can go to town with defining what each shortcode represents and then replace them like this:

{% set listOfEntries %}

        {% for item in craft.entries.section('something').all %}

{{ item.title }}

        {% endfor %}

{% endset %}

{% set parsedBody = entry.body|replace({
    "[dynamic-address-injection]" : craft.entries.section('something').one().addressField,
    "[video]" : entry.videos.one().embedCode,
    "[list-of-entries]" : listOfEntries
}) %}

{{ parsedBody }}


Is there a way to localise error messages in Craft Commerce 2?

User accounts’ First Name field isn’t required, so I’m guessing this is a custom field?

You can translate your custom field names using static message translations.

Create a new file at translations/<Language>/site.php:

my-project.test/
├── config/
├── ...
└── translations/
    └── <Language>/
        └── site.php

(replace <Language> with your language ID, e.g. el.)

Then have it return an array that translates your custom field names.

<?php

return [
    'First Name' => 'Ονομα',
];


What is the best way to number form entries in Freeform?

If you want to do this without creating a plugin, a "cheat" way would be to use the entry id of the submitted form - that would guarantee that you have a unique number and, assuming they are being saved to the same section, they would be in sequence.


Is there a way to avoid content duplication on multi site setup?

That would probably be the Propagation Method setting in the channel´s settings. There you can choose "Only save entries to the site they were created in" (among other options). The thing is not your template path, but that the entry is stored to both sites (which is useful for, say, two sites that are just different language versions of the same site, and should have the same content).


Craft only stores a small number of things in the Cache. As per this article (disclosure: written by myself) the things Craft will add to a Redis backed data cache are:

Available updates
Plugin store data
GraphQL query results
Some bits of data from the Craft Net API including license information
Project Config modification timestamps
Any data which is explicitly cached by plugins you have installed

Craft doesn't store any data which is cached using twig {% cache %} tags in the Redis backed data cache. The reason for this is discussed here but it boils down to the fact that Craft maintains a relationship between element queries inside the cache block and the cache results. This allows edits to specific elements to be traced back to all of the cache blocks that they might impact and should therefore be cleared.
Brandon puts it a little more succinctly:

[it] provides the most efficient cache-busting logic

Update 8th Sept 2020
Craft 3.5 now stores its {% cache %} tag data in the default data cache configured for Craft. If you are using Redis as Craft's data cache your template caches will now be placed there.
It also moves the cache busting logic out of the database and instead uses Yii's tag based cache invalidation. These changes should be significantly more performant and prevent previous issues with background tasks trying to clean up too many cache entries held in the database.


Is it possible to Filter entry types via the URL?

Yes, it is possible.

Pass the entry type handle to a segment and access that segment using the craft.request getSegment() method. Use this segment variable with the craft.entries .type() method to fetch only the entries of the given type. The example below assumes your entry type handle is in segment 2.

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

{% for entry in entries %}
    <li>{{ entry.title }}</li>
{% endfor %}


Can a User Group Create Drafts of New Entries Only?

Am I missing something here?

Yes, you’re missing a bugfix that should be going out today ;)


add text or image to Craft Commerce confirmation email through the CMS

Even though the emailConfirmation was only one entry it was an array.

{% set emailEntry = craft.entries.section('emailConfirmation').first() %}

setting up the entry to the html was similar to what I thought, but I didn't include the ".first()" so I wasn't getting what I expected.


You'd have to store the complete array into the variable

{% set replaceHeadline = {'
': '
', '
': '
'} %}
{{ entry.richText|replace(replaceHeadline)|raw }}

But instead of storing that variable I'd probably just create a macro for that snippet.

_includes/macros.html

{% macro formatRichText(string) %}
    {{- string|replace({
        '
': '
',
        '
': '
'
    })|raw }}
{% endmacro %}

_layout.html

{% import '_includes/macros' as macros %}

You can now use that helper macro everywhere in your templates

{{ macros.formatRichText(entry.richText) }}

Another recommendation, have a look at the RetconHTML plugin, a nice little plugin to manipulate HTML with Twig.

{{ string|retconChange('h1', 'p') }}


You need to query using strings and your condition should be written as follow:
{% set catYear = craft.app.request.segment(-1) %}

{% set firstDayOfYear = catYear ~ "-01-01" %}
{% set lastDayOfYear = catYear ~ "-12-31" %}

{% set params = {
    section : 'termine',
    datumTermin : ['and', '>=' ~ firstDayOfYear, '<= ' ~ lastDayOfYear]
} %}

{% set beitrage = craft.entries(params).all %}

See documentation for reference :)