Creating a calendar event from within a plugin (stuck on saving)

I got help on Discord. The way to do it was Calendar::getInstance()->events->saveEvent($event); Edit: DateTime also needs to be replaced with Carbon()


Validate fields in Solspace Freeform plugin

You could use the regex field (not sure if that is available in the lite edition). In that field you could put in regular expressions to evaluate the data entered and force an error if the evaluation doesn't work.
For example you could enter this as the regex patter to prevent a field from accepting special characters and numbers:
^[a-zA-Z\s.-_']+$
Freeform also has ways to run validation from either a module or client side with javascript.
Via a module or plugin:
https://docs.solspace.com/craft/freeform/v3/developer/form-events.html#on-validating-the-form
Via JS:
https://docs.solspace.com/craft/freeform/v3/developer/js-plugin.html#adding-callbacks


Craft 3 Deprecation Error from Twig/Extension/Core.php. How to fix?

I figured out the issue.  I was trying to get a single image from a matrix block by block.image|first instead of block.image.one(). The code was in a macro that was used on several templates so those templates got this error.


phpdotenv with multi-lang Craft setup on MAMP

Some troubleshooting steps:

Make sure a vendor/ folder exists two levels up from es/. If not, you need to run composer install in your terminal from the directory that contains a composer.json file. (If you don’t have Composer installed, see its installation instructions.)
Make sure a .env file exists two levels up from es/. It probably won’t, as you’re not supposed to include your .env file in the Git repo. You can copy it from production, or from .env.example if that exists. Then fill it in with working credentials for your local environment.

Matt Stauffer wrote a great article explaining how to get phpdotenv running with Craft 2: https://mattstauffer.com/blog/environment-specific-configuration-for-craftcms-using-phpdotenv/ Probably a good idea to read through that just to get an idea of how it’s all supposed to work (and what the advantages are).


fixedOrder only works with the id param. (If fixedOrder is true and id is set to a list of IDs, it will return the elements in the exact order that the IDs were listed.) It’s currently not possible to query elements in a fixed order based on any other params.

For your use case, the |group filter should work nicely:

{% set kinds = ['pdf', 'word', 'excel'] %}
{% set filesByKind = craft.assets.kind(kinds)|group('kind') %}

                {# Loop through the file kinds in the order we want #}
                {% for kind in kinds %}
                    {% for file in filesByKind[kind] %}

                            {{ file }}

                    {% endfor %}
                {% endfor %}


What files does Craft store in "craft/storage/runtime/temp"

The easiest thing is to look it up. Craft CMS is usually really self-explaining So when you take a look at your folders in craft/storage/runtime/temp you'll see the following

/assets <- for example cached thumbnails/preview icons and all those things
/cache
/compiled_templates <- templates that have cache tags, that should only compiled once... for example static pages that does not change that much
/HTML <-- mostly some json objects
/logs <-- well seems obvious
/state <-- Yii.CSecurityManager.validationkey a json object

The compiled_templates folder could become huge when you messed around with cache tags too much or if you have a really large site.
assets will grow when you insert many assets.

The purpose of this folder is to make Craft CMS faster because it does not have to generate HTML, thumbnails and so on with every page refresh, instead it uses already generated files.

How big is this folder for you? Does it require too much space?


logo uploaded through backend doesn't come through (on my environment)

My colleague had used a  local server name 1 char different to mine.

The domain I was using didn't match the "siteUrl" param in the general config.

The image was loading in with a different domain to what I was on.


Get all available fields in plugin setting page

The fields service does include a method getAllFields:

$fields = Craft::$app->fields->getAllFields(false);


I just published a plugin called Limit Block Type, which adds the ability to limit Matrix blocks per block type.

There's also a feature request for adding this feature to core.


Plugins with element criteria selection does not work for empty or zero values

When you do this:

$criteria->accent = '';

Craft is going to look for users where the accent field’s DB cell is an empty string.

Those values are probably null though, if they aren’t getting returned.

Try setting your accent param to :empty: instead of ''. When you do that, Craft will search for both empty strings and null values, so you should get the results you’re expecting.


Prevent redirecting to the control panel from a URI of "/login" when logged in

I can confirm this is a bug in the latest build of Craft (2.1.2570).  The fix for this will be in Tuesday's (09/02/2014) release.

UPDATE

This bug has been fixed in Craft 2.2. http://buildwithcraft.com/updates#build2579


Why does asset creation not work for hidden images?

Set generateTransformsBeforePageLoad in your config/general.php file.

'generateTransformsBeforePageLoad' => true,

  Configures Craft to generate new image transforms right when getUrl()
  is called, rather than when the browser first requests the image.


I had the same issue, turns out I had Craft Commerce Lite installed when the feature requires the Pro version.


Get full url of asset, not just the path

You can slice the / from the end of {{ siteUrl }} and combine it with getUrl relative path:

<meta property="og:image" content="{{ siteUrl|slice(0,-1) }}{{ entry.fieldName.one().getUrl('kafel620') }}">

This will produce expected path:

<meta property="og:image" content="http://site.local/assets/images/ramPamPam/headers/_kafel620/tagiatelle.jpg">


I had a similar issue where my '*' was being chosen all of the time, meaning all my environments used the same DB details.

Possibly try splitting it up, and not have a '*' for your DB details, for any environment?


PHP Fatal error: Allowed memory size of X bytes exhausted

Craft will run out-of-the-box with 32M of memory, no problem.  However, memory consumption will start to increase depending on several factors including:

The complexity of your site, including the number of fields, sections (and types of sections), categories, tags, users, entries, plugins in use (and how efficient they are working), etc.
More importantly, how your front-end templates are coded and how they are pulling in all of this data in.

Also worth noting that 32M is usually the default on older PHP installs (or really stingy newer hosts) and the latest PHP releases ship with something more reasonable, like 128M.

If you enable devMode, you can view memory profiling information in your browser's console to help you see where the memory is being distributed.


The following code fires the onBeforeEmailSubmission event (link)

// Fire an 'onBeforeEmailSubmission' event
$event = new Event($this, array(
    'email'      => $notificationEmail,
    'submission' => $submission,
));
$this->onBeforeEmailSubmission($event);

So you'll have access to the $submission and to the $email as array keys in your $params variable. In order to get the form you have to do

$submission = $params['submission'];
$form = $submission->getForm();
if($form->handle === 'whatever'){
     // do something
}


How/Can does Craft handle ancestor/grandparent relationships?

As usual with Craft you have several options. If you didn't need the index pages, I would suggest a location category, which you organized into 3 levels: states, regions, counties. Selecting a county location would also select its containing region and state. In your town entry you would do:

{% for l in entry.locations %}
  {{l.title}}
{% endfor %}

You would go through the loop three times, and {{l.title}} would be the state, region, and then county.

Disadvantages:

nothing in Craft enforces that you properly organize your location categories
nothing in Craft keeps you from choosing 3 states instead of one county for your town entry
the location index pages will be hard to write

Another option is to use a channel (or category) for states, a channel for regions, a channel for counties. The county entry would have a field for the containing region, the region entry would have a field for the containing state. And the town entry would have a field for the region. Then in the town template:

{{ entry.region.first.county.first.state.title }}

This will fail badly if any of the required relationships aren't there. You can test everything before you use it:

{% if entry.region.first %} ...

Or you can use the ?? (null-coalescing) operator:

{{ entry.region.first.county.first.state.title ?? 'no state' }}

Fetching the state title will be fairly expensive. You could use the preparse plugin to save the state name on the town entry.

For the index pages, you will want the regions that are related to the state, etc.


What's the recommended way to include vendor library dependencies in your plugins?

Composer!

There's already a package for Stripe: https://packagist.org/packages/stripe/stripe-php

Install composer.
Add a composer.json file in your plugin's root folder.
Add this to the composer.json file:

{
    "require": {
        "stripe/stripe-php": "1.17.2"
    }
}
Run php composer.phar update from your plugin's root folder.
The library will be installed in a /vendor folder in your plugin.
Add an init() method to your main plugin's class file with this in it:

require CRAFT_PLUGINS_PATH.'/pluginhandle/vendor/autoload.php';

And you're done.

Composer will handle autoloading all of the class files, so you don't need to worry about it.

If you ever want to update the Stripe library to a newer release, grab the version number from the packagist site, update your composer.json file with it and run php composer.phar update again.


Get a named parameter value from request

It is passed as a parameter to your function

public function actionView($post_id){
    Craft::dd($post_id);
}

Note: your parameter must have the same name like defined in your route. You can't access it with public function actionView($postId)


Widget initialized in Business Logic plugin not loading

Sounds like you haven't loaded jQuery on that page. You'll need to make sure that jQuery is loaded before your {{ craft.businessLogic.shortcode }} tag.


Until the plugin store arrives, the complete list of available plugin is here:

  http://straightupcraft.com/craft-plugins

I don't know of any quiz plugins specifically. I did build a rudimentary quiz for a client, using only a matrix field. Depending on how you wanted to architect your quiz, a plugin may not even be necessary.


Upgrade C2 to C3 Uncaught TypeError involving Dotenv

Using a earlier version of Craft (3.3.3) solved the problem. Updating from there was shaky but eventually worked.


Deploying Craft 3 site to production has working admin but 503 front end


Similar to How to fix "ambiguous" column error generated when DeleteStaleTemplateCaches is run?

But somewhere, in one of your templates that are using the {% cache %} tag, you're ordering by dateCreated in your template and it should be elements.dateCreated.

The {% cache %} tag has already picked up the invalid Twig code and cached it to the database so whenever the DeleteStaleTemplateCaches task tries to run, it trips up on the invalid Twig.

So after you fix the original error, you'll want to clear your template caches using the Clear Caches tool under settings in the control panel to purge the invalid cached code as well.


Charge Plugin - Stripe payments occasionally not being received in craft

At first glance I cannot tell you why your plugin runs intermittently.
But if your plugin is interacting with Charge, there are some log functions you can use that may be helpful.

craft()->charge_log->email("yada yada");
craft()->charge_log->note("yada yada");
craft()->charge_log->error("yada yada");


Errors occuring with Assets and Amazon S3

There are a few regions that support only S3's v4 of signing requests without the possibility of falling back to v2.  The S3 library that Craft 2 uses only supports S3 v2. Check this table for reference - if it says "Version 4 only" in the last column then that region can't be used in Craft 2.

We're not switching out that library in Craft 2.x, but it won't be a problem in Craft 3, so currently your best bet is to move your bucket to a different region, which also supports S3 v2 signing of requests (any other one, really).


Limit slugs to ASCII for auto-generated titles

Since the slug is used to generate assets folders, accents aren't suitable and results in question marks in the folder names.

You could do something similar to How to rename filename of asset before (or after) upload in Craft 3 in a plugin except you run the folder name through the same ASCII normalization process that auto-generated slugs go though.


Solution for Matrix-within-Matrix (or More Robust Table Fields)

Rather than trying to store multiple stats together in a single block, another option would be to make a "Stat" (singular) block type, which only holds a single stat, and just have authors create as many of those as they need, positioned together.

From your template, when looping through blocks, you can check to see if the current block is the first/last of its type, and add some extra HTML when that's the case, so that consecutive Stat blocks still appear grouped together in the rendered HTML. Something like this:

{% for block in entry.myMatrixField %}

    {# Find out if this is the first/last consecutive block of this
type #}
    {% set type = block.type.handle %}
    {% set isFirstConsecutiveBlockOfType = (loop.first or type != block.getPrev().type.handle) %}
    {% set isLastConsecutiveBlockOfType = (loop.last or type != block.getNext().type.handle) %}

    {% switch type %}

        {% case 'stat' %}

            {% if isFirstConsecutiveBlockOfType %}

            {% endif %}

            {% if isLastConsecutiveBlockOfType %}

            {% endif %}

        {% case 'quote' %}

            {% if isFirstConsecutiveBlockOfType %}

            {% endif %}

            {% if isLastConsecutiveBlockOfType %}

            {% endif %}

    {% endswitch %}
{% endfor %}


How to reference a folder inside of a volume, Craft 3

You could run a query to fetch the folderId you need based on the name:

{# Change this to your volumeId #}
{% set volumeId = yourVolumeId %}

{# Change this to your folderName #}
{% set folderName = yourFolderName %}

{# Returns an ID if there is a match, otherwise false #}
{% set folderId = craft
    .query()
    .select(['id'])
    .from('{{%volumefolders}}')
    .where(['=','parentId', volumeId])
    .andWhere(['=','name', folderName])
    .scalar() %}

{% if folderId %}
    {% set assets = craft.assets().folderId(folderId).all() %}

    {% for asset in assets %}
        ...
    {% endfor %}
{% endif %}


You have to listen to the onBeforeSaveEntry event, then query the database for the existing entry (if one exists).

craft()->on('entries.onBeforeSaveEntry', function(Event $e)
{
    if(!$e->params['isNewEntry'])
    {
        $updatedEntry = $e->params['entry'];
        $currentEntry = craft()->entries->getEntryById($updatedEntry->id);

        if($updatedEntry->getUrl() != $currentEntry->getUrl())
        {
            // Do your thing
        }
    }
});

It might also be worth checking if the updated entry even has a URL, so you could skip that DB query if you don't need it.

You have to be careful with this event though - there's always the possibility the transaction could fail and the updated entry won't get saved to the DB. In that case, you might want to also listen to the onSaveEntry event (if you're doing anything other than writing to the DB - this would get rolled back automatically if something fails) as a way of checking if everything went okay.


How can I get the parent category group via the category to create multiple relation criteria?

Not 100% sure if this is correct, but this works.

Example urls:

www.mysite.com/cars/corvette/red
www.mysite.com/cars/red/corvette
...
www.mysite.com/cars/red/
www.mysite.com/cars/corvette

Here is my template:

{#
 # Check if there are multiple url segments to compare against.
 # This means we need to check against multiple relationships.
 # Ex: All Corvettes that are also Red
 #
 #}
{% if craft.request.getSegment(4)|length %}
    {% set secondaryCategory = craft.categories.slug(craft.request.getSegment(4)).first() %}
    {% set entries = craft.entries.section('mySection').relatedTo(['and', { targetElement: primaryCategory }, { targetElement: secondaryCategory }]) %}
{% else %}
    {#
     # Get all products related to the current category.
     # Ex: All Sports Cars that are related to Corvettes.
     #
     #}
    {% set entries = craft.entries.relatedTo(primaryCategory) %}
{% endif %}

...

{% if entries|length %}
    ...
{% endif %}

What i'm not sure about is both are using targetElement instead of one being sourceElement.


Output Channel entries on another page with a matrix block

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

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


Commerce Manage Settings for User Groups

This is currently not a native Commerce feature, but feel free to add a thumbs-up/comment to this feature request, which is what you're asking for: https://github.com/craftcms/cms/issues/1082


How to remove entries with craft migration safeDown elegantly

As mentioned by Oli, I was able to use deleteElementById($entry->id). Note $id now refers to $elementId
/*
 * Find the matching entries to delete
 */

$entry = (new \craft\db\Query())
->select("elementId")
->from("content")
->where( "title = " . $title )
->all();

/*
 * Delete the entry
 */
foreach( $entry as $key => $value ) {

  // Hard delete.
  $success = Craft::$app->elements->deleteElementById( $value['elementId'], null, null , true );

}

Now entries deleted also deleted slugs that were created. But there was one problem: entries deleted previously before this migration code upgrade were still there. I found that these slugs were kept in the table element_sites and I manually deleted all the old slugs no longer being used. So far there has been no issue with this and the rest of the site functions apparently normally.


Search for related entries based on tags

This should work:

{% set tags = entry.q_tags %}
{% set entries = craft.entries.relatedTo(tags).order('score').find() %}


Contact Form - ReplyTo or Output fromEmail

Not without hacking (boo!) or forking (yay!) the plugin.

Currently, the fromEmail is being set from the email address set in the plugin's setting.

$email->fromEmail = $emailSettings['emailAddress'];

And the replyTo is being set to the email that was supplied on the front-end contact form.

$email->replyTo   = $message->fromEmail;

This is done because some email servers will see that the from address is different than the domain the email originated on and wrongly mark it as SPAM.

You'd adjust those however you need.

If you want to output the email in the message body, you'd just need to add it to the $message->message property in the controller.

Alternatively, you can use a more robust form building solution.


How can I change status of all the entries in a channel to closed?

Grab all of the entry IDs you want from the craft_entries table, then find the rows matching those IDs in the craft_elements table and set their enabled column to 0 to disable them en masse.


How-to display a dropdown field with optgroups?

This would work for both with or without optgroup (replace aDropdown with your fieldname):

{% set field = craft.app.fields.getFieldByHandle('aDropdown') %}

{# If we have optgroups in this field, set a counter to 0 else return false #}

{% set optgroupCount = field.optgroups ? 0 : false %}
<select name="fields[aDropdown]">
    {% for option in field.options %}

        {% if option.optgroup is not defined %}
            {# This is a regular option #}
            {% set selected = entry is defined ? entry.aDropdown.value == option.value : option.default %}
            <option value="{{ option.value }}" {% if selected %}selected{% endif %}>
                {{ option.label }}
            </option>
        {% else %}
            {# This is an optgroup #}
            {# Check if we should close a group before opening a new one.#}
            {{ optgroupCount > 0 ? '</optgroup>' }}
            <optgroup label="{{ option.optgroup }}">
            {% set optgroupCount = optgroupCount + 1 %}
        {% endif %}

    {% endfor %}
    {# If we had optgroups better close the last one #}
    {{ optgroupCount ? '</optgroup>' }}
</select>


How can i get all values in a global set

Have a look at the answer given here to someone trying to solve this in the template. With a plugin you'd probably do it like so:

public function getFieldsByEntry($entryModel)
{
    $fields = array();
    $fieldLayoutFields = $entryModel->getFieldLayout()->getFields();
    foreach ($fieldLayoutFields as $fieldLayoutField)
    {
        $fields[] = craft()->fields->getFieldById($fieldLayoutField->fieldId);
    }
    return $fields;
}


How do you create an alternating layout in a template? i.e. an image on right then an image on left

Personally I'd do this in pure CSS. e.g.,

        ...

        ...

CSS:

.item {
    overflow: hidden; // expand around floated children
}
img {
    float: left; width: 50%;
}
.text {
    float: right; width: 50%;
}

.item:nth-of-type(2n) img {
    float: right;
}
.item:nth-of-type(2n) .text {
    float: left;
}


Conditional fields based on structure level

This is not possible natively to have conditional fields based on the structure's level. For the same cases as yours, I'm also using different entry types.

Maybe you could consider moving your children to a Channel and link them to their parent using an Entry field + some routing, or using one of the plugins bellow to add a bit of hack, but I would not recommend it at all:

https://plugins.craftcms.com/conditions
https://plugins.craftcms.com/cp-css


Can I assign an image for a product type listing page?

I would say it's intended that you use Craft's in-built system for product classification/hierachy/taxonomy - i.e. Categories.

Categories have support for custom fields of course, thus you can add backend manageable category images easily using an assets field, and you can also leverage all the things categories can offer without requiring anything extra from Commerce.  And any plugins etc. that work with Categories then work out of the box with your products, too.  Indeed, with Craft's neat separation of Category Groups, this still allows for good separation of your products from the rest of your data (whatever that might be, blogs etc).

I would recommend Product Types instead for managing separation of data concerns more so than product classification.  That is to say, if you have products requiring clearly different data (e.g. your sell monitors, and printers - these clearly require different lists of specifications) - that's a good use of Product Types allowing you to have the specific fields you need for these things nicely separated.

In addition to specific product types where your data determines you need them, we find it handy to have generic product and product with variant types to cover those sundry things that don't fit neatly into the various data separations we've made - with these things having just the core fields that all your products share.


Limit/offset output of Matrix field by 50%

This is what I have used, some math and the slice filter.

{% set midIndex = ((entry.myMatrixField|length) / 2)|round - 1 %}

{% set blocksA = entry.myMatrixField|slice(0, midIndex) %}
{% set blocksB = entry.myMatrixField|slice(midIndex, null) %}


Evenly dividing up table items in columns

It's actually quite simple! What you're looking for is Twig's batch filter... Ironically, the example given on that page is nearly identical to what you are requesting.

I've adapted the example to more closely match what you're looking for:

{% set myData = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] %}

{% for column in myData|batch(3, 'No item') %}

            {% for item in column %}

{{ item }}

            {% endfor %}

{% endfor %}


Overriding isSystemOn setting for a single page

I realized there is a simpler solution after stepping away from this issue for a bit. There is one page that still returns a 200 code on a Craft site even when the isSystemOn (or isSystemLive as of Craft 3.1) is false. Using the control panel login page as a health check url is the solution.


Calling plugin controller externally fails with 500 error

So my question is – is there anything special to be aware of when calling plugins from the outside?

Not particularly.  They're both hitting the same controller endpoint in your plugin, but there are about a million flags/options you can pass into wget to change it's runtime behaviors you might want to play with.

Personally, I stick with using cURL for cronjobs.

Regardless, the behavior you describe sounds like a webserver/Apache crash or segfault.  If they are long-running scripts and you inadvertently triggered them multiple times, maybe you hit some hard resource limits. If that's the case, the underlying error message would be in your web server's error logs for the 500 Internal Server Error.

If it were Craft generated 500 ISEs, then the underlying error message would be in craft/storage/runtime/logs.


Output children of a structure section in reverse order

The primary parameter you're looking for is lft:

craft.entries.section('volumes').order('lft desc')


There's nothing native in Craft that would allow you do to that.

Should be possible via a Craft and Redactor custom plugin, though, I'd guess.


List all entries below top level 1 in a structure section (level 2 or 3 or 4 ...)

Alright. you can just exclude the top level entries with not:

{% set entries = craft.entries.section('library').level('not 1') %}


Display & check-for User Group on public profile

If you know the user will only belong to one group, something like this should do it.

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

{# make sure we found a user %}
{% if user|length %}
    {% set groups = user.getGroups() %}

    {# make sure they belong to at least one group #}
    {% if groups|length %}
        {# display the name of the first group #}
        {{ groups[0].name }}
    {% endif %}
{% endif %}


How can I delete all entries that belong to a user?

You'll want to set the authorId of your entry to be the new user's id.

When you delete that user through the control panel, it'll ask "What do you want to do with this person's content?"... At that point, you can just select "Delete it".


How can I get contact form added information on the control panel?

You can find the Contact Form Extensions plugin in plugin store. It’s free to use.

Install it and then fill the setting form as you need it. After that settings completed you will see the new option “Form Submisson” in your side bar menu in control panel. You will get all filled contact form records in it from now on.


P&T Contact Form Plugin: HTML Email Templates

If you mean to build a template for all the e-mail messages, including the ones sent by P&T Contact Form Plugin, then you should at least have Craft Client edition, which supports Custom HTML email templates.

If you have Client or Pro, you can set an e-mail template in your Email Settings (in the field called HTML Email template).

If, on the other hand, you want to change the text sent by the plugin (so the body of your e-mail), I don't think there's a way to do that without altering the plugins code.


Best Technique for have sections in display in same page with anchor link to each section

What I should do is create a category group whish should be filled with your "Food Categories". Once you've done that you could display them in your side menu. (If you show the menu on everypage make sure to include it in your _layout.html or as a new block however you like it.

For your food category section.

You could create a Channel for those. Add all the fields you need and put them in there. Don't forget to create a Category field connected to your food categories group. This way you can link an entry to the category it's supposed to go too.

If you created a couple of entries and connected them to their categories. You can display them in the big section by looping over all the entries in your Food Channel. You can grab the category by looping over the category field you made. This way you can add the coloured banner which belongs to the chosen category.

Here are some links for all this:

https://craftcms.com/docs/templating/craft.categories

https://craftcms.com/docs/categories-fields

https://craftcms.com/docs/categories

https://craftcms.com/support/entries-related-to-category

Craft CMS also has a slack community. For more detailed questions you could ask for help there. You can checkout how to join here.

https://craftcms.com/community#slack


Duplicate meta descriptions when category has multiple pages

I would add custom fields to your category group, for META Descriptions. This would allow you to display meta data when on a 'category home page'.

Then on a single entry page, the entry-type custom fields for meta data would be used.

See this example/answer: How do I define an entry's META description?


Filter Sprout Forms entries based on field value, using parameters

Filtering entries is now possible as of Sprout Forms v2.2.0:

{% for formEntry in craft.sproutForms.entries.formHandle('contact').firstName('Zoe') %}
  ...
{% endfor %#}


Fixed by changing the following line:

'siteUrl' => 'http://testurl.com',


Is there a way to output only the first paragraph of a Rich Text field?

You can do this entirely with Twig.

First, use the |split filter to split your HTML into an array of paragraphs, on their closing
 tags:

{% set paragraphs = entry.myRichTextField|split('
') %}

Then, you can assign the first paragraph to a new variable using the |first filter. And don’t forget to bring back that missing
.

{% set firstParagraph = paragraphs|first ~ '
' %}

Finally, you can output that. Use the |raw filter so that Twig doesn’t encode the HTML entities.

{{ firstParagraph|raw }}


Populating Matrix Blocks with JavaScript

This is not documented because the P&T team sees this as internal functionality I guess.
Looks like the control panel is going to be rebuilt in version 4 anyways probably in Vue. So you would have to rewrite your entire script too. If it‘s going to be Vue there is probably no way to use their JS API anyways.
Even if it sounds funky I would suggest you to imitate the user input with JS. Just crawl the DOM for the buttons and inputs and fire click and input events on these. This way you could even provide meaningful error messages in the console for yourself, for example if some button selector stopped working after a Craft update because maybe they changed the markup.
As an alternative solution I see a PHP script that populates the entry before rendering it in the entry edit view. However I don’t know if there is an event in Craft where you could hook into the right place.


How do I change a user's password programmatically in a plugin?

You shouldn't need to call changePassword() at all.  Try this:

$user = craft()->users->getUserById(6);
$user->newPassword = 'mynewpassword123';
craft()->users->saveUser($user);

If it's not updating correctly, then there is likely a validation error somewhere.  You can check that with:

$user->getErrors();

Which will return an array of properties that failed validation and their error messages.


Okay. So, my problem was that I had multiple Asset Sources since I was trying to give my groups permissions to specific sub-directories. This was causing indexing issues which is why I wasn't seeing the images show up.

CraftCMS has an excellent customer support. They were able to create a plugin that allowed me give my groups permissions to their subdirectories.

Link to plugin: https://github.com/pixelandtonic/AssetSubfolderAccess

All you have to do is create your user groups. Then create an asset source configuration that points to your root folder that will contain the subdirectories. Give your user groups permission to the Asset Source (Root folder).

Then on the plugin page after you have installed the plugin. Click on the plugin to go to its settings. This is where you can configure each of your user groups to only have access to their sub-folder. =)

Huge thank you to CraftCMS, Pixel And Tonic, and Brandon for all the help. You guys are amazing!!! =)


Craft Commerce 2, turning on debug bar and getting error

Delete all active carts in the control panel and the errors will go away.

You changed the base currency and some exisiting carts are referencing a non exisiting currency. This should only be happening in development as you wouldn’t change the base currency for an existing site.


Creating a modal warning for an external link?

A modal cannot exist without JS... no matter how it is triggered.

At best, you'd have the user navigate to an intermediate page, with "Forward" and "Back" buttons. That being said, the UX sounds pretty terrible in that case.

You're actually dealing with conflicting requirements:

Must warn people before leaving site.
Must be non-JS compatible.

Those two requirements will never really be in harmony.


There currently aren't any docs for _includes/forms... you'll need to backwards engineer it. You'll notice some common patterns as you dig in there, which gives great insight into the overall Craft structure.

That file (or batch of files) is one of the most commonly backwards engineered parts of the core code. You may be able to find other posts (on Stack Exchange or blog posts) which describe it in some detail, but you'll still want to investigate on your own.


How can I check from a plugin config file if devMode is enabled?

For those coming here using Craft 3, it's now Craft::$app->getConfig()->general->devMode.


Searching for item SKU in Commerce orders

Use the hasPurchasable order query param:

https://docs.craftcms.com/commerce/v2/dev/element-queries/order-queries.html#haspurchasables

{% set myOrderQuery = craft.orders()
    .hasPurchasables(product.defaultVariant)
    .limit(10)
%}


How do I perform a critical update if my Craft site relies on older plugins?

I'd want the client knowingly and enthusiastically on board with a sensible plan that'd support business goals and the nature of evolving software.

Either a) do with fewer plugins/integrations, b) invest in privately upgrading the plugins, c) open source the work if possible and ask for improvements with fingers crossed, or d) rethink the site so it's less directly dependent on these plugins and thus safer from a repeat of this scenario should a-c seem unattractive. (Freezing the Craft version and avoiding software updates should be unacceptable as it's risky and invites compounding future problems—might as well pick e) move to a static site.) Re-affirm the importance of the CMS and each plugin, or remove the cruft from the equation.
The solid and ongoing work behind Craft, and the support that comes with it, is a steal and having a well-tailored CMS likely empowers employees in various ways—decreasing dependency on (and cost of) web nerds or additional training to update content. If nothing else, staying up to date takes advantage of lots and lots of work that's included in the price of a license while keeping the site as fast and secure as possible.
I'd encourage the line of thought and compare other ways of meeting those objectives. For example, I might contrast the (nonexistent) maintenance costs of running a SquareSpace site compared to the freedom and flexibility of hosting a Craft install. The site, as it is, is most likely supporting current business objectives and keeping it up to date will make it possible to quickly and elegantly support future business objectives with great agility. It may not be worth it, but I'd try and help them understand how much versatility they have for the (un-sexy) cost of maintenance and burden of technical diligence. Odds are they chose Craft and their custom plugins for a reason and those reasons are still vitally relevant, as is the ability to stay nimble in the future.

You might also try to get Ben Parizek on the horn and submit the whole site for a Straight Up Craft code review. In my experience, that can be one way to get rid of unnecessary plugins.


If you reverse the relationship then you should be able to order the entries (i.e. add products to an entries field within the category, instead of adding categories to a categories field within the product).

So instead of grabbing the products using relatedTo(category),

{% set products = craft.entries.section('products').relatedTo(category) %}
{% for product in products %}...{% endfor %}

you would be able to grab the products directly from the products entries field in the category using category.productsFieldHandle, which should be returned in the order defined in the CP.

{% set products = category.productsEntriesFieldHandle %}
{% for product in products %}...{% endfor %}


Why does getting a single block in NEO prevent getting the remainder of the blocks?

This is because of a change in Craft 3 and you need to clone your query (docs).
I have not tested this but the below should work:
{% set blocks = entry.nutritionBuilder %}

{% set item = clone(blocks).type('blockCalories').one() %}
{{ item.nutritionValue }}

{% for block in clone(blocks).level(1).all() %}
    ...
{% endfor %}


Which string identifiers for field types do exist?

I don't know if any enum exists (couldn't find it in source), but you could have a look at the contents of the craft/app/fieldtypes folder (and ignore BaseFieldtypes, DataModels and interfaces) to find the identifiers:

UsersFieldType.php
TagsFieldType.php
TableFieldType.php
RichTextFieldType.php
RadioButtonsFieldType.php
PositionSelectFieldType.php
PlainTextFieldType.php
NumberFieldType.php
MultiSelectFieldType.php
MatrixFieldType.php
LightswitchFieldType.php
EntriesFieldType.php
DropdownFieldType.php
DateFieldType.php
ColorFieldType.php
CheckboxesFieldType.php
CategoriesFieldType.php
AssetsFieldType.php

String identifiers correspond to the file names (without "FieldType.php", obviously).


Attach Custom Information to Commerce Order Model

Add a custom plain text field to your orders, say test.

Then, when calling updateCart, you can add data in to this custom field using a form with an input named like this:

  <input name="fields[test]" type="text"> etc...

This data will then get saved with the order.  This same approach can basically be applied to any field/type.

To actually validate the data, you'll need to look to making a plugin, most likely listening to onBeforeSaveOrder to check the vailidity of the data.  If valid, great, if not, set perfomAction to false and return an error on the Order model.

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


Currently not, but there probably should be.

There is already a somewhat related, similar feature request here.


Structure - Add class if element has children

The Methods section on the EntryModel documentation page has a lot of useful things for working with navigation for Structure sections. You can use hasDescendants():

{% if entry.hasDescendants() %}class="has-dropdown"{% endif %}


how to includeJsFile in head instead of body

You can use the getFootHtml function to tell Craft where to output HTML queued up with includeJsFile and includeJs. You'd normally have that tag somewhere at the end of your <body>. But all it does is to get all queued up HTML and output it, so if your JS are already "included", you can use it in <head>.

Another thing you could do is to not use the includeJsFile function to add the HTML to the <head>, but use a different approach. Here's an example using a var and an example using a dedicated Twig block:

index.html

{% extends 'base.html' %}

{% set headHtml = '<script src="{{ url('assets/javascripts/myscript.js') }}"></script>' %}

{% block head %}
    {{ parent() }}

    <!-- Scripts -->
    <script src="{{ url('assets/javascripts/myscript.js') }}"></script>
{% endblock %}

base.html

<head>
    {% block head %}
        <!-- Document head -->
        <meta charset="utf-8">

        {% if headHtml is defined %}
            <!-- Scripts -->
            {{ headHtml }}
        {% endif %}
    {% endblock %}
</head>


I think you should be ok to just copy the ca_ES file and rename it to whatever handle you like. Full instructions here: https://craftcms.com/knowledge-base/adding-additional-locales-in-craft-2#creating-custom-locales
I had to do this myself for an Icelandic locale and it worked fine.


When a connection to the database can't be made Craft throws a 404. This sound like it might be your problem because you say it happens intermittently.


Indeed: http://buildwithcraft.com/docs/searching

Anywhere there is a search bar in the control panel, you can use any of the syntaxes listed on that page.


How do you auto zoom/center Smart Map with multiple markers?

So for starters, let's clear something up for anyone visiting this thread:
We're talking about JavaScript... specifically, how to manipulate a map that has already been generated. The official documentation on what kind of variables (maps/markers/info bubbles) which are created by the plugin can be found here...
Beyond that, you can basically do anything you want with those JS variables. Much of that is beyond the scope of what I can help you with, but I'll try to at least point you in the right direction.

Map JS object
The way you'll want to refer to the map is like this:
smartMap.map['smartmap-mapcanvas-1']

By default, the map will be called "smartmap-mapcanvas-1" (or 2, 3, etc). But this value can be easily overridden when creating your map, by using the id parameter in your options.
Now that you've got this map object, you can do anything you want via the Google Maps API.
Marker JS objects
When you're referring to individual markers, the format looks like this:
smartMap.marker['smartmap-mapcanvas-1.100.myAddressField']

That naming scheme breaks into three separate components:

Your map ID ("smartmap-mapcanvas-1")
The element ID ("100")
The field handle ("myAddressField")

Now that you've got this marker object, you can do anything you want via the Google Maps API.
Info bubble JS objects
The format for marker info bubbles is nearly identical:
smartMap.infoWindow['smartmap-mapcanvas-1.100.myAddressField']

Now that you've got this info window object, you can do anything you want via the Google Maps API.
Debugging
Finally, since it's not always clear what maps, markers, and info bubbles have been created, you have these three functions available to you for debugging purposes...

smartMap.listMaps()
smartMap.listMarkers()
smartMap.listInfoWindows()

Beyond that, you're really just asking a standard JavaScript and Google Maps API question. I'd highly recommend searching Stack Overflow (or just a Google search) to get the best results on "how to use fitBounds" or "how to zoom/center" a map.
Hope that helps!


Does Craft have an equivalent of EE's Custom Fields loop for front-end entry forms?

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

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

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


How to disable loops from automatically wrapping non-marked up content?

Pretty sure that's just your browser's console trying to tidy things up when you inspect.

If you View Page Source, I'd guess it wouldn't be there.

I also just tested this with your example code on a fresh Craft 3 install on the latest Chrome and Firefox on Windows and the latest Safari on OSX and was not able to reproduce your picture.


Seems to be the new standard since version 2.2.2582:

"Entry and category search results now place a 5X weight on search term matches within Title fields."


If you create a Lightswitch field and add it to the section's field layout (let's call it unlisted), then you can query for live entries that have unlisted not checked with:

{% set entries = craft.entries.section('sectionHandle').unlisted('not 1').find() %}

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


Removed above code and added the custom validation function for CVV Validation

public function validateCVV($attribute) {
    $value = $this->$attribute;
    if(!preg_match('/^[0-9]{3}$/', $value)) {
        $message = Craft::t("Oops!  Try again with a valid CVV security code on the back of your card.");
        $this->addError($attribute, $message);
    }
}

$rules[] = ['CVC', 'validateCVV'];

Thank You.


Categories do not have authors. They should not be considered "content" like entries in channels or structures, but as a way to relate entries or assets together. If you needed to associate a category with a particular person, you can create a user field and add it to the categories custom fields.


Need .last() functionality for categories – .last() will be deprecated going forward

If you are not going to update your current project to Craft 3 (which will break nearly all your templates and all plugins anyway) you don't need to bother about that message. This is only for Craft 3 and not for Craft 2.

Otherwise looking in the docs might be a good idea. You can do

{% set query = craft.entries().section('news') %}
{% set total = query.count() %}
{% set last = query.nth(total - 1) %}

or

{% set oldest = craft.entries()
    .section('news')
    .inReverse()
    .one()
%}


Using SSL for entire website on Arcustech server

This worked for me on the Arcustech server:

Put this code in the root .htaccess file:

<IfModule mod_rewrite.c>
RewriteEngine On

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

# SSL only
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !^https
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

As RitterKnight mentioned you also need to modify your site's "Site URL" in Settings>General to be https://.


I think the issue with trying to set a variable in a macro is that the variable is limited to the scope of the macro you are triggering, so {% set parent = thisEntry %} is available within the scope of your macro, but doesn't define it for the rest of your template.

  Macros are comparable with functions in regular programming languages. They are useful to put often used HTML idioms into reusable elements to not repeat yourself.

  Macros differs from native PHP functions in a few ways:

  Default argument values are defined by using the default filter in the macro body;
  Arguments of a macro are always optional.
  But as with PHP functions, macros don't have access to the current template variables.

Taken from the Twig docs

So due to the limitations in scope and the nature of macros, they are meant to be used to just output reusable code, not set and define logic in your templates. So everything is just rendered as a string (models have their __toString() method called)

The way you could get this to work for you is to just output whether or not the logic in your macro is true or null, then do the rest of the logic in your template, something like:

{% macro hasParentEntry(thisEntry) %}

 {% import _self as self %}

 {% if thisEntry.parent|length %}

   {# would output 1 #}
   {{ true }}

 {% else %}

   {# or just output null #}
   {{ null }}

 {% endif %}

{% endmacro %}

Then in your template do something like:

{# This will either be true or null #}
{% set parent = self.hasParentEntry( entry ) %}

{% if parent %}

 {# this will set your parent variable to the entry model or leave the variable as null #}
 {% set parent = entry.parent %}

{% endif %}


Try

return [
'endpoints' => [
    'products.json' => [
        'elementType' => 'Commerce_Product',
        'criteria' => [
            // 'category' => 'products', // randomly trying stuff here!
            // 'section' => 'products',
            // 'type' => 'products',
        ],
        'transformer' => function(Commerce_ProductModel $product) {
            return [
                'title' => $product->title,
                'url' => $product->url,
            ];
        },
    ]
]]


First you need to get the correct entry. Based on what you write, you can get it in any template by doing:

{% set contactPageEntry = craft.entries.section('pages').type('contact').first() %}

Then you should be able to loop over your matrix field like this:

{% for block in contactPageEntry.MatrixFieldHandle.type('MatrixBlockHandle') %}
    {{ block.title }} etc...
{% endfor %}


Store a redirect URI for use after login

First – your Twig syntax is a little off. Here's how you could add the current URL/request path to a link, as a query parameter p:

Log in

Notice that the syntax/tag for printing a value/variable is {{ value }}, not {% value %}.

Second, since the redirect in this case should happen when the login form is successfully submitted, it makes sense to add the redirect URL to the form as a redirect input:

<input type="hidden" name="redirect" value="{{ craft.request.getQuery('p')|default('/') }}" />

Note that craft.request should be all lowercase; in Craft almost all variables or service names follow the camelCase naming convention (the craft.request variable refers to the HttpRequestVariable class, which wraps the HttpRequestService).

Additionally, the above example demonstrates use of the default filter, which will print the declared value (in this case, /) if the value preceding the default statement is null or false. In this case, using default will save you an if statements and several lines of code.

Finally, if you want to do a (conditional) redirect outside of a form submission, you can make use of Twig's redirect tag:

{% set redirectUrl = craft.request.getQuery('p') %}
{% if redirectUrl %}
    {% redirect redirectUrl %}
{% endif %}


Commerce 1 with Apple Pay, is it possible?

Quick answer.

Yes you can use Apple Pay with Craft Commerce and the first-party Stripe Gateway Plugin.

In order to do that, you need to customise your template and add the functionality for the Payment Request button. What this does is more or less generating a charge promise token for Stripe (same way it does for card).

Charging the token is then handled by the gateway itself as you would with a card charge.

You can choose to display the button by checking if a relevant Payment API is supported with paymentRequest.canMakePayment() method.

I hope this helps in terms of a high overview.

[EDIT]

The above answer was for use with Craft Commerce 2, as originally set by the question.

Requirement changed to Commerce 1.

The quick answer is still yes.
We have completed a similar task before (with Stripe Elements and Stripe Sources), though that's before SCA.
But Elements are SCA ready as far as I know and you need to use the PaymentIntents API PaymentMethods API.

Difference is that the main Stripe Gateway for commerce 1 (by omnipay) doesn't seem to support webhooks from Stripe, which informs your system whether a token (Source at the time) can be charged or not.

Hence, you need to build kind of your own plugin that loads an extra stripe gateway either new or extending the existing Stripe gateway class (extending is easier as you don't need to rebuild everything).
Might need to add a custom Payment Form to your plugin.

You still need to build a custom template.
The template should use Stripe elements.
Logic is same, chargeable promise token which you need to charge.
Request for charging
Await webhook that notifies your system if your intent can be charged
And then continue with charging if available, otherwise inform user for any errors.

That's still a high overview of how the process works.
You would need to use Payment Intents API and Payment Methods API

[/EDIT]


insertAll() not inserting entries into database

All of the element saving events (like onBeforeElementSave(), onElementSave(), onBeforeSaveEntry()..., etc. are all wrapped in a database transaction (specifically encapsulated in the CDbTransaction class).

When you call exit, you're killing the request and never giving a chance for the transaction to commit to the database.


This will be fixed in Craft 3.4.11, per craftcms/cms#5820.


Remove subdirectories from admin URL with .htaccess

I have Craft public files set up within subdirectories of a primary domain’s web root.
The following .htaccess rules allow for the public_html subdirectory to act as the new web root.

Is there a reason you're doing it this way? The .htaccess you have is only rewriting the content, it's not actually setting the web root. You're basically asking Apache to serve content out of the root for your other domain. There's only a couple circumstances I can think of where you'd need to actually do that (mirroring a domain for example but that's not something you probably want to do here).
For that, you need to set Apache's DocumentRoot properly for your second domain.
It sounds like you have a  CPanel based setup, where it's common for it to put add-on domains inside of the web root of the primary domain by default.  I'm not sure how the document root got changed to the primary domain but you need to set the document root of the add-on domain to the proper place (in Cpanel it's usually the Modify Domain function).
What you type in depends on your path but it's probably set to just public_html now. You want public_html/example.com/public_html/.
That'll get you back to a properly functioning setup.  Then just use Craft's default .htaccess file.


This article might be of use to you: Setting up a New Craft CMS 3 Project

The DEPLOYMENT section talks about using Composer to install our dependencies, and not checking them into Git. That means a .gitignore that excludes vendor/

This isn't really a right or wrong situation, but rather that the advantages slightly outweigh the disadvantages, imo.

If you want to see this all live in action, you can see the devMode.fm website Github repo which is an OSS example Craft CMS website that powers the devMode.fm podcast.


Sounds like you need to move everything up one level...

/opt/bitnami/apache2/cms/ (if you can)
/opt/bitnami/apache2/htdocs/

The web folder can be renamed to htdocs (or anything, really) and it will work normally.

If you can't get above htdocs, you'll want to do it like this...

/opt/bitnami/apache2/htdocs/cms/
/opt/bitnami/apache2/htdocs/index.php
/opt/bitnami/apache2/htdocs/cpresources
/opt/bitnami/apache2/htdocs/.htaccess


How to Update an If Rule Based on Different Parameters Passed to a Macro?

Why don't you pass an array as a parameter?

{% macro mobileNav([
    {url: '/1', title: 'Foo'},
    {url: '/2', title: 'Bar'},
    {url: '/3', title: 'FooBar'},
], {} ) %}

And in your macro..

{% for item in items %}
    {% if item.title is defined and item.title is not empty and item.url is defined and item.title is not empty %}
         // ... output something
         {{ item.title }}
         {{ items|length <= 3? 'less than 4' : 'more than 3 are passed' }}
    {% endif %}
{% endfor %}


How to display the featured image on a Commerce product:

A good approach is always to check if the element even has a related asset or not, otherwhise you'll receive exceptions.

{% set asset = entry.featuredImage.one() %}
{% if asset is not null %}

{% endif %}


The main issue is that the require_once CRAFT_VENDOR_PATH.'/autoload.php'; fails.
This is because the DIR constant, used to compute the value of CRAFT_BASE_PATH and CRAFT_VENDOR_PATH is undefined.
Try to define the value of the DIR constant so that CRAFT_VENDOR_PATH points to the vendor directory in your Craft project (it hard to help you further without knowing your directory structure).
Once this is done, as Jamie mentions, you must use composer to install Craft dependencies.
Did you make any changes to the index.php file of is it just like it was in the archive you received from the other dev?


Correct, categories don’t have the same localization features that entries do, as it is expected that all categories will always live in all locales. And Craft doesn’t actually keep a record of which content has been directly translated, vs. which content was just copied over to a locale when one of the other locales was edited.

If you really want to only show the categories that have been translated, you’d have to add a custom “Translated” Lightswitch field to your category group’s field layout (which would be translatable so each locale gets its own value), and then factor it into any category queries:

craft.categories.group('groupHandle').translated(1)


Cannot declare class because the name is already in use

At this point, after much playing around it seems to be working (at least on to the next bit of debugging).

To sum up, it was mostly changes to composer.json, followed by

composer remove kr37/calendar37
composer require kr37/calendar37

src/Plugin.php became src/Calendar37.php
Added "class": "kr37\\calendar37\\Calendar37" to the "extra" part of composer.json
Corrected the autoload "psr-4" to "kr37\\calendar37\\": "src/"
Made sure that all the names matched up just right.
This error, "because the name is already in use," should really be "because the name doesn't match up."


Organizing repeating content on a single page

You could use a Matrix Field! Each block in your matrix field can be a slide with whatever information you need inside. While your method will work fine, using a matrix will help keep your content organized on a single entry.


Create structured object from query results

Definitely not the most efficient way to do this (it'd be cleaner and more efficient with PHP), but assuming you have  "projects" section that has a "country" Plain Text field and it also had a "state" Plain Text field and you wanted to group projects by country and then state, something like this should work:

{% set countryArr = {} %}

{# grab all projects #}
{% set allEntries = craft.entries.section('projects').limit(null) %}

{# group them by country #}
{% set countries = allEntries|group('country') %}

{# Build the nested array structure #}
{% for country, projects in countries %}
    {# if it's a new country, add it to our structure #}
    {% if countryArr[country] is not defined %}
        {% set countryArr = countryArr|merge({(country):[]}) %}
    {% endif %}

    {# loop through all of the projects in that country #}
    {% for project in projects %}
        {# see if we have a record for the state yet #}
        {% if project.state not in countryArr[country] %}
            {# because twig isn't great with multidimensional arrays #}
            {% set tempArr = countryArr[country] %}
            {% set tempArr = tempArr|merge([project.state]) %}

            {# merge back into our main structure indexed by country #}
            {% set countryArr = countryArr|merge({(country):tempArr})  %}
        {% endif %}
    {% endfor %}
{% endfor %}

{# output our structure #}
{% for country, projects in countryArr %}

{{ country }}

                {% for project in projects %}

{{ project }}

                {% endfor %}

{% endfor %}


Create an Array in Twig and loop through fields in global set

Seems like a great use case for a Twig macro.  Completely untested, but something like this:

{% macro social(object, type) %}

    {% set value = attribute(object, type) %}

    {% if value | length %}

    {% endif %}
{% endmacro %}

{% import "myMacros.html" as myMacros %}

{% set socialArray = ['facebook', 'twitter', 'instagram', 'vimeo', 'youtube'] %}

{% for socialType in socialArray %}
    {{ myMacros.social(socialMedia, socialType) }}
{% endfor %}


No need for a plugin.
Just add:

 "imageResizable": true,
 "imagePosition": true,

to your chosen redactor config file i.e. (/craft/config/redactor/standard.json)


Changing Image transforms for different media queries

This is absolutely possible using plain old HTML, and media queries within a <picture> tag.
Within the tag you set your base image <img> to the url of the smallest size, and a <source> with a media query, like this:
<picture>
  <source
    srcset="{{ image.url('gridLarge')"
    media="(min-width: 1000px)"
  />
  <img
    src="{{ image.url('gridSmall') }}"
    alt="Image of a thing"
  />
</picture>


Best way to use saveCookie and craft.request.getCookie('location')

You should probably be using something like this:

    $cookie = new HttpCookie($name, $value);
    $cookie->expire = time() + 3600;

    craft()->request->getCookies()->add($cookie->name, $cookie);

Setting whatever properties you want on HttpCookie.

Using UserSessionService->saveCookie is meant mainly for Craft's session identity cookie, so it has some security checks it goes through saving the cookie that craft.request.getCookie('location') is probably failing.


Creating a new entry in a specific section

The EntryModel you have has a sectionId property you can set.  i.e.

 $entry = new EntryModel();
 $entry->sectionId = 1;
 $saveIt = craft()->entries->saveEntry($entry);

Note that there are other properties you'll need to set for it to pass validation.  So, if $saveIt is false after calling saveEntry($entry), then call $entry->getErrors() to get an array of validation errors to fix.


nystudio107 has a great plugin that takes care of this and lets you implement redirects when broken links are found.

retour on Github


This will be a bug in a plugin you've got installed on that site that is trying to reference the non-existent (as of a few hours ago) Craft Client edition.

If you look in your craft/storage/logs folder for that error, then you'll be able to see which plugin is causing it in the stack trace leading up to the error.

You'll then need to contact the plugin developer and share the stack trace with them so they can get it fixed for their next release.


Why is ElementsService forgiving of an element type whose populateElementModel() method doesn’t return an actual element model

Someone requested it. They had a use case for it where they couldn’t simply prevent the rows from getting selected in the DB query with a conditional (which is still definitely the recommended way to go). The only reason I decided to add it was for the sake of defensive coding.


"Email" Control Panel Settings page is blank

I was able to resolve the issue by downloading the latest version of Craft CMS and replacing my existing /craft/app directory with that latest version (as outlined in the Manually Updating section of their documentation).

I was previously using the One-click Updating method in the control panel, so I'm not exactly sure of the original cause of the issue.

Thanks to Brad Bell for the help!


Create Model relationship with just an ID rather than full Model?

I think that's actually the way to do it, assign the id to the owning record:

$record = new Cocktails_CocktailRecord;
$record->authorId = 10;
$record->title = "Gin Tonic";
$record->save();

When getting the record from the db, the record is turned into a model, at this point, records and models are only dealing with authorId, not the whole record. Your model will then have to define a getAuthor() method that will get the author user for you:

public function getAuthor()
{
    if ($this->authorId) {
        return craft()->users->getUserById($this->authorId);
    }
}

This way your model only loads the relationship when you actually use it:

$model->getAuthor();


Try changing this:

{% set category = craft.categories.slug(slug) %}

to

{% set category = craft.categories.slug(slug).first() %}


The dynamic object passed to a Notification Event depends on which Event is being triggered. In your case, the "When a user is saved" event has access to the User Model.

All of the attributes you are trying to access are on that User Model and are directly associated with the model itself:

{firstName}
{lastName}
{email}

{{ object.firstName }}
{{ object.LastName }}
{{ object.email }}

In your example, you are trying to access the attribute author. However, author is an attribute from the Entry Model. The Entry Model is available to the "When an entry is saved" event and other Entry-specific events.


Unchecking Rich Text option to clean up HTML still cleaning?

I came upon this issue when wrapping copy with a span tag in order to style it differently. The span tag was removed when I saved the entry.

By design, Redactor removes span tags that don't have attributes. The fix is to edit the Redactor config file and add the removeWithoutAttr config as an empty array.

removeWithoutAttr: []

This prevents tags without attributes from being removed by Redactor.


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

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

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


Varnish is sometimes used to paint over poorly written code.  It's not horrible to get it up and running, but it seems to me that in this case, it might just be easier to fix the poorly written code.

I believe that what cache warmer does is it pings all of the URLs to get the caches to regenerate... but that just triggers the cache rebuilding process, which isn't instantaneous with Craft CMS.  Did you try waiting a little bit?

Does the data in the large structure change that often?  Something else you could consider too is putting the left menu in a its own template that you cache and load via AJAX so that the rest of the page isn't waiting for it.


I'm not sure if this is causing your error, but it's recommended to use setContentFromPost() or getContent()->setAttributes() so that craft has a chance to prep the field values, as discussed in this answer, setContent() vs $entry->getContent()->foo, and What is getContent()?.

$user = craft()->userSession->getUser();
$user->getContent()->setAttributes(array(
    'middleName' => "Dave",
));
craft()->users->saveUser($user);

Although with that error it's possible that something else is going on in your plugin.


Best practice way to store countries and cities

This will depend on what you're actually trying to do, but if you're building this as part of a plugin, I'd store them as relational tables in the database, and display them as dropdown fields. If you provide more specific information about what you're building, I'll see if I can lend a hand.


Front-end form submission feedback on buttons

I'd say your best bet would be to use something like jQuery to make an AJAX call and then manipulate the DOM depending on what response you get. Something like:

$('#loginForm').submit( function (e) {

  // Stop the form actually doing anything or refreshing the page
  e.preventDefault();

  // Get the inputs from the form
  var data = $(this).serialize(),
      button = $(this).find('button');

  // Find our button and change its text or something...
  button.text('Logging you in');

  $.ajax({
    method: 'POST',
    url: '/',
    data: data,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
  })
  .success(function(data) {

    // They are now logged in, reflect that in your button
    button.text('Logged in!');

    // Maybe redirect them aswell?
    window.location.href = "/some/members/area";

  })
  .error(function(data) {

    // Something went wrong, we can now show that
    button.text('Something went wrong');

  });
});

Thats a adapted version of code I found from this question: Front end login form with ajax so I haven't actually tested it, but it sounds like it should work and then changing the button is just straight forward jquery.

If you get errors with CSRF protection, then you should find a solution here: http://buildwithcraft.com/help/csrf-protection#updating-your-javascript

Hope that helps get you started!


Displaying variable in array in array = Impossible to access an attribute ("date") on a string variable ("")

I attempted to get senate directly and output one element of it but no matter what index/key I set it would give me an error. Also, trying to change the object (or whatever it happened to be) in the PHP caused errors as well. I needed up just doing |first and |date to grab the date I needed and format it. The timezone_type and timezone were being converted into dates (December 1969 and current date) for some reason.

{% set batchRowStats = craft.analytics.loadSavedBatch() %}
{% for stat in batchRowStats %}
    {{ stat['senddate']|first|date("F j, Y") }}
{% endfor %}

I did change on thing in the PHP. I added (array) before the object inside of the array it's in. There are more complications to this scenario but I was assigning it to another variable and adding it to a different array. No matter what way I tried to extract the variable it would give me errors. String conversion gave me array error and array conversion usually gave me a string error and several others along the way. After placing (array) in front of it while assigning it to a variable it seemed to behave a bit better.

$emptyDateArray = (array) $innerResults['BatchStartDate'];


Fetch matrix field attributes in controller

Your code looks right. I'd double check for spelling mistakes and check if there's a entry model returned from your $event = $criteria->first(); by outputting its ID with return $event->id.


Sensible way to have different number of entries on page one of pagination?

There's an offset parameter that allows you to skip the first entries from your ElementCriteriaModel.

You would set up two nearly identical ElementCriteriaModels, one exclusivly for your featured entry, using the first() method to only query for the first entry, and to the second one you'd add offset(1) as a parameter, to get all the other entries for your pagination.

{% set params = { section: 'blog' } %}

{# Get the featured entry #}
{% set featuredEntry = craft.entries(params).first() %}

{# Get all the other entries #}
{% set entries = craft.entries(params).offset(1).limit(10) %}

{% paginate entries as entriesOnPage %}

    {# Show featured entry on page one #}
    {% if paginate.currentPage == 1 %}

    {% endif %}

    {% for entry in entriesOnPage %}

    {% endfor %}

{% endpaginate %}


The relatedTo param expects an object, an ID or an array of object or ID (docs), in your case secondSegment is a string and this is the issue. Try:

{% set tag = craft.tags.slug( craft.app.request.getSegment(2) ).one() %}
{% set entries = craft.entries.relatedTo(tag).all() %}


Is there an event that is triggered when an entry expires?

There is no event for this and it would not be possible via event since no one is executing any scripts. Unless there is a request there is no way for PHP to execute code on its own so you need to create a cronjob or a Craft task and execute your functions when someone visits the site.

I would create a cronjob that executes hourly and search for expired entries in order to find them. You can store a value in a field that is not in the layout of the model to mark it as "handled"


From AttributeType::Enum in Model to a matching selectField?

The upcoming Craft 2.2 release added a getConstants() method to the BaseEnum class so you'd be able to do:

EnumClass::getConstants()

to get an array of all of the options in an enum.


Adding new locale - hangs at Step 3 'ResaveAllElements'

You probably need to up Craft's internal memory limit, as well – the following should go into the array in your general.php configuration file:

'phpMaxMemoryLimit' => '1024M',


This sounds possibly a little awkward, depending on what you may mean by 'jumps onto a search results page'.

Some thoughts towards an answer, as you asked:

actually opening a second page is going to remove you from present context, and raise also the question of getting back if the search results aren't used.
you could arrange something happening on typing in the search box by a javascript event on the typing, likely. Probably some issue with transferring what's already typed into such a page, especially with not missing anything being typed while it happens.
a better plan would likely be a Garnish (Craft's ui framework) or other Javascript scrolling modal coming from the original page, no change in url. This might possibly be arranged so that the typing box stays the same, while Algolia results appear in the modal.

Vuejs might be of use in this modal idea, as it handles events and transfer of watched information (the typing) in its framework.


Craft 3.1: value of craft/web/Application::getIsLive() must be of type boolean, null returned

I resolved this by adding 'isSystemLive' => true in general.php


You can query Matrix blocks like you are used to with all other elements

{% set blocks = element.matrixFieldHandle.type('typeHandle').field('some value').all() %}

Keep in mind your field should be a valid field handle within your block type


I'm 99% sure the answer is yes, that's doable, although you'd need a custom plugin to handle the bulk of it. You'd need to write some PHP to handle the unzip, and place the files where you want them.

You may want to create a plugin with a Controller to handle the file upload & unzip.  You can use Craft's Zip::compress() and Zip::unzip() methods to help. Your form will be able to POST directly to that controller.


The only way to do what you're describing out-of-the-box is by adding a user field for Users. Then you can either check that field for child users or get a little creative with relatedTo to get parent users.

If you want to, for example, prevent a child user being linked to several parents or you want the same field to display the parent (if any), you're looking at a custom field type implemented by a plugin.


Redactor: Set a min height and preserve line breaks

The redactor configs are stored inside the config/redactor directory.
Make sure you're editing the right config that your field uses (eg Standard) and add:
  "minHeight":"500px",

... to that file. The configs use JSON so when you see a Redactor configuration, that's how Craft is going to initialize it.
To answer your other question, Redactor is not really designed as a code editor—it's really for end users editing text in a WYSIWYG fashion.
I was able to get Redactor to keep line breaks in tact and keep comments using something like:
  "cleanOnEnter": false,
  "removeComments": false

You might also want to turn off HTML purifier (or modify its own config).
FWIW it's probably much easier to use a dedicated field type for editing code, such as the CodeMirror plugin.


Internal Server Error: SQLSTATE[42000] 1118 Row size too large

You're running into a MySQL/InnoDB server limitation that commonly occurs with a significant number of columns in a single table.

Fortunately, there are several documented workarounds for it:

https://stackoverflow.com/questions/15585602/change-limit-for-mysql-row-size-too-large

https://www.percona.com/blog/2011/04/07/innodb-row-size-limitation/

https://dba.stackexchange.com/questions/6598/innodb-create-table-error-row-size-too-large

From the Craft side, another workaround would be to re-think your information architecture. Currently, most fields in Craft have their content stored in the craft_content table in the database, so when you have a lot of textual fields on the site, you'll see the error you're getting.  The exception to this rule is Matrix fields, which get their own table where their content is stored.

If you can move any of those fields into Matrix fields where they make sense, you'll take them out of the craft_content table helping mitigate the issue.


I believe that you can get the options directly from the 'currentUser' entry, without referring to 'user' separately (they are likely the same thing in this case anyway):

<label for="providerLanguages">What languages do you work with?</label>
{% for option in currentUser.providerLanguages.options %}
    <input type="checkbox" id="providerLanguages" name="fields[providerLanguages][]"
    {% if option.selected %}checked{% endif %} value="{{ option.value }}">
        {{ option.label }}
    </input>
{% endfor %}

The value is also available as 'option.value' instead of 'option.selected'.


Set Password form - use front-end template for admin users

Not without hacking up some core files, unfortunately.

You can see the logic Craft 2 uses to determine which set password template to render for a given request here: https://github.com/craftcms/cms/blob/develop-v2/src/controllers/UsersController.php#L1702-L1720

Basically, if a user has "accessCp" permissions (which admins certainly do), then they're going to get the Control Panel set password template.


I assume you're referring to the auto incrementing primary key values in the tables.  Craft doesn't manage that at all, but relies on MySQL to do so.

See here for discussion on how to do it, just keep in mind that there's a pretty high chance you'll be breaking foreign key constraints on existing data.  And I'm pretty sure you'll need to truncate the table first before running the command you tried.

  I've also noticed that there is no auto_increment setting in the table structures.

Sure it does. Check the primary key of any table and you'll see the auto increment bit.


If you are hosting on an Apache server, check your rewrite rules. The output provided appears to be appending a / to the end of the URL - which would most likely return a 404 error as it thinks the file is actually a directory.

To be more specific, check for any rewrite rules that add a trailing slash to directories (or in general). That is most likely the culprit.

Hope that helps.


How do you display a file asset (PDF) in the template?

What do you mean by 'display the asset'? Showing a thumbnail is not an option, because no thumbs are made for PDF files. If you'd want to show the filename, for example, use the filename property of the asset.

If the page contains multiple entries, you'd have to loop through the entries first. Then, for each entry, check if it has an asset in the desired field (by using | length, after which you can display the asset.

{% for entry in craft.entries.section('bla').relatedTo('bla') %}
    {% if entry.dataCard | length %}
        {% set asset = entry.dataCard.first() %}
        {{ asset.filename }}
    {% endif %}
{% endfor %}


Is there a way to programatically add a user when no one is logged in

Oh well, totally forgot to allow anonymous access at the top of the controller.
I guess I can leave this answer here in case somebody is as forgetful as me:

protected $allowAnonymous = true;


Yes, looks like you'll need to look at the folder yiisoft and subfolders for permissions. Maybe set them to read, write until you're done and then change them to read only.
Just thinking off the top of my head about what the issue could be.


Craft 3 Controller - Redirect with errors

In Yii2 there is no such a thing as "redirectWithErrors". Usually you have 2 scenarios

There are validation errors -> display the form again with those errors
Successful -> redirect

The first one doesn't require a redirect. You just return null in your controller and Yii2 will route the to the url specified via GETparameter.

So you can have a form like this.

<form method="post" action="myUrl">
    <input type="hidden" name="action" value="mycontroller/save">
</form>

Yii2 will do the following

Route to your controller and hit the save action
When you redirect or return a valid object of type yii\web\Response or a string that can be converted into that it will return the Response
When you don't return something it will route the request a second time with your get param myUrl, that can be treated as you routeWithErrors function because you set the errors Craft::$app->getUrlManager()->setRouteParams(['model' => $model]) and have then access to these parameters.

If you really dislike this, you could use return Craft::runAction('controller/action', $parameters); to run a controller action with certain values

Edit
Usually you want to leave action="myUrl" blank and don't insert it. That way Yii2 will automatically reload the current route so you can dispaly your errors


Editing assets custom fields in a full page publish form

Sure, this should be possible from a plugin. But you could also suggest this as a new core feature on the Craft Feedback page. I'd definitly vote for this! ;)


Registering events for a specific feed in Feed Me

it seems parse feed event only provide url and response. i don't know about specifying additional data for feed but some other solutions are:

add feed name as query string to feed url (if it is url and you have have control over it) and parse url on EVENT_AFTER_PARSE_FEED to detect feed name

Event::on(DataTypes::class, DataTypes::EVENT_AFTER_PARSE_FEED, function (FeedDataEvent $event) {
   $url = parse_url($event->url);
   $path = $url['path'];
   $query = $url['query'];
 });

using EVENT_BEFORE_PROCESS_FEED and changing feed data before processing

<?php
use craft\feedme\events\FeedProcessEvent;
use craft\feedme\services\Process;
use yii\base\Event;
Event::on(Process::class, Process::EVENT_BEFORE_PROCESS_FEED, function(FeedProcessEvent $event) {
    if ($event->name == 'feed A') {
      foreach ($event->feedData as $key => $data) {
        $event->feedData[$key]['title'] = 'item' . $key; //changing data attribute of each data
      }
    }
});
?>


How to use assets while building Craft CMS plugins?

You need to register asset bundles in your plugin, see the Craft docs -> https://docs.craftcms.com/v3/extend/asset-bundles.html


Does Craft Have a URL Rewrite Vulnerability?

Both Yii 1 and Yii 2 will check for the X-Rewrite-URL header when determining the requested URI, however no known vulnerabilities exist related to that, because Craft is sure to use the same URI (whatever its source) for both routing and any other URI-related logic throughout the system. So it’s not possible to have Craft base its routing on one URI and template logic off of another URI, for example.


What's the best practice for handling data migration and organization across development environments?

My general approach for this, not just with Craft, but with all CMSes is to have a shared database for development. It's not the most ideal solution, since there can be overwriting of work, but it at least prevents schema changes from having to be redone across multiple environments.

Once a site goes live, maintaining a dev environment alongside live becomes a bit more troublesome. My approach right now is generally to either make the changes in both places, or make the schema changes on live first and then copy the database back down to dev. (This of course requires that the changes not be anything that will break the current live site, and that both dev and live site are running the same version.)

On the upside, Craft does an awesome job of handling the schema changes that come with Craft updates. Basically the database version is checked against the file version, and the database changes can be reapplied on additional environments to update all the databases. This makes updates across environments lot easier than something like ExpressionEngine, which usually requires a multi-step copying of database down from live and back up to live.

In the future I'd love to see ways to encapsulate configurations in a migration similar to the updates, so that it's really just a matter of running the latest migrations to keep everything in sync.


Include Time In PostDate/DateTime Field Control Panel Display

There's a plugin for Craft 2 that did this called BigDates.

As of 7/19/2018, it's been ported to Craft 3 on the v2 branch, but not tested or added to the Plugin Store yet, so there might still be some issues: https://github.com/pixelandtonic/BigDates/tree/v2


How do you find more documentation about queries, services, plugins, etc?

Click on the little triangle! It gives nice examples.


What do the values in /admin/utils/phpinfo mean?

I just made a change on my server (DigitalOcean w/ ServerPilot) which resulted in a double-value... Before my change, there was only a single value.

I can confirm that the top value is overriding the bottom value.

My server default was set to 1000. I used a .user.ini file to override that to 5000.

  ServerPilot: How to Change PHP Settings

  https://serverpilot.io/community/articles/how-to-change-php-settings.html


Getting UTC DateTime from Model attributes

I can't think of a way to automatically tell Craft to do this, but you could write a simple helper method to do this for you:

public static function convertDateTimeToUTC($dateTime)
{
    return $dateTime->setTimezone(new \DateTimeZone('UTC'));
}


Sending a custom email in the users prefered locale

You can translate string in PHP and Twig via translate function

public static function t($message, $variables = array(), $source = null, $language = null, $category = 'craft')

Twig

{{ 'my string'|t() }}

PHP

Craft::t('my string');

So all you need to do is to wrap every string in your templates within the translate filter and pass the preferred local as an argument. For example

{{ 'my latest news'|t([], null, currentUser.locale) }}

If no parameter is set, Craft will use craft()->getLanguage() by default so you can do the following as well

$tmpLocale = craft()->getLanguage();
$user = craft()->userSession->getUser();
craft()->setLanguage($user->locale);
$content = craft()->templates->render(
   '_emails/notification',
   [
       'userInfo' => $this->generateUserInfo($newUser),
   ]
);
$craft->setLanguage($tmpLocale);


I'm doing this at the moment. It's not a perfect solution, but nor is it terrible. In a lot of ways, I'd quite like Craft to just burn Singles and Channels and use nothing but Structures. You can do everything with Structures that you can with the other two, and you get better flexibility and much nicer groupings in the CMS that make more sense to clients (the one confusing bit of Craft clients seem to have is why editing pages is spread out over three areas they don't see any real logic behind). But, that's not how things are. Anyway...

If you're getting "entry does not exist" then you've got something broken in your routing. Every page inside a Structure is an Entry, and if you've got URLs resolving to entries in your Structure then you've got access to the entry variable in your template.

Check your Structure and see what template it's actually loading. The only thing I can think of at the moment with the little detail you've given is that you've got templates in a path that match the Structure, and instead of routing theough the database it's routing theough the files.

i.e., if you've got templates/my-structure/my-entry.twig and also an Entry with a URI of /my-structure/my-entry then you might be skipping the database because your filesystem is matching first.


Listing all entries which belong to an entry

I had a similar problem to yours, and here's what I ran into.

It may be that you're using entry for your main info on the retailer entry page? Because {{ for entry in relatedProducts }} would return one result (the retailer entry). So instead, use a different variable for the loop.

Try something more along the lines of this:

{{ entry.title }}

{{ entry.body }}

{% if craft.entries.section('products').relatedTo(entry)|length %}
  {% set relatedProducts = craft.entries.section('products').relatedTo(entry) %}

Some great entries

  {% for relatedEntry in relatedProducts %}
   {{ relatedEntry.title }}
   {{ relatedEntry.body }}
  {% endfor %}
{% endif %}

Also, note that I wrapped the whole thing in an if-check. It checks to see if there are related products first, and then, if there are, sets the variable and runs the loop.

And your H3 should be outside the loop, otherwise it'll show up on every pass around.


Export Array of entries in modifyEntryTableAttributes

You'll need to use the find method rather than first and last, in order to pull all the entries.

Then, you'll have to loop through the entries, appending their titles to a variable which will be used for the attribute's HTML value in the list view.

Here, I'm pushing the entry titles to an array called $tempArray. After looping, the array is joined and returned as a comma separated list:

public function getEntryTableAttributeHtml(EntryModel $entry, $attribute)
{
    if ($attribute == 'sponsorEntries')
    {
        if ($sponsorEntries = @$entry->$attribute->find())
        {
            $tempArray = [];
            foreach ($sponsorEntries as $sponsorEntry)
            {
                $tempArray[] = $sponsorEntry->title;
            }
            // Will return "Awesome Entry, Another Awesome Entry"
            return implode(', ', $tempArray);
        }
    }
}

If you want to, you can also make the entry titles in the list view clickable – i.e., to make it easy for your content editor to edit those entries – by wrapping the titles in anchor tags and pulling the entries' cpEditUrl property:

if ($sponsorEntries = @$entry->$attribute->find())
{
    $tempArray = [];
    foreach ($sponsorEntries as $sponsorEntry)
    {
        $tempArray[] = 'cpEditUrl . '">' . $sponsorEntry->title . '';
    }
    return implode(', ', $tempArray);
 }

...or if you prefer, you can make the links point to the entries on the frontend, by using $sponsorEntry->url instead:

$tempArray[] = 'url . '" target="_blank">' . $sponsorEntry->title . '';


Update:

As of the next Craft 2.6 release (post 2.6.2945), Craft has exposed an attributes database config setting that you can pass arbitrary PDO attribute key => value pairs into.

So, assuming your MySQL box is setup properly to use SSL and assuming the database user that Craft is using to connect to the box can connect over SSL, then you can do something like this to enable Craft to talk to MySQL over SSL:

'attributes' => array(
     PDO::MYSQL_ATTR_SSL_KEY    => '/path/to/my/client-key.pem',
     PDO::MYSQL_ATTR_SSL_CERT   => '/path/to/my/client-cert.pem',
     PDO::MYSQL_ATTR_SSL_CA     => '/path/to/my/ca-cert.pem',
 ),

Original:

In Craft 2.x, this isn't currently possible.  Craft 3, however, will expose the necessary client side configs so that if your MySQL box has an SSL cert installed and supports SSL, then you can configure Craft to connect via SSL.


Yes that's possible, all Twig loops have a loop variable:

  loop.index - The current iteration of the loop. (1 indexed)
  loop.index0 - The current iteration of the loop. (0 indexed)

Example:

{% for block in entry.myMatrixField %}
  {% if block.type == "quote" %}

{{ block.quote }}

  {% endif %}
{% endfor %}


I got the link to work, but it seems like a dumb workaround. For some reason, http://example.com redirects to https://example.com when I use {{ entry.Url }}, but when I use http://www. the redirect doesn't occur. I changed my Site Url to www. and created a redirect to www. in the .htaccess file.


'Could not find your craft/ folder' error despite following installation instructions

I have a similar set up for one particular installation and have the $craftPath set as follows:

$craftPath = 'craft';

Which works fine.


How to differentiate EVENT_BEFORE_UPDATE_SUBSCRIPTION events in Commerce 2/3

Could you use one of the following events?
\craft\commerce\stripe\services\Invoices::EVENT_BEFORE_SAVE_INVOICE
\craft\commerce\stripe\services\Invoices::EVENT_SAVE_INVOICE

Maybe looking in the invoice model invoiceData attribute (that is passed to the above event).
If that won't suffice, we should expose a way for you to listen to any Stripe Webhook event that comes into commerce, and react.
Please comment on the ticket for that here if so: https://github.com/craftcms/commerce/issues/1799


How do I print the field ID of a category field in place of its title?


Add a /translations/ folder to your project root and within that folder a /fill-in-locale-here/ folder. Add a file "app.php" to that /translations/fill-in-locale-here/ folder which returns an array of those translations. Here's an example => view screenshot


Commerce: notification emails to multiple custom recipients fails

I've run into the same issue and reported it to Craft Commerce support at the beginning of April. It was acknowledged to be a bug:

  "At the moment we are only able to support a single email address in
  the custom 'TO' field."

and improving it was added to their TODO list.

You can use BCC field (with email addresses separated by comma or semicolon) to send notification email to multiple recipients or you can create multiple emails (hooked up to the same template and status) - one for each custom email address.


How do I clear deprecation errors for looping through element queries?

What about using the all() function as well? Your field doesn't contain an array, it contains the same type of object like craft.entries provides.

{% for flag in country.all() %}

It doesn't appear because you have a loop in a loop it appears because you treat and object as an array


When you use the craft.commerce.products tag, it will return a criteria model, but you are treating it as the first result by accessing the title attribute.

Try {{ relatedProduct.first().title }} instead.


Display old entry version content through twig?

Probably something very similar to what Craft does when displaying past entry revisions from a template in the control panel. :)

https://github.com/craftcms/cms/tree/master-v2/src/templates/entries/_revisions.html#L23-L36

{% if section.enableVersioning %}
    {% set versions = craft.entryRevisions.getVersionsByEntryId(entry.id, entry.locale) %}
    {% if versions %}

{{ "Recent Versions"|t }}

            {% for version in versions %}

                    {{ "Version {num}"|t({ num: version.num }) }}
                    {{ version.dateCreated.uiTimestamp() }}, {{ version.creator }}

            {% endfor %}

    {% endif %}
{% endif %}


How do you output images without "?mtime" at the end of the url?

?mtime= should only appear for Assets images that are being served from a source that has Expires settings set (so, either an S3 or Google Cloud source).

This is done done for cache busting purposes. If you upload a new file, it's mtime value will change causing a different URL and, in turn, forcing the user's browser to serve the new image, instead of the cached version.

So to serve images without that you would have to turn off Expires setting for that source.


Put SEO and Twitter card Meta tags in the Head section prior the render of the template

There's a plugin that allows you to connect to an external database, which will allow you to do a query within the template. Remember to cache the result though as it could slow things down otherwise.
Another option is to sync the external data with Craft using feed me, so you can pull the data locally.


AJAX user registration and JSON returned

Instead of listening to the onSaveUser event, I'd update my user save form on the front-end to point to a controller's action in my plugin.

You can run similar logic to what Craft's UsersController->actionSaveUser() is doing and return any custom JSON encoded data you want back to your template.


pass block into embed and forward to another embed?

If partial_with_form.twig isn’t making any of its own customizations to form.twig, then I’d just include the form.twig template using an {% include %} tag, and wrap that whole thing with a {% block %}, so if a template wants to include the partial and make changes to the form, they can just redefine the form themselves.

partial_with_form.twig:

{% block form %}
  {% include 'form' %}
{% endblock %}

Other template:

{% embed `partial_with_form` %}
  {% block form %}
    {% embed 'form' %}
      {% block form_extension %}
        <!-- ... -->
      {% endblock %}
    {% endembed %}
  {% endblock %}
{% endembed %}


Redirect to another EntryType template if no Children exist

Fixed!

So bearing in mind i'm using this method to load templates according to entry type, Clive Portman's answer got me thinking about hasDescendants.  In my _entry.html I now have something like this:

{% if entry.hasDescendants() %}
  {% include "products/_types/secType_categoryGroupOverview.html" %}
{% else %}
  {% include "products/_types/secType_productSpecification.html" %}
{% endif %}

...and it seems to work as required :)

Obviously happy to hear of any more elegant solutions.


Looping through images in a Asset field type

An Asset field – like all relational fields, including Entries, Categories etc – always return an array-like object which is an instance of a class called ElementCriteriaModel. To output the actual file data, this means you have to loop on the field, e.g.:

{% for asset in entry.wireframeImages %}

{% endfor %}

The above is true even if there's 1 Asset selected in the field, or 100.

The cool thing about the for loop in Twig is that it won't throw an error if you attempt to loop on an empty array or object. This means that you don't have to wrap the loop in an {% if %} statement to take care of cases where the Asset field may be empty. Moreover, you can add an {% else %} statement to the for loop, which will be executed if the field is in fact empty:

{% for asset in entry.wireframeImages %}

{% else %}

Nope, no images here :(

{% endfor %}

In situations where your Asset field is limited to 1 file, a loop may seem like overkill – then you can use

{% set asset = entry.wireframeImages.first %}

to get the first (and only) file. Keep in mind though, that if the Asset field is empty, calling first on it will in fact produce an error. To get around this, you can use the default filter to add a default value to the variable and suppress the error. In these cases you have to have a conditional testing the value as well, though – so the amount of code is about the same as just using a for loop:

{% set asset = entry.wireframeImages.first|default(false) %}
{% if asset %}

{% endif %}

Note that first isn't the only method available to ElementCriteriaModel instances, check out the official docs to read more about it.