Craft 3 Feed-Me Auto run all feed I currently use Feed-Me to pull data from an API-Endpoint. This API-Endpoint does change from time to time, providing new elements with each change.

I don't want to manually trigger the Feed-Me-Reimport each time I notice a change.
I do know that Feed-Me provides actions URLs for each feed-entry but as the amount of different import-feeds will grow rapidly soon, I don't think it's feasable to manually create those feeds, and after creation also manually put the URL into a custom cronjob.

So in the end what I'd like to have is simply a script that is triggered by a single cronjob, then gets all Feed-Me feeds and for each feed run the reimport.

Via PluginFactory I already generated a plugin that provides me an endpoint(/controller) to be called by cron

public function actionAutoImport()
    {
        $result = 'Autoimport engaged';

        return $result;
    }

But now I am wondering: How do I get information from the Feed-Me plugin i.e. get all existing feeds and trigger a run on each?

You should be able to use something similar to the following:

use Craft;
use verbb\feedme\FeedMe;
use verbb\feedme\queue\jobs\FeedImport;

$feeds = FeedMe::$plugin->feeds->getFeeds();

foreach ($feeds as $feed) {
    $limit = null;
    $offset = null;
    $processedElementIds = [];

    Craft::$app->getQueue()->delay(0)->push(new FeedImport([
        'feed' => $feed,
        'limit' => $limit,
        'offset' => $offset,
        'processedElementIds' => $processedElementIds,
    ]));
}

The above will add all your feeds to Craft's queue system and start them.


Output tags from matrix fields related to an entry Using the code below, Craft was able to get related tags to an entry, before I decided to move TagFieldType to MatrixFieldType.

{% set entries = craft.entries %}

{% for entry in entries %}

{{ entry.title }}

   {% for tag in craft.tags.relatedTo(entry) %}

     { tag.title }}

 {% else %}

No tags found

 {% endfor %}

 {% endfor %}

I'm quiet struggling to pull tags out so I rather share with you my Field's structure in my CP.

I took many options to consider, Why I can't get it right, even found the post, that same handles may cause a problems, so I gave them all unique handles.

To get tags defined within a matrix field, you will first want to loop through the matrix-blocks in your matrix; and then loop through the tags in your tags field defined in each block.

{% for block in entry.myMatrixFieldHandle %}
    {% for tag in block.myTagsFieldHandle %}
        {{ tag.title }}
    {% else %}
        No Tags found.
    {% endfor %}
{% endfor %}

Also, for retrieving tags defined in a tags field on an entry (as in your example), you can simply retrieve the tags through the tags field directly, rather than using relatedTo(entry).

{% for tag in entry.myTagsFieldHandle %}
    {{ tag.title }}
{% else %}
    No Tags found.
{% endfor %}

For more information please see the documentation for tags and matrix fields.

Update

If you want to output your tags as you have them displayed in your screenshots, then use this:

    {% for block in entry.technologyField %}
        {% if block.type == "tag" %}
            {% for tag in block.technologyTag %}
                {{ tag.title }}
            {% else %}
                No Tags found.
            {% endfor %}
        {% endif %}
    {% endfor %}

However, I can also see some potential problems with your naming system and how you are using matrix blocks. Here are some suggestions for improvement.

You don't need to end each Tag Group handle with 'TagGroup', as you already know that it's a Tag Group (so instead of 'technologyTagGroup', you can simply call it 'technology').
You don't need to end each field handle with 'Field', as you already know that it's a field (so instead of 'technologyField', you can simply call it 'technology').
Matrix block types support more than one field — I suspect that instead of having 3 separate block types defined, you actually only want 1 block type defined (let's call it 'technology' for example), with three fields in it: 'text', 'media', and 'tags' (or 'technologyTags' if you prefer).
When using a Tags Field Type (or Assets, Entries, Categories or anything else with more than one item), it is generally a good practice to name the field handle plural so that you always know that it contains more than one of something (so instead of 'tag' the field should be called 'tags').
If you followed #1, #2, #3, #4 above then the code to output your tags would be:

{% for block in entry.technology %}
    {% for tag in block.tags %}
        {{ tag.title }}
    {% else %}
        No Tags found.
    {% endfor %}
{% endfor %}

If you later define another Block Type then when looping through the blocks you will need to check block.type, and only include those that have a Tags Field defined with the handle your looking for ('tags' in this case). For example:

{% for block in entry.technology %}
    {% if block.type == "technology" %}
        {% for tag in block.tags %}
            {{ tag.title }}
        {% else %}
            No Tags found.
        {% endfor %}
    {% endif %}
{% endfor %}


Why should I update Craft CMS? Haven't updated since version 2.6.2949 - are there any potential negative consequences of not updating? If so, what are they? Thanks.

No software is perfect. Like any other well-managed software project, Craft CMS is regularly updated with new features, improvements and bug fixes.

Occasionally, the changes will relate to a specific security issue that has been discovered in the software.

By not updating, you are missing out on the new features, improvements and bug fixes that make Craft CMS better.

If you don't update when a new security issue is patched, then you are leaving your site at risk of exploitation of the security vulnerability. Depending on the nature of the specific vulnerability, that could mean a threat to your site, your business, the web server that your site is running on or all of them.

Note that this applies to all software, not just Craft CMS.

The Craft CMS changelog is a good resource to see what changes are included in each update.


Upcoming events from specific groups using Venti I'm new to both Craft and Venti so apologies if this is quite basic.

I've got multiple groups setup using Venti and multiple events within these groups.

On the client side I just want to display the 5 upcoming events from a specific group. Anyone know the best way to go about this?

After looking at this for over an hour I've literally figured it out. Just in case others need it:

craft.venti.events.group('handle').limit(5)

So easy!


How can I create an ICS calendar file I want to create an ICS file that people can download to add events to their calendar. I have done this with ExpressionEngine by creating an xml template and just calling it. Below is the code I have so far but I think the problem is that twig doesn't allow php in a template. I'm guessing that means I need to put this in a plugin, but that's beyond my skills. Any help/advice appreciated.

<?php
$ical = "BEGIN:VCALENDAR
X-WR-TIMEZONE:Europe/London
PRODID:-//Orienteering Club//NONSGML v1.0//EN
CALSCALE:GREGORIAN
X-WR-CALNAME:Orienteering Club
VERSION:2.0
{% set events = craft.entries.find({section:'events,activities', eventDate : ">= " ~ now.w3cDate() , order:'eventDate'}) %}
{% if events %}
{% for entry in events %}
BEGIN:VEVENT
UID:{entry_id}
URL;VALUE=URI:{{ entry.url }}
DTSTAMP:{{ entry.eventDate.format('Ymd') }}
DTSTART:{{ entry.eventDate.format('Ymd') }}
DTEND;VALUE=DATE:{{ entry.eventDate.format('Ymd') }}
LOCATION:{{ entry.eventName }}
SUMMARY:Orienteering,nr.{{ entry.map.parts.postal_town }}
END:VEVENT
{% endfor %}
{% endif %}
END:VCALENDAR";

//set correct content-type-header
header('Content-type: text/calendar; charset=utf-8');
header('Content-Disposition: inline; filename=calendar.ics');
echo $ical;
exit;
?>

You don't need a plugin.  Here's some example code from an old project of mine.

{% spaceless %}

    {% set thisPackage = "" %}

    {% set packageId = craft.request.getSegment(2) %}
    {% if packageId %}
        {% set thisPackage = craft.entries.section('packages').id(packageId).find()[0] %}
    {% endif %}
    {% set craftAdminId = craft.users.admin('1').first().id %}

    {# -- Do some sanity checking, make sure they have perms #}

    {% if thisPackage %}
        {% set authorInfo = craft.users.id(thisPackage.authorId)[0] %}
        {% set thisCurrency = thisPackage.currency.value %}
        {% if authorInfo.id != currentUser.id and craftAdminId != currentUser.id %}
            {% redirect siteUrl %}
        {% endif %}
    {% else %}
            {% redirect siteUrl %}
    {% endif %}

    {% header "Content-Type: text/calendar; charset=utf-8" %}
    {% header "Content-Disposition: attachment; filename=cal.ics" %}
{% endspaceless %}
BEGIN:VCALENDAR
VERSION:2.0
METHOD:PUBLISH
X-WR-CALNAME:{{ thisPackage.packageTitle | raw | escape }}
PRODID:-//tastystakes/tourneycal//NONSGML v1.0//EN
{% spaceless %}
{% for block in thisPackage.packageTournaments %}
BEGIN:VEVENT
UID:{{ thisPackage.id }}{{ block.id }}{{ authorInfo.email }}
DTSTART:{{ block.date.getTimestamp() | date_modify("+3 hours") | date("Ymd", "UTC") }}T{{ block.date.getTimestamp() | date_modify("+3 hours") | date("Gi", "UTC") }}00Z
DTEND:{{ block.date.getTimestamp() | date_modify("+3 hours") | date_modify("+" ~ block.days ~ " days") | date("Ymd", "UTC") }}T{{ block.date.getTimestamp() | date_modify("+3 hours") | date_modify("+" ~ block.days ~ " days") |date("Gi", "UTC") }}00Z
SUMMARY:{{ block.tourneyName }}
DESCRIPTION:{{ block.tourneyName }}
END:VEVENT
{% endfor %}
END:VCALENDAR
{% endspaceless %}


Linking to channel page I'm just getting started with Craft. My problem is that I'd like the user to be able to change the location of call to action buttons on the site. Instead of allowing them to enter any URL, it would be bit nicer to let them select the related entry.

I can use the entries type, but it won't allow me to select channels. How should I proceed? Create a single section that displays the channel entries so that I can link to it?

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

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

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


How do I check if an Entry is new? How can I check if an Entry was posted less than a month ago?

{% if entry.postDate > now|date_modify("-1 month") %}
    {# Output #}
{% endif %}


How to serve Craft with Caddy server Caddy seems to be an easy to use alternative to established web servers. How does the Caddyfile look like for a Craft site?

For local development the Caddyfile looks like this (assuming that php-fpm runs on port 9000, you may have to adapt root to point to your web root relative to the location of the Caddyfile):

localhost:2020 {
    root public_html
    fastcgi / 127.0.0.1:9000 php
    rewrite {
        r .*
        to {uri} {uri}/ /index.php?p={uri}&{query} /index.php?{query}
    }
}

Edit: For Caddy >= 0.9.x the rewrite has to be changed to this:

rewrite {
  to {path} {path}/ /index.php?p={path}&{query} /index.php?{query}
}


Set conditional parameter to not output "dateUpdated" field, when entry is first time created I was going through my code for testing purposes and found out, that When entry's first time created, it also outputs data from the field "dateUpdated".
I'm assuming, when an entry is first time created it is also first time updated.

So I'm trying to write a conditional statement to not output "dateUpdated" for entries, that were first time created.

So far I didn't come up with anything, because I'm not sure If what I'm assuming is true.

For the start.

{# Date #}

     {{ "published"|t|ucwords }}: {{ entry.dateCreated is empty ? "" : entry.dateCreated|date("d.m.Y") }},

{% if entry.dateUpdated %}

            {{ "updated"|t|ucwords }}: {{ entry.dateUpdated is empty ? "" : entry.dateUpdated|date("d.m.Y") }},

{% endif %}
{% if entry.expiryDate %}

            {{ "expire"|t|ucwords }}: {{ entry.expiryDate is empty ? "" : entry.expiryDate|date("d.m.Y") }},

{% endif %}

Here's where I'm going to be more help in theory, rather than code. But maybe something like this? I'm happy to revise if someone sees a typo.

{# Date #}

     {{ "published"|t|ucwords }}: {{ entry.dateCreated is empty ? "" : entry.dateCreated|date("d.m.Y") }},

{% if entry.dateCreated != entry.dateUpdated %}

            {{ "updated"|t|ucwords }}: {{ entry.dateUpdated is empty ? "" : entry.dateUpdated|date("d.m.Y") }},

{% endif %}
{% if entry.expiryDate|length %}

            {{ "expire"|t|ucwords }}: {{ entry.expiryDate is empty ? "" : entry.expiryDate|date("d.m.Y") }},

{% endif %}


How can I loop through my entries to export them using Beam? I want to export my entries to CSV or JSON.  Craft 2 had a plugin.  I can't find one for Craft 3.

I reached out to the Craft community on Slack.  They suggested I try the Craft 3 plugin Beam.

I was told it should be trivia. But, the documentation on Beam is light.

This is the example provided in the Beam documentation to export to CSV:

{% spaceless %}
{% set options = {
header: ['Email', 'Name'],
rows: [
      [ 'test@example.com', 'John Doe' ],
      [ 'another+test@example.com', 'Jane Doe' ],
      [ 'third+test@example.com', 'Trond Johansen' ],
]
} %}
{{ craft.beam.csv(options) }}
{% endspaceless %}

I want the header to be the field names used in an entry and the rows to be values for each entry in my posts section.

I can't use a loop in the option settings.  So, how do I set the options to loop through the entries fields and values?

Thanks

This is what I ended up doing... obviously remove anything that is specific to your project. But this essentially will export all fields and entries from a passed in sectionHandle as a URL Param.

{# @var craft \craft\web\twig\variables\CraftVariable #}
{# @var section \craft\models\Section #}
{% requireLogin %}
{% spaceless %}

    {# Set the section from the optional sectionHandle param, defaulting to 'answers' #}
    {% set section = 'answers' %}
    {% set sectionHandle = craft.app.request.getParam('sectionHandle') %}
    {% if sectionHandle | length %}
        {% set section = sectionHandle %}
    {% endif %}

    {# Get all of the fields from the layout for the CSV header #}
    {% set csvHeader = [] %}
    {% set fields = craft.sections.sectionByHandle(section).getEntryTypes()[0].getFieldLayout().getFields() %}
    {% for field in fields %}
        {% set csvHeader = csvHeader | merge([field.name]) %}
    {% endfor %}

    {# Get all of the entry content for the CSV data #}
    {% set csvData = [] %}
    {% set entries = craft.entries.section(section).all() %}
    {% for entry in entries %}
        {% set csvRow = [] %}
        {% for field in fields %}
            {% set csvRow = csvRow | merge([entry[field.handle]]) %}
        {% endfor %}
        {% set csvData = csvData | merge([csvRow]) %}
    {% endfor %}

    {# Output the data as a CSV file #}
    {% set options = {
        header: csvHeader,
        rows: csvData
    } %}
    {{ craft.beam.csv(options) }}
{% endspaceless %}

...enjoy. This is what was used (with a few additions) in the project: Post-Mortem: LinkedIn Talent Intelligence Experience


Install button not visible in Plugin Store I added my user to a user group that had every permission checked. I also looked at general.php and there was nothing about allowUpdates, so I added allowUpdates = true, but neither of these things helped.

I was not the person who installed this site, is there anything else that might cause the plugin store to lack install buttons?

Since the Craft install is hosted at Hyperlane, they have a way of locking changes so that you have to push to the repo through git and deploy. No changes can be made to the filesystem through the admin UI.


How can I 'Parse' { entry.belongsTo } to array with users? From my plugin, I know I can use ...

craft()->templates->renderObjectTemplate($string, $entry)

... to parse, for example, { belongsTo.first.fullName } to the full name of the first user in the belongsTo field.

Now, I need an easy way to parse { belongsTo.find } into an array with all users related to this belongsTo field. Is there an easy way to do this, or should I let my plugin do the work?

Background information

My custom notification plugin has a settings field where I can set the 'receivers' of a notification. If an entry has a user field called 'belongsTo', and the setting is { belongsTo.find }, I need all the users related to this field, so I can further process the notification.

You should be able to use the full Twig tag for what you want to do.  Perhaps something like the following (which assumes you have an email field you are trying to output for each user and want to separate your emails by a comma):

{% for person in object.belongsTo %}{{ person.email }}{% if not loop.last %},{% endif %}{% endfor %}

renderObjectTemplate should parse both the abbreviated syntax with a single curly brace or complete Twig tags.  To take a close look, the abbreviated syntax:

{ belongsTo.first.fullName }

Is being interpreted by Craft as the following:

{{ object.belongsTo.first.fullName }}


Set a dynamic `activateAccountSuccessPath` How to set a dynamic path for activateAccountSuccessPath that contains the username (or any other field from the user profile)?

Completely untested, but something like this should do it.  Create a simple plugin and add this to the main plugin class:

public function init()
{
    craft()->on('users.onBeforeActivateUser', function(Event $event)
    {
        $user = $event->params['user'];

        craft()->config->set('activateAccountSuccessPath', 'members/'.$user->username);
    });
}


How to automatically rename image uploads? How to automatically rename the image files to a random string during the upload process? For example, I have an image named "big_poster.jpg" and I want it to be saved as something random, for example "2680542675157_cc7m541v_l.jpg"

I see every asset have a "Filename" and "Title" field. Would be possible to use these fields to generate a random string? Perhaps using the Randomm plugin?

Use the assets.onBeforeSaveAsset event
You could write a plugin that listens for when an asset is saved via the assets.onBeforeSaveAsset event and rename the image before it is saved to the database?
So you could have something like this in your plugins init method:
craft()->on('assets.onBeforeSaveAsset', function(Event $event) {

    // Only rename if it’s a new asset being saved
    if($event->params[‘isNewAsset’])
    {
        $asset = $event->params[‘asset’];

        $asset->setAttribute(‘filename’, ‘SOME_RANDOM_STRING’);
    }
}

I haven’t tested this code, but from looking at Craft’s source and the docs this should work.
Documentation about events can be found on the Craft website


Live Preview not showing content, Craft 3 I use the same templates for live preview as for the front end. Until a recent change in Craft 3, they worked fine for live preview, then they stopped showing most fields.

I use a lot of includes to build pages, for example, I send the id of an entry to a separate template to display a Matrix field. I just pass entry.id.

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

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


How do I actually add a Digital Product to an order? I'm trying to use the fresh new Digital Products plugin in my website.

I managed to create some products and assigned licenses, I see some  licenses when I log in as an end user - but the last link is missing.

What is the process of getting a specific product object in my "digital product detail page", adding it into the order along with other products, paying and getting the license auto generated?

You would start out by listing the digital products in your templates. For example, if you had digital product type with the handle of onlineCourses, you would get the list of products like this:

{% set products = craft.digitalProducts.products({type: 'onlineCourses'}).order('price desc') %}

Looping through those is just like looping through variants (since digital products don't have variants) or entries. One thing to note, is that currently digital products do no have a salePrice, if you've been using that for Commerce products - just price.

You would add digital products to the cart exactly like you would add a Commerce product and, as soon as an order is completed, any digital products that were in the order will have their licenses automatically generated.

Please note, unlike Craft Commerce standard products where the purchasable is the products' variant, in the case of Digital Products, the purchasable is the product itself.

For example:

<input type="hidden" name="purchasableId" value="{{ product.defaultVariant.purchasableId}}"/>

vs

<input type="hidden" name="purchasableId" value="{{ digitalProduct.purchasableId}}"/>


Dynamic email recipients with amforms I have a situation where I need a form to submit and be sent to my company's email address AND to an email address outputted from an email field from the entry that the form sits on. Is it possible to have a hidden input in the template that contains the email addresses I want the notification to go to?

I've figured this out (the solution is not in the docs). Follow these steps:

1) In the amforms plugin's settings, create a custom text field called 'notificationRecipients'.

2) Add that field to your form's list of fields in the form's settings.

3) Under the notifications tab of your form, add this to your "Email Recipients" field:

defaultAddress@domain.com,{notificationRecipients}

4) Now in your template, add a hidden input in the <form> like so:

<input type="hidden" name="fields[notificationRecipients]" value="{{ entry.yourCustomFieldEmailAddress }}">

Keep in mind that multiple emails should be separated by commas like example1@gmail.com,example2@gmail.com,example3@gmail.com

That's it!

If you don't want the list of email recipients to appear in your notification email, then you need to edit line 24 of craft/plugins/amforms/templates/_display/templates/email.twig to look like this:

{% for field in fields if field.getField().handle != 'notificationRecipients' -%}

Additional examples and info can be found on these closed issues of the developer's git page:

#72
#86
#99


How can I have a dynamic/virtual attribute AND have as an attribute of the Model? Take the example of a model with a firstName and lastName.

I know I can add a getFullName method to the model, and $model->fullName will run through the getter.

However, I'd like the attribute to also remain part of the model (accessible through $model->attributes), which if I use the getter, it isn't.

If I use the getter AND include the same name in defineAttributes, the getter is ignored.

Is there a way to achieve this?

I think you're out of luck.  You can't go through the magic __get() logic and have a concrete get method and use both.  How will Yii/PHP know which one you're referring to when you do $model->fullName?


Simple way to create a slideshow with Twig and a for loop? I have this code, which is basically a loop in a Twig template where I show opinions:

        Opiniones de otros guardianes

        {% for opinion in opiniones %}

                {{ opinion.opinion }}

                {{ opinion.autor }}

                {{ opinion.ciudad }}

        {% endfor %}

I'd like to create a simple slideshow to show these 3 opinions. I've tried with diferent methods but they don't work. Does someone know a simple, easy way to do it? Thanks.

This isn't really a Craft question. Craft is simply responsible for outputting the requested data into your template, and you can use whatever you'd like on the front end to display it.
What you want in this case is a JavaScript carousel or slider. You can build your own, or use a simple library. I like Flickity and use it often, but if you just do a Google search for "javascript carousel" you'll find tons of options to choose from. If you're using a specific library or framework for your site, you might want to include that like "javascript carousel bootstrap" or "javascript carousel react" to find something that leverages libraries you're already loading.


Categories on a Front-end form I have searched the forum and cannot find the answer to my question.
I know how to populate a dropdown with the categories that are already in the system, but what happens if the category that needs to be assigned to the entry doesn't exist in the list of categories.

So, my question is this. Is there a way to display the dropdown of categories, as well as having the ability to add more categories via a form on the front-end?

Thanks

This isn't possible with the build in FEEF functionality.

You can however achieve this via a Plugin. What you need to do is to listen to the onBeforeSave event and make an if-statement to check if the entry is being added to your section. Then you can run a loop that checks all the submitted categories against your database and adds new entries for the categories that doesn't exist and re-populates your EntryModel with the new category ID's before insertion.


Craft entries not saving We have received the Craft CMS and design files from our web developer with content already loaded into the Craft backend.

All of the frontend displays correctly but we are able to edit all the textual content in the 'Globals' sections and save it but when we edit any text/fields in the 'Entries' section and save the changes, the page reloads with the old content which hasn't been updated with the changes.

Does anyone know a fix for this?

Based on our comment thread, I would suggest to perform a manual update of Craft.

Download and unzip the latest copy of Craft, and replace the old app folder with the app folder that you just unzipped. No other files or folders need to be replaced.

Make sure to change the permissions of your new app folder, so you can perform auto-updates in the future.


Twig_Error_Runtime on Local Dev Environment Trying to set up craft on local environment and getting the following error once running mysql. Any clue what usually causes twig_error_runtime?

Twig_Error_Runtime

Method "bust" for object "Craft\CraftVariable" does not exist in "_layout" at line 66 (/Users/username/Sites/site.com/craft/app/vendor/twig/twig/lib/Twig/Template.php:485)

#0 /Users/username/Sites/site.com/craft/app/etc/templating/BaseTemplate.php(41): Twig_Template->getAttribute(Object(Craft\CraftVariable), 'bust', Array, 'any', false, false)
#1 /Users/username/Sites/site.com/craft/storage/runtime/compiled_templates/f7/b1/be6fe94a8e6c7ce48ecb00086d0a2ebde7cc24cc43eec4a6ba82fa4a24c9.php(128): Craft\BaseTemplate->getAttribute(Object(Craft\CraftVariable), 'bust', Array)
#2 /Users/username/Sites/site.com/craft/app/vendor/twig/twig/lib/Twig/Template.php(313): __TwigTemplate_f7b1be6fe94a8e6c7ce48ecb00086d0a2ebde7cc24cc43eec4a6ba82fa4a24c9->doDisplay(Array, Array)
#3 /Users/username/Sites/site.com/craft/app/vendor/twig/twig/lib/Twig/Template.php(287): Twig_Template->displayWithErrorHandling(Array, Array)
#4 /Users/username/Sites/site.com/craft/storage/runtime/compiled_templates/44/d5/7fc586931d2e13dfcd02f8209765153f695b63c7cf7dd78afa05d76029c4.php(27): Twig_Template->display(Array, Array)
#5 /Users/username/Sites/site.com/craft/app/vendor/twig/twig/lib/Twig/Template.php(313): __TwigTemplate_44d57fc586931d2e13dfcd02f8209765153f695b63c7cf7dd78afa05d76029c4->doDisplay(Array, Array)
#6 /Users/username/Sites/site.com/craft/app/vendor/twig/twig/lib/Twig/Template.php(287): Twig_Template->displayWithErrorHandling(Array, Array)
#7 /Users/username/Sites/site.com/craft/app/vendor/twig/twig/lib/Twig/Template.php(298): Twig_Template->display(Array)
#8 /Users/username/Sites/site.com/craft/app/vendor/twig/twig/lib/Twig/Environment.php(293): Twig_Template->render(Array)
#9 /Users/username/Sites/site.com/craft/app/services/TemplatesService.php(223): Twig_Environment->render('404', Array)
#10 /Users/username/Sites/site.com/craft/app/controllers/BaseController.php(74): Craft\TemplatesService->render('404', Array)
#11 /Users/username/Sites/site.com/craft/app/controllers/TemplatesController.php(201): Craft\BaseController->renderTemplate('404', Array)
#12 /Users/username/Sites/site.com/craft/app/framework/web/actions/CInlineAction.php(49): Craft\TemplatesController->actionRenderError()
#13 /Users/username/Sites/site.com/craft/app/framework/web/CController.php(308): CInlineAction->runWithParams(Array)
#14 /Users/username/Sites/site.com/craft/app/framework/web/CController.php(286): CController->runAction(Object(CInlineAction))
#15 /Users/username/Sites/site.com/craft/app/framework/web/CController.php(265): CController->runActionWithFilters(Object(CInlineAction), Array)
#16 /Users/username/Sites/site.com/craft/app/framework/web/CWebApplication.php(282): CController->run('renderError')
#17 /Users/username/Sites/site.com/craft/app/framework/base/CErrorHandler.php(368): CWebApplication->runController('templates/rende...')
#18 /Users/username/Sites/site.com/craft/app/framework/base/CErrorHandler.php(351): CErrorHandler->renderError()
#19 /Users/username/Sites/site.com/craft/app/framework/base/CErrorHandler.php(218): CErrorHandler->renderException()
#20 /Users/username/Sites/site.com/craft/app/etc/errors/ErrorHandler.php(128): CErrorHandler->handleException(Object(Craft\HttpException))
#21 /Users/username/Sites/site.com/craft/app/framework/base/CErrorHandler.php(131): Craft\ErrorHandler->handleException(Object(Craft\HttpException))
#22 /Users/username/Sites/site.com/craft/app/framework/base/CApplication.php(740): CErrorHandler->handle(Object(CExceptionEvent))
#23 [internal function]: CApplication->handleException(Object(Craft\HttpException))
#24 {main}

Was simply root password in DB changing since last loading up environment. Threw some more errors to finally see database connection issues and just had to update db.php to fix. Leaving this here in case anyone else has issues.


Add items to user's cart in Craft Commerce 2 I'm trying to add items to user's cart from a plugin but I'm stuck on getting cart of a user other then current user.
I have the code for adding items to cart, it's something I used on current user. But I don't know how to get the cart for any user.
<?php
$cart = iHaveNoIdeaHowToGetUsersCart($user->id); // <---
// I used this for current user:
// $cart = craft\commerce\Plugin::getInstance()->getCarts()->getCart();
if ($cart->id == null) {
    // Create cart if it does not exist
    Craft::$app->getElements()->saveElement($cart);
}

$purchasableId = Craft::$app->getGlobals()->getSetByHandle('booking')->breakProduct->one()->id;
$options = [
    'amount' => (float)$something,
    'description' => 'Something'
];
$newLineItem = Plugin::getInstance()->getLineItems()->createLineItem($cart->id, $purchasableId, $options, 1);
$cart->setLineItems([$newLineItem]);
Craft::$app->getElements()->saveElement($cart);
?>

In Commerce, a User (or guest with an email address for that matter) can have multiple carts (or unfinished orders).
So we need to get the most recently active one. Something like this should work:
$query = Order::find();
$query->id($whateverId); // you could also use $query->email
$query->isCompleted(false);
$query->orderBy('dateCreated DESC');
$cart =  $query->one();

... // rest of your code


How to show multiple calendars I am using Michael Rog's Calendar add-on with these params:

{% switch craft.request.getSegment(2) %}
    {% case '' %}
        {% set thisCalendar  = '2,3' %}
        {% set calendarTitle = 'Full Calendar' %}
    {% case 'mts' %}
        {% set thisCalendar  = '2' %}
        {% set calendarTitle = 'MTS Calendar' %}
    {% case 'day-school' %}
        {% set thisCalendar  = '3' %}
        {% set calendarTitle = 'Day School Calendar' %}
{% endswitch %}

{% set calendarParams = {
    dateRangeStart: 'today',
    dateRangeEnd: '+36 months',
    calendarId: thisCalendar
    } %}

The individual calendars are working and showing the correct entries but without a segment 2 I am only getting the events from Calendar ID 2 but not from ID 3.

If I do this:

    {% case '' %}
        {% set thisCalendar  = '3,2' %}

I get events from Calendar ID 3 but not from ID 2.

How do I get events from all calendars? Is comma separated the correct syntax? Should this be working?

Posting comment as answer, since the suggested solution solved it:

Pass the IDs as an array instead of comma separated: {% set thisCalendar = [3,2] %}


Adding Google Analytics to an RSS feed via server-side tracking? Google Analytics provides a server-side API for sending data to their servers; this is the generally approved way of tracking views of a page that can't include Javascript, such as an RSS feed. You just send a specially formatted http request to Google's servers when the page is requested.

Has anyone got a plugin or other solution for sending either (a) GA requests specifically or (b) just HTTP requests in general from a Craft template? If so, then I can set that template not to cache, and get at least some rough idea of how many views I've got on the feed. (And if not, I'll break down and write my own plugin, but I'm hoping not to have to.)

I don't know of any off-the-shelf plugins that do it, but it seems like it'd be simple enough to set up, based on existing code.

Craft includes Guzzle which will make calling GA (or any web service) pretty easy. Trevor Davis' craft-guzzle has some code you could use as a starting point.  Just perusing the GA docs, you'll need to do use POST instead of GET but some of plumbing is already done.


Sort entries per category I have a collection of entries in a structure, and each entry can be in multiple categories.

Is it possible to sort the entries seperately for each category?

So it would look something like this:

Category 1: entry 1, entry 2, entry 3
Category 2: entry 3, entry 2, entry 4

There seems to be lots of very similar questions here already, but none that are exactly like this, and I can't figure out how to do it. Can someone please help?

I might be wrong, but your question sounds like you currently don’t even have something set up in the CMS that determines the order the entries should be listed under each category, and the reason for this probably is that you are using a Categories field assigned to the entries’ field layout.

What I am suggesting is to reverse that setup. An Entries field on your category’s field layout not only allows to select which entries you want to relate to each category, but also in which order they should be listed.

Before implementing this you better check if this reversed setup does also make sense for the data entry, but the fact that you’re interested in the sort order is an indication that this might be the case.


Redactor table plugin for craft Okay so my question is simple. Is there a craft plugin that lets me add tables in my redactor fields? If not then is there a way I can add the table.js to the redactor plugin config. I add ti but it doesn't show up.

Craft ships with Redactor’s Table plugin, but you must add it to your Redactor config yourself (in craft/config/redactor/).

{
    // ...
    plugins: ['table']
}

To determine which config file to place this in, go to your field’s settings in Settings → Fields → [your Rich Text field name], and check your “Redactor Config” setting.


Include tax in price on product page Is it possible to include any tax values in the price on the products page (not just the cart)?

I believe the only way to do this at present is to select the Include in Price option on the Tax Rate in Commerce settings.


Method for pulling entries that have a specific image linked? Let's say that I have an Assets field on a single page where someone can add a bunch of images to a "gallery" on that page. Is there a way to perform a query and return the entries from a channel where these images are used as well?

Ideally, I'm trying to get the URL's to all of the listing entries where any of these images are also used, but without the admin explicitly relating them to those entries on the single page. There's no explicit relationship between them, other than the same images were used on both the single and channel entry.

You can use relatedTo for that:

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

Or

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

Check out the documentation on relationships.


Restrict asset image filetypes Is it possible to further restrict asset filetypes than just "image"?

For example only allow .jpg, .jpeg and .png ?

It depends. If the only files you want to upload are .jpg, .jpeg, and .png, then yes: set allowedFileExtensions in your config/general.php

'allowedFileExtensions' => 'jpg, jpeg, png',

If you want those to be the only image filetypes, but  to allow other files for non-image assets, then that is harder (and I don't know how to do it).


Craft Commerce: Hard code different product prices based on currency? We are considering using Commerce for a site where the company sets hard coded prices for the various regions and countries they sell in. I know Commerce has multi-currency support but pricing is in a primary currency and then you set conversion rates. However our client just sets prices - there's not a consistent conversion rate. So, for example, a US product would be $700, it would be $950 in Canada and 14000 pesos in Mexico.

Is there a way to achieve this with Commerce in a fashion where the client can update these prices in the admin? It's an important requirement for them and we're considering other platforms but thought someone might have some insight specific to Commerce because we do like Craft for other reasons. Thanks!

--- UPDATE ---

Trying this as per the accepted answer and the lineItem price on the Cart page doesn't seem to reflect what gets set in the plugin. My code...

class NewPricingPlugin extends BasePlugin
{
    function init(){
        craft()->on('commerce_cart.onBeforeAddToCart', function($event){
           $line = $event->params['lineItem'];

           NewPricingPlugin::log($line['price']); # = $9.00

           // this sets the lineitem price, but when the cart page
           // loads the price hasn't changed.
           $line['price'] = 1000;

           NewPricingPlugin::log($line['price']); # = $1000.00
        });
    }

    // other plugin methods...
}

Is there a lineItem or cart update method that needs to be called?

You can add custom fields to store the 'other' price for your products (and/or variants), like, as you say, a matrix, or probably even a table would do.  The fields can then be edited by admins in the back end.

In your templates, you'd selectively display whichever price the particular market needs - this would just be basic template logic.

Then, you'll also need a simple custom plugin that listens to onPopulateLineItem and checks which market the customer is in, and modifies the lineItem price accordingly (by retrieving the correct price form the appropriate field).  Once the lineItem prices are modified as appropriate, they'll be used for the payments and stored with the order, factored into totals etc.

There is an example of modifying a lineItem in the docs here:
https://craftcommerce.com/docs/events-reference#commerce_lineitems.onpopulatelineitem

Unless you have other requirements not mentioned, for someone with Commerce experience, that would be really be quite simple to implement.

(Based on ~ a years work with Commerce and related plugin writing).


Omnipay Mollie implementation I'm working on a webshop that should have an integration with Mollie to provide the payment methods. Craft Commerce's docs mention that Mollie is already integrated by using the Omnipay interface.

Am I correct that Omnipay only provides a basic interface to communicate with various Payment Gateways (including Mollie) and does not include more concrete functionality, like getting the payment methods/issuing banks?

Basically, the code like below I still have to write myself? Or am I doing double work?

public function actionGetPaymentMethods()
{
    $this->requireAjaxRequest();

    $paymentResponse = $this->gateway->fetchPaymentMethods()->send();

    if ($paymentResponse->isSuccessful()) {
        $paymentMethods = array();
        foreach ($paymentResponse->getPaymentMethods() as $paymentMethod) {
            $paymentMethods[] = array(
                'id' => $paymentMethod->getId(),
                'name' => $paymentMethod->getName(),
            );
        }

        $this->returnJson($paymentMethods);
    }

    $this->returnErrorJson('error');
}

Nevermind, I did not understand that Mollie is an off-site implementation. So the checkout just redirects you to the Mollie environment. If you want to implement on-site payments using Mollie you'd have to write your own logic I presume.


Is it possible to restrict access to a page based on a visitor's country? Is it possible to restrict access to a page based on a visitor's country?

For instance, only users in the US can view the FAQ page?

Thanks!

Luke Holder has created a plugin that would help you in this situation.

Geo Plugin for Craft CMS


Resolving “Stuck” Background Tasks Hi guys so I am having an issue with the "generating pending image transforms" being stuck.

I've seen the solution listed here https://craftcms.com/support/stuck-tasks telling me to go to the craft_tasks table and fix the error. But I cannot for the life of me figure out how to get to this table. Where is it? No one seems to explain this.

The easiest way is to use a GUI MySQL client to connect to the Craft database and edit the table directly.  Popular ones include Navicat and Sequel Pro, but there is a good list here of options for both OSX and Windows.

Once you connect to the database, you can edit the data in the craft_tasks table and change the value of status from running to pending to re-trigger it.


What are the best practices for the development setup? I've started with Craft developing all locally. The struggle for me when working locally was synchronizing the database and the backend assets with coworkers on the same project.

In the last project we tried a different approach, where we have the db, the assets and the CP on a server. So all devs involved in the project had the same backend.

What we still had locally were our templates and frontend stuff. The db.php pointed to the remote db. The basepath pointed to our local root so it would load the local templates.

I'm actually pretty happy with that solution the only problem I haven't figured out yet is using image transforms. Since I'm using locale templates (and a locale craft installation for templating ), the transforms tries to generate the images locally which doesn't seem to work. Maybe my configuration is off since I don't have to much experience with transforms and the configuration with this setup can get a little confusing as well :)

How does your setup look while working in a team?

And any suggestions for the my problem with transform?

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

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

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


Charge 2 form that has multiple one of plan amounts? I have been trying to set up a Charge 2 payment form and have it all working except for giving the user 3 different plan amounts at the end of the form.

For example, I need to offer the following in a select box or radio buttons at the bottom:

Plan A at $10.00
Plan B at $20.00
Plan C at $30.00

This is relatively simple using subscription modal, but I only want it to be a one off payment rather than daily, weekly, monthly or yearly.  Is this possible?

check out the docs here - http://squarebit.co.uk/software/craft/charge/usage/reference/payment-options and note this bit:

  planIntervalCount accepts int The number of periods for a recurring
  plan. If you're creating recurring charge, this is required, and must
  be 1 or higher. Not including, or passing a 0 value will create a
  one-time charge.

So, you could do

<input type="hidden" name="planIntervalCount" id="planIntervalCount" value="0"/>

for a one off payment.


How to integrate Craft Commerce with Salesforce? We're looking for a way to integrate Craft Commerce with Salesforce. What are the options there?

Is there a Craft API to talk to? (I can't seem to be able to find it...)

And the other option is to write a plugin in Craft that communicates outwards to Salesforce, I suppose?

Is there a Craft API to talk to?

Yes, but it depends on what sort of API you're talking about and you'll need a Craft plugin no matter what.

At the PHP level, Craft has a service layer API that plugins can utilize.

If you're looking for a web service API where you can configure what gets exposed so that 3rd party apps can consume Craft data, there is the Element API plugin that works with any Craft elements (including plugin elements, like Orders, Products and Variants like in Commerce).  Note that this is read-only and is not a REST API.

There currently isn't a native REST API in Craft, but feel free to add your comments to this feature request.  It's also possible for a plugin to implement its own REST API using its own controller endpoints and authentication/authorization methods.

As far as consuming 3rd party web endpoints, Craft ships with Guzzle that a plugin can utilize, or it can use any other library it desires (or straight up cURL).


Form validation plugin result in 404 I'm new to craft development, and I'm on the verge of success in the creation of my plugin, but I have a strange problem.

It's supposed to save a record based on user input data. The problem is that it works on my computer, but not on my mobile phone (-> result in 404).

Here is the form

<form class="ui form" method="POST">

        Activité
             <select name="activity" class="ui fluid dropdown">
                 <option value="3">Third</option>
                 <option value="2">Second</option>
                 <option value="1">First</option>
             </select>

             Nom et prénom
             <input name="nom" type="text">

         <input type="hidden" name="action" value="eventEquipe/event/addParticipant">
         <button class="positive ui fluid button" type="submit">Je viens !</button>
</form>

Here is my controller's code
public function actionAddParticipant() {

$this->requirePostRequest();

    $participant        = new EventEquipe_ParticipantRecord();
    $request            = craft()->request;

    $participant->nom       = $request->getPost('nom');
    $participant->activity  = $request->getPost('activity');

    craft()->eventEquipe_event->saveParticipant($participant);
    $this->redirect('/agenda');
}

The problem is that sometimes, this redirects me to /login (I dont know why, I have no /login route) and thus result in a 404.

Thanks for your help !

Sounds like you need to allow anonymous access to your controller action.

I guess it works on your computer because you are logged in and thus have a valid session, but then when you try on mobile, you haven't got a valid session, your controller isn't set up to allow logged out users to post to it and therefore you get redirected to /login

To allow non logged in users access to this action, its simple. Add either one of these just at the top within your controller class.

// Will allow anonymous access to all actions within this controller
protected $allowAnonymous = true;

// Only allow access to specific actions
protected $allowAnonymous = array('action addParticipant');


postCpLoginRedirect wrong redirect when used with autoLoginAfterAccountActivation See below updates and accepted answer for a full solution

I finally discovered postCpLoginRedirect which solves my needs, even though I only need users to access their profile (which includes lots of custom fields, hopefully we'll have a few more permissions options in future for the cp).

Anyway, the issue I'm having is I want to redirect to a front-end dashboard which is at {{siteUrl}}counsellors/dashboard. This page has a {% requireLogin %} tag which redirects to the cpTrigger. And, as cp is enabled for default user groups, I understand activateAccountSuccessPath, postLoginRedirect are defunct settings.

When logging in from the Craft cpTrigger the relative link string /counsellors/dashboard works fine.
But when used in combination with the autoLoginAfterAccountActivation it directs to the wrong path (relative to the admin trigger login/counsellors/dashboard)

Ideally I'd like to keep it separate as eventually the CP will be swapped out for a front-end solution, so any clues as to why this is happening? Or what combination of settings are required to fix it?

settings:

'cpTrigger' => 'login',
'postCpLoginRedirect' => '/counsellors/dashboard',
'activateAccountSuccessPath' => '/counsellors/dashboard',
'autoLoginAfterAccountActivation' => true,
'loginPath' => 'login' # Redirect to cp trigger
// 'postLoginRedirect' => 'counsellors/dashboard',

Updates 28/01/2016:

If you're giving users access to Control Panel activateAccountSuccessPath won't work, regardless of the path — a plugin is required to make this happen.

So it seems for now at least, everything has to be built front-end as @RitterKnight suggests

A big caveat is, no matter what, if a new registered user has access to the CP, activateAccountSuccessPath is ignored. You'll need a plugin to have newly activated accounts forwarded to your success page.
Another nice addition is to use the brilliant Control Panel Nav plugin (which really I think should be built into Craft)

If you're having users login directly from CP login, you can couple this with postCpLoginRedirect if you want to hide the dashboard from users.

So to recap, full settings are now:

Front end registration, front-end success page, front-end login form, front-end dashboard;
A plugin to enforce activateAccountSuccessPath settings
Control Panel Nav plugin with a link to the custom dashboard;
The following config settings:

'loginPath' => 'counsellors/login',
'activateAccountSuccessPath' => 'counsellors/success',
// 'autoLoginAfterAccountActivation' => true, # Doesn't work
// 'postCpLoginRedirect' => 'myaccount#profile', # Optional
'postLoginRedirect' => 'counsellors/dashboard',

Ideally I'd like to keep it separate as eventually the CP will be swapped out for a front-end solution, so any clues as to why this is happening?

I think you're close.  Just so we're on the same plane, you're using the CP for users to edit their profiles but everything else is on the front end? Do you have a front end login form already setup? If not, get one setup at counsellors/login.

Don't set your cpTrigger and loginPath to the same values if you intend to keep the front and back end logins separate to begin with. That's issue number 1.

On the front end, you probably want to set loginPath to something like counsellors/login and you'll want to obviously uncomment your postLoginRedirect to counsellors/dashboard so after they login, they'll get shuttled off to that page.

Set  activateAccountSuccessPath to something like something like members/activation-success and then in that template,  you can do whatever you want there, either link back to the CP with a hyperlink so users can "finish" their profiles or use Craft's {% redirect %} code to send them to the CP.


Pass field handle from to render tag using Freeform field I'm new to Craft and I'm trying to figure out how to place a form within an entry using a Solspace Freeform field.  Specifically I need to pass the form handle into the render tag to place that form on a particular page.

{{ craft.freeform.form("formHandlefromfreeformfield").render() }}

Thanks!

Is this what you are looking for?

{{ entry.myFreeformfieldname.render() }}


Switch to graphical buttons in Redactor 2 I am trying to replace the text-based buttons in Redactor 2 with graphical ones as per this article on the imperavi website:
https://imperavi.com/redactor/examples/buttons-default-icons/

I created a simple plugin loading a JS file (a copy and paste of the JS on the page above) and a CSS file (fontawesome.min.css). These two files and the fonts are in the resources/ folder of the plugin. Example of plugin file in this post:
Can a plugin add JS or CSS to the control panel?

Everything seems to work fine: CSS file loaded in the head and JS file loaded right before the  tag.

My problem is that the JS loaded by my plugin comes before the main JS redactor file. Console barfs an error at me for trying to work with $.Redactor.prototype, which obviously does not exists yet.

Is there an easy way for my plugin to load the JS file at the end of the JS queue or at least after the main redactor JS file ?

EDIT 1:

Following Carl's advises below, I managed to get it working.

Basically, the approach is to create a RedactorPlugins object and populate it with what you need so it is available for redactor when it runs afterwards. The plugin you create that way can be used in your redactor config files.

Something like

if (!RedactorPlugins) var RedactorPlugins = {};

RedactorPlugins.iconbuttons = function()
{
  return {
      init: function ()
      {
          var icons = {
              'format': '',
              'lists': '',
              'horizontalrule': '',
              'image': '',
              'link': ''
          };

          $.each(this.button.all(), $.proxy(function(i,s)
          {
              var key = $(s).attr('rel');

              if (typeof icons[key] !== 'undefined')
              {
                  var icon = icons[key];
                  var button = this.button.get(key);
                  alert(key + " - " + button + " - " + icon);
                  this.button.setIcon(button, icon);
              }

          }, this));
      }
  };
};

Once you have created a plugin loading this JS file and the CSS you need, you can tell Redactor to use that plugin in your redactor config files:

"plugins": [ "iconbuttons", "source" ]

EDIT 2:

I will probably abandon this altogether and roll with the default text-based version of redactor 2. It looks like this approach does not work with some buttons where Craft has to do some work. It seems that when the replaceRedactorButton function in craft/app/resources/js/RichTextInput.js is run, it removes buttons customisation.

You could use my plugin Redactor Icon Buttons.

It includes the icons from the (old) Redactor 10 editor and you can map icons to buttons via a iconMapping config setting. It also allows to use a custom icon set.

If you still want to write your own plugin, have a look at the source code of P&T’s Redactor Clips plugin.


Getting image for product in Cart Screen Really struggling with this (perhaps my brain is tired), but how would I get the image of a product for each entry in the cart screen in Craft Commerce?

This actually depends where the image is stored - if the asset (image) field is on the product, and is called myImage, then as per Brad's example you'd use:

lineitem.purchasable.product.myImage

...BUT if it's in rather a field on the variant you would instead reference it as:

lineitem.purchasable.myImage

(This is because lineitem refers to a variant....in the case of a product without variants it references the implicitly created defaultVariant).


Change the location of the user photos Is it possible to change the default location users upload their profile photos to? Right now they are stored in /admin/resources/userphotos/ which for me is not preferable for some reasons. I’d rather have them somewhere in html/img/member or similar.

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

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


How to browse uploaded assets on the front end? I have a frontend entry form which included a file field to upload files to the entry. All works fine. I even have a delete function to remove individual uploaded files from the entry.

The problem is if a user wants to attach a file they have already uploaded. Uploading the file results in the same file uploaded but with a different filename (a timestamp added to the end).

This is going to result in unused files being left on the server and a nightmare version control going on - people left wondering what version is correct, which is being used, is it safe to delete the old ones etc.

So ideally what is needed is the user can browse the assets uploaded on the front end and ideally be able to upload within that.

Is there a facility to do this?

Thanks

For Craft 3, there is UploadIt, a  front end asset uploader.


How to output  for each language? I can't work out how to output <link rel="alternate"> for each language variation?

Is there any easy way to do this please?

Many thanks!

If you're looking to get the locale code for each site's language globally, it'd be something like this:

{% for locale in craft.i18n.getSiteLocales() %}
    {{ locale }}
{% endfor %}

If you're in the context of an entry, and you want to get the full URL and locale code for each site that entry is enabled it, it'd be similar to the answer here: https://craftcms.stackexchange.com/a/23751/57

{# Grab the entry #}
{% set entry = craft.entries.id(2).one() %}

{# loop through all of the supported sites for the entry #}
{% for siteInGroup in entry.getSupportedSites() %}
    {% set site = craft.app.sites.getSiteById(siteInGroup['siteId']) %}

    {# Grab the entry for the given site #}
    {% set entryForSite = craft.entries.id(entry.id).siteId(site.id).one() %}

    {# output the site-specific entry info #}
    <link rel="alternate" href="{{ entryForSite.url }}" hreflang="{{ site.language }}">{{ entryForSite.title }}</link>
{% endfor %}


What's the correct directory setup for Craft with Vanilla Forums? I'm looking in to setting up a new site which has a Craft site in front of the open source version of Vanilla Forums. I'm a bit stuck on exactly where I should put vanilla though, and how to access it on the front end.

At the moment I've got this setup:

/
    /craft
    /public
        /vanilla

But then vanilla's URLs look like http://domain.dev/vanilla/index.php?p= and it seems to conflic with Craft's .htaccess.

I've also seen on another question that someone installed vanilla in the templates directory. Is that better or a bad idea?

Lastly, should I be trying to run the forums under something like domain.dev/forums/, or would it be easier to run it on a subdomain like forums.domain.dev? I'm going to be using the Single Sign On plugin to integrate it with Craft.

Daryl,

I've setup a few sites with Craft and Vanilla Forums, I've always named the folder "Vanilla" to either "Community" or "Forum" so the url being "vanilla" isn't a problem. Also you should know you can do a javascript include into another craft template so the URL can be anything you want really. I've never had a .htaccess conflict though.

I've always run the forums under /forums or /community or something of the sort when not using the javascript iframe embed method at which point the url can be anything. I've never attempted using a sub-domain, just did not see the point.


Refresh Craft for loop with form parameters Recently new to Craft and Twig although I have used Expression Engine in the past. I am looking for a way to update a for loop that is pulling entries from a defined category based on the current entry/page category by using a dropdown list with all categories available.

Entries: Vehicles

Categories: Truck, Suv, Compact, Economy

Fields: Color, numofDoors, passangers, gasmileage

Example of code:

{% set related = craft.entries.section('vehicles').relatedTo(entryVehicleCategories%}

{% for vehicle in related %}

    {% if related|length %}

Name:{{vehicle.name}}

color:{{vehicle.color}}

Number of doors:{{vehicle.numofdoors}}

    {% else %}

No content

    {% endif %}
{% endfor %}

<form action="{{ url('search/results') }}">
    <select name="vehicle-search" placeholder="Search">
        <option value="Truck">Truck</option>
        <option value="Suv"> Suv </option>
        <option value="Compact"> Compact </option>
        <option value="Economy"> Economy </option>
    </select>

    <input type="submit" value="Go">
</form>

Upon form submit I am hoping I can change/set related to something new.

Example: Current loop is looping and showing all related truck entries.

Action wanted: User selects suv and div reloads suv entries on page without reloading page.

You will need to use JavaScript, either AJAX calling to a template that re-runs a new Twig for loop and returns the results in HTML, or a framework like Vue or React in conjunction with P&T's Element API that will create an endpoint of your section's entries in JSON format.

If you don't mind a page refresh, you can filter your entries dynamically using craft.request to grab pretty much whatever you want: a segment from the URL, query string, post data, etc. So basically, when the form submits, your redirect url should go to that page and either you add submitted data to the url via get or grab the data via post.

Also, fyi, you have a syntax error in your code: missing a ) at the end of your .relatedTo ;)


Can you change the URL for Assets uploaded to a Rackspace CDN? Assuming that you're using Craft Pro, is it possible to change the URL from the long randomly generated character string to something more user friendly?

Currently: http://83af0ee9e3c8cba9844f-a33048c0ede2332addff32deec6d7158.r40.cf3.rackcdn.com/subFolder/randomImage.png

Not really Craft related, but: for this to work in Craft, you should first make sure Rackspace recognizes the url you want to use. They explain how to do this here.

In short: create a CNAME record for your domain, pointing to your Rackspace domain. After doing that, change the display url for your asset source.


How do I set up same site to use two different subdomains? I have to set a the same site on two different subdomains. I have the two subdomains included in the config.php. But that doesn't seem to work. Is there any other configurations I need to set?

// internal
'sub1.website.com' => array(
    'overridePhpSessionLocation' => true,
    'environmentVariables' => array(
        'siteUrl' => 'https://sub1.website.com/',
        'fileSystemPath' => '/var/www/html/'
    )
),
// external
'sub2.website.com' => array(
    'overridePhpSessionLocation' => true,
    'environmentVariables' => array(
        'siteUrl' => 'https://sub2.website.com/',
        'fileSystemPath' => '/var/www/html/'
    )
),

Are these two sites exactly the same, and this is just an alias?  If so, you don't need any configuration, just point the DNS to the right place, and it'll work.

If not, can you provide more details on what you're trying to achieve?


Where does Craft store the field definitions? I would like to add field and section definitions to versioning. Or at least, have them backed up constantly.

I haven't been able to find out yet how craft handles this. I'd say it's in the database, but apparently it's not: the database has a uid column where values like 305ed8b6-3519-422f-8436-eca448145656 are stored. This probably refers to some git-ish entries in the file system.

So is this out of reach for manual save/restore/export/import?

Basically look for the tables "craft_fields", "craft_content" and "craft_sections".
For Fields you can use the "Field Manager" Plugin.


How do I log out a guest user? In the sample code, Logout doesn't actually do anything. Once a user has created a cart / order and the go to a different page, I want to force log them out, so if they go back to the cart page, it's a new order etc where they have to enter their email in again. Thanks

I'm not clear on what you're asking.

A user's cart is created as soon as they land on any page that has {% set cart = craft.commerce.cart %} in it; whether they are a logged in user or not. Carts are not attached to Users until the order is complete (and only if you were a logged in user). You can have a cart as a guest, add to it, then log in and you'll still have the same cart.

Are you saying that you want someone to fill out a cart, pay for it, complete the order - then be logged out immediately? Why? If they complete an order and then make another order it will already be a different cart.


Asset subfolder is not showing in the entry field as a folder option I have an asset folder images and I have created a subfolder in the images folder so:

images
   |
subfolder

In my entry fields I am not seeing the subfolder in the asset selection pop-up. Any ideas why this would be?

Worked this out. In the entry field I was limiting uploading an image to one folder. Once this was unchecked and only images selected in the folder list the subfolder appeared.


How can I list previously viewed entries? What approach should I take to create a list of previously viewed entries? Including the ability display the list, remove an entry from the list or delete the whole list.

The previously viewed entries list would only exist for the duration of a visit.

Craft doesn't have anything like an onViewEntry event, which you could listen for.

One way to do it would be to have a plugin that listens for onEndRequest. That plugin would determine if the current URI matches an entry and if so saves it to the database along with the userId.

Then you could build a management page off of that info where you could remove from the history or delete it all-together.


Guest Entries plugin will only submit when logged in - not anonymously (via AJAX) I am trying to create an entry in a section via AJAX from the front end when not logged in. I am using the 'Guest Entries' plug in for craft to do this.

The entries are all the same and consist of only a title.

I have the whole thing working perfectly when I am logged in but not when I am logged out.

There is no form on the page as the whole thing is called via JS. The Jquery code looks like this:

var formData = [{name: "CRAFT_CSRF_TOKEN", value: "biglongtokenhere"},{name: "action", value: "guestEntries/saveEntry"},{name: "sectionId", value: "5"},{name: "title", value: "Added"}];
  $.post('/', formData , function(response) {
    if (response.success) {
      //do stuff
    }else{
      // do other stuff
    }
  });

When logged out all I get back is a 400 bad request error. Logged in as an admin it works perfectly.

The plug in is installed correctly and has a default author selected and the 'Entries Enabled by Default' slider set to true on the settings screen.

My understanding is the plugin should allow for anonymous entry submission. Thanks in advance for any suggestions.

So can now answer this myself. Basically the issue is the CSRF token validation.

Options are to disable CSRF in the config.php file. Up to you how comfortable you are with that.

Or use the CSRF token properly! I thought I could set the token statically but that's not the case (which is obvious in hindsight). It is unique to each browser and is set as a cookie.  To work with a pure JS set up this needs be set dynamically as a JS variable on page load. More information here: https://craftcms.com/support/csrf-protection#updating-your-javascript


How can I keep the Compiled Templates from caching during development? I'm currently developing some templates in Craft. My work flow is

> Make a change to the template file
> Save the file, which automatically loads to the server
> Reload a test page in a web browser

About half the time, and somewhat erratically the adjusted template does not load. Once it is not loading, no amount of browser reloading, clearing local caches etc will help. The only thing that I have been able to find that will consistently fix this is to go in CP Settings and clear the Compiled Template cache. Obviously this is a pain to do each time, and slows my development time considerably.

Initially I tried to set a Craft config of 'cache' => false, because I read this advice somewhere, but I see it doesn't appear in the documentation, and it doesn't work. I've also tried  'cacheDuration' => 'PT1S' to no avail.

The cacheMethod is set to Default. Craft version is current.

If you're in devMode, then Twig's compiled templates will be regenerated on every request.  Otherwise, they'll be regenerated when Twig sees that the source template's date modified timestamp has changed.

As of PHP 5.5+, PHP's opCache is enabled by default, which might explain what you're seeing. If you're in development, you'll want to disable that to make sure PHP isn't doing any caching at the byte level.


Show all form errrors using amforms I'm using amforms and would like to display all form errors at the top of my page, not just per field. I can't seem to find the answer in the docs. Is this option available?

I'm not sure if this is the intended way, but I rigged this up and so far it works well.

{% set yankee = craft.amForms.getForm('hotel') %}

{% macro foxtrot(errors) %}
    {% if errors %}

            {% for error in errors %}

{{ error }}

            {% endfor %}

    {% endif %}
{% endmacro %}

{% from _self import foxtrot %}

{# list of form errors #}
{% if hotel is defined %}

        {% set fields = yankee.getFields() %}

Please correct the errors listed below before submitting the form.

            {% for field in fields %}
                {{ foxtrot(hotel.getErrors(field.handle)) }}
            {% endfor %}

{% endif %}


Populate Lightswitch field from Frontend Entry Form I have the following buttons on my frontend entry from (user editing one of their entries). The idea is to turn the lightswitch "on" (green) when entry is being marked as draft and "off" when submitted for review. The turning it "on" part seems to work. I just cannot seem to control its "off" state.

        <button class="btn btn-primary btn-lg btn-block " style="margin:10px 15px 0 0;" type="submit"  name="fields[gistDraft]" value="true">Save as Draft</button>

          <button class="btn btn-success  btn-lg btn-block " style="margin:10px 15px 0 0;" type="submit"    name="fields[gistDraft]" value="false">Save &amp; Submit for Review</button>
        </form>

The Lightswitch field is a simple boolean/tinyint column, with a 0/1 value. For this to work, you want to do something like this:

<input type="checkbox" name="fields[gistDraft]" value="1" {% if entry.gistDraft %} checked="checked"{% endif %} />

If you are sending the value some other way than a checkbox (the lightswitch field is a hidden checkbox), make sure that gistDraft has a value of 0 (off) or 1 (on).


Looping through Entries based on MultiSelect Field Selection I’ve got a people entry type that has a peopleCategory multiselect field. I’m wanting to loop through all the people and grab the ones that have a a specific item selected in the multiselect field (in this case - that they have been marked as being in 'leadership'). I was using

{% for entry in craft.entries.section(‘People’).peopleCategory(‘leadership’) %}
    {% if entry.peopleCategory.contains('leadership') %}

but in conjunction with another if statement

{% if loop.index==1 %}
{% elseif loop.index==2 %}
{% elseif loop.index==3 %}
etc

and that ended up throwing off the formatting in the template  - so now I’m tyring to find a new solution using something like:

{% set leadershipTeamTest = allPeople.peopleCategory('leadership').peopleCategory('leadership') %}

or

{% set allPeople = craft.entries.section('People') %}
{% set leadershipTeam = allPeople.peopleCategory('leadership').peopleCategory.contains('leadership') %}

but having trouble where it’s either returning everyone, or no one.

I'm still a pretty new to Craft - but would appreciate any help ( was using this - https://craftcms.com/docs/multi-select-fields but couldnt get it going)

Pretty straight forward in the end =]

{% set allPeople = craft.entries.section('People') %}
{% for entry in allPeople if entry.peopleCategory.contains('leadership') %}


How is conflicting asset filename created I upload files on the frontend using AJAX requests to actionUpload controller. When file is uploaded, I immediately display it using filename returned by controller.

In case if filename conflict, the duplicate file is created, with a name like something_200518_221543.jpg. How can I retrieve this duplicate filename, so I can display this file too? In control panel, this duplicate filename is somehow appended to the page, but I don't know how - there is no request that returns this new filename from backend.

This will be possible as of the next Craft release, which will be 3.4.21: https://github.com/craftcms/cms/commit/a787fe0ef37841706a5a9910fbeae0391da3be6f


What variables are available to what template types? complete newbie question here. Craft is so well designed, I could probably work it out, but it seems like this simple info might help others as well.

So here goes, a two part question:
1. Is there a simple list of the types of pages Craft outputs?
   (like single-entry, single-category, search-results, etc)
2. What are all the variables available to each of those?
   (single-entry has a variable called 'entry', plus the globals, I think)

Thank you!

It looks like you're coming from some other system? When I see "single-whatever" I think of WordPress' specific template structure... which may or may not have any meaning in Craft.

Unlike something like WordPress where there's a very specific structure to how you get information and what template determines how it behaves, Craft is a bit more open-ended (and DIY) in that regard and that can lead to some confusion, especially if you try to setup something like a search page and then try to use entry as variable (which won't be defined, unless you define it yourself).

1. Is there a simple list of the types of pages Craft outputs?

Unlike other content management systems, Craft really doesn't have a concept of "page types". One of the great things about Craft (and probably slightly confusing when you first start) is how you reference content throughout the system in the same, simple way.

You probably know that Craft holds your "page" content in what are called Entries. Think of Entries like Pages since they can map to a URL but they don't necessarily have to...

2. What are all the variables available...

Templates more or less work the same throughout. Craft's Globals are available no matter which template you're in, but Craft really allows you to fetch any piece of content (user, asset, tag, entry, etc.) anywhere you need it.

But what I think you're kind of asking about is when you view an entry or category specifically...

If you setup your sections/categories to have a URL/slug that Craft knows about, Craft automatically will populate the entry or category variable for you so you can access things like title, slug, and any custom fields you might also have on that entry or category.

It's basically a shortcut so you don't have to get it yourself and determine what kind of "page" you're on when you're in a template. Plugins can also inject their own variables into the system.

Craft's documentation on routing is a good place to reference on this as well, especially if you're used to another system where a certain file/folder structure is implied. Everything is up to you so your templates can be as messy or clean as you want them to be.


How to place assets in plain text fields? In ExpressionEngine i had a matrix field for images (assets) that i used in my entries.

I was using NSM Transplant and in my entries i could use {bild-1}, {bild-2} and so on wherever i wanted a image in my content.

The code is:

{produkte_ma_text_bilder}

  {exp:nsm_transplant:content id="bild-{row_count}"}

    {exp:ce_img:make src="{produkte_ma_text_bild}" max_height="{produkte_ma_text_bild_height}"}{/exp:ce_img:make}

  {/exp:nsm_transplant:content}

{/produkte_ma_text_bilder}

The matrix field looks like this:

When creating an entry it looks like this:

It seems like in Craft you need Super Table to do this.
But i can't figure out the code.

The solution is:

{% set mainText = entry.mainText %}

{% for row in entry.textImages.all() %}
    {% set findImage = '%%image' ~ loop.index ~ '%%' %}

    {% set replaceImage %}

    {% endset %}

    {% set mainText = mainText | replace(findImage, replaceImage) %}

{% endfor %}

{{ mainText | raw }}

Thanks to Andrew Welch from https://nystudio107.com/

Matrix fields in Craft are much more powerful than EE. In EE each Matrix row has a single set of fields available to it (a limitation of using a table-based UI). But in Craft you can set up multiple “block types” for a single Matrix field, each with a different set of fields.

So you can manage your text and assets all with a single Matrix field, with Text and Image block types. When an author wants to “insert” an image in the text, they can just click the button to create a new Image block; then continue writing more text by clicking the button to create a new Text block.

In your templates, you loop through each of the blocks, and output different HTML depending on the block type:

{# Load the blocks, eager-loaded with their image assets #}
{% set blocks = entry.yourMatrixFieldHandle
    .with(['yourAssetsFieldHandle'])
    .all() %}

{# Loop through them all #}
{% for block in blocks %}

    {# Alter the HTML output depending on their block type #}
    {% switch block.type.handle %}

        {% case 'text' %}

            {{ block.yourTextFieldHandle }}

        {% case 'image' %}

            {# Make sure that an asset is actually selected #}
            {% if block.yourAssetsFieldHandle|length %}

                {% set image = block.yourAssetsFieldHandle[0] %}

                {# Set the positioning class #}
                {% switch block.yourFloatFieldHandle %}
                    {% case 'left' %}
                        {% set class = 'float-left' %}
                    {% case 'right' %}
                        {% set class = 'float-right' %}
                    {% case 'center' %}
                        {% set class = 'center' %}
                    {% default %}
                        {% set class = '' %}
                {% endswitch %}

                {# Get the transformed image URL based on the chosen width and height #}
                {% set imgUrl = image.getUrl({
                    width: block.yourWidthFieldHandle,
                    height: block.yourHeightFieldHandle
                }) %}

            {% endif %}

    {% endswitch %}

{% endfor %}

Replace all the your____FieldHandle references with your actual field handles.

You also may wish to store image alt text either on the block or image, rather than just using the entry title. In that case replace the entry.title references with block.yourTitleFieldHandle or image.yourTitleFieldHandle.

(To create a custom field on your images themselves, create a new Text field in Settings → Fields called “Alt Text”, and then go to Settings → Assets → [your volume name], and add the Alt Text field to the volume’s field layout. You will then be able to access the field by double-clicking on your assets, either from the main Assets page or from within your Matrix field after you’ve selected an image.)


Can entries disabled by default in Guest Entries plugin and in section be enabled from the front-end? So I have the switch for Enable entries by Default set to OFF for Guest Entries and a channel.

Given this value="1" for input field name="enabled" on Guest Entry submission I always get entry not updated in corresponding field with desired value.

{# Enable entry #}
<input type="hidden" name="enabled" value="1">

I think the channel switch for Enable entries by default should be on as guest entries doesn't have control over that?

Currently, that won't work.

The Guest Entries plugin looks at the plugin's setting for whether that entry should be enabled for the given section or not, not anything from $_POST.

https://github.com/pixelandtonic/GuestEntries/blob/master/guestentries/controllers/GuestEntriesController.php#L227


Can't install plugin - Could not find plugin folder in zip I'm trying to install the plugin "Download assets" to Craft and I get an error when trying to install.

Directory was unable to install this plugin :(
No files have been updated and the database has not been touched.

Could not find plugin folder in zip

I do have an external site and a local development site. And this happens on the external site. It does however work correctly on the local site, and it's the exact same installation. What could be the cause for this issue?

As Brad mentioned in his comments, make sure you have the latest version of the plugin uploaded to the craft/plugins directory on your production server. I just tried it for testing sake and it seemed to work fine for me!

If you are sure they are in the right spot, check out this answer from a different question, stating to make sure the directory names are all lowercase, so "downloadassets" and not "downloadAssets" or "DownloadAssets," as many production environments are case-sensitive.


Craft 3 Plugin: Unable to add a new method to EntryQuery I am developing a Craft 3 plugin and would need to add a new method like

{% for item in craft.entries.section('sectionName').birthday('XYZ123').all() %}

According to doc https://docs.craftcms.com/v3/element-types.html#element-query-class, I am using following code:

File: /by/prefix/element/Birthdate.php

    <?php
    namespace by\prefix\elements;
    use craft\base\Element;
    use craft\elements\db\ElementQueryInterface;
    use by\prefix\elements\db\BirthdateQuery;
    class Birthdate extends Element
    {
        public $birthdate;
        public static function find(): ElementQueryInterface
        {
            return new BirthdateQuery(static::class);
        }
    }

File: /by/prefix/element/db/BirthdateQuery.php

    <?php
    namespace by\tariffsinfo\elements\db;
    use craft;
    use craft\db\Query;
    use craft\elements\db\ElementQuery;
    use craft\helpers\Db;
    use by\tariffsinfo\elements\BirthdateElement;
    class BirthdateQuery extends ElementQuery
    {
        public $birthdate;
        public function birthdate($value)
        {
            return $value;
        }
    }

and I am getting error message:
Calling unknown method: craft\elements\db\EntryQuery::birthdate()

Could anyone please help what am I doing wrong.

Thanks

You know you don't add a new function to Crafts EntryQuery you create a custom Element type with a custom Query and add a function to that one. By the way you should probably fix your namespaces

use by\prefix\elements\db\BirthdateQuery;
use by\tariffsinfo\elements\BirthdateElement;

In order to use your function you'll have to do

BirthdateElement::find()->birthdate('whatever');

To search for a custom field in an entries FieldLayout you just need to call the parameter by handle... So when you include a field into the layout with the handle birthday you can do

{% set entries = craft.entries.birthday('whatever').all() %}

When you want to search for your custom element type in your frontend you'll have to include a function to Twig like Craft does

/**
 * Returns a new EntryQuery instance.
 *
 * @param mixed $criteria
 * @return EntryQuery
 */
public function birthdays($criteria = null): BirthdateQuery
{
    $query = BirthdateElement::find();
    if ($criteria) {
        Craft::configure($query, $criteria);
    }

    return $query;
}

So you can access it via

{% set birthdates = craft.pluginName.birthdays.id(2).birthdate('whatever').all() %}


List the categories an entry is part of? I'm new to all of this and so far Categories from a templating point of view are confusing me a bit. I'm loving Craft so far but some concepts are causing me some headaches to adjust to!

What i'm trying to do is list the sub-categories a blog post is part of.

I have 6 categories and each has 4 sub-categories.
I only want to list the sub-categories.

So when someone is viewing the site and they click into a full blog post page, at the top i'm listing the title, author, posted date and i want to follow that with a lisrt of the sub-categories applied to that blog post.

This will list all the categories that are assigned to the entry regardless of level.

    {% for category in entry.categoriesFieldHandle %}

category.title

    {% endfor %}

If you only want to list the subcategories, (regardless of whether a main category is also assigned) then you can add a test for the category level.

    {% for category in entry.categoriesFieldHandle %}
        {% if category.level > 1 %}

category.title

        {% endif %}
    {% endfor %}


Get sale price in Commerce How does one get the sale price of a product in Craft Commerce on a product page? I'm new to Craft and Twig and the sale section of the Commerce docs is.. well, not really there (page under construction). I have a product that has a sale set on it. I pull the single product without problem:

{% set product = craft.commerce.products({
    relatedTo: category,
    slug: craft.request.getSegment(3),
    status: 'live',
}).first() %}

Product Title - {{ product.title }}
Product Price - {{ product.defaultPrice|commerceCurrency(cart.currency) }}

But a {{ dump(product) }} doesn't show any discount or sale values at all. I know the sale exists and is up; this returns my sale name:

{% for sale in craft.commerce.sales %}
    {{ sale.name }}
{% endfor %}

And I know my product is a part of that sale, it shows it as a related sale on the product entry page. The sale is wide open (no expiry or start, just one product picked (the one that populates the page I'm testing)). All attempts at sales price result in a templating error: {{ product.price }},{{ product.salePrice }},etc.

The only thing I can think is a nested loop and then conditionals... something like (pseudo code):

<span class="price">
{% for sale in sales %}
    {% for sale_product in sale.products %}
        {% if sale_product.sku == product.sku %}
            ... do some weird math?
            Check if % off or $ off and math it up with
            {{ product.defaultPrice }}?
        {% endif %}
    {% endfor %}
{% endfor %}

And that is clearly not how this is supposed to be done. Thanks!

Edit

And for that matter, how do I check if it is on sale at all, regardless of the sale value? The client design involves slightly different coloring/styles for a sale price versus a default price.

I think you would probably also need to check the default variant of the product, e.g.:

{% if product.defaultVariant.onSale %}
  {% set price = product.defaultVariant.salePrice %}
{% else %}
  {% set price = product.defaultVariant.price %}
{% endif %}

Product Price - {{ product.price }}


Sprout Forms Notifications to Office 365 address failing I've got a few Sprout forms on a site that are functioning nicely. Data is being save and notifications are firing to 2 of the 3 addresses. The third address is an Office 365 mailbox on the same domain but hosted elsewhere.

I'v tried updating Craft's Email setting to the SMTP info provided by the IT company in charge of the mail but it's erroring out with:

SMTP Error: data not accepted.

Has anybody else had issues with this? A little Googling has led me to believe that this is a common issue. Wondering if anybody in the Craft community has dealt with it successfully.

This error could be caused by the relationship between the user used in your SMTP Email settings in Craft and the From Address set in your Form notification. Some Mail Servers don't allow the sender (From Address) to be different from the SMTP user. Can you confirm if your From Address is the same email address in your SMTP settings?

Additionally, you may want to update your SMTP settings to use Mandrill or Mailgun. Those services make it pretty easy to look at your sent mail and see if it's being delivered and can provide more insight into what is happening if it is not being delivered.


Plugins in admin navigation Is it possible to choose which plugins appear in the main admin navigation?

I've installed Entry Count (https://github.com/putyourlightson/craft-entry-count) and it's now showing in the navigation (under Users).

In this case, I'd prefer to just access Entry Count via Settings > Plugins.

There's a plugin for that by Josh Crawford
https://github.com/engram-design/CPNav


What SQL query can I run to remove all users assigned to a particular group? So I have a user group containing a few thousand users and I want to remove all of those users with a SQL script.

These users don't have access to the control panel and so don't have any Entries authored by them.

At the moment I have this:

DELETE FROM elements WHERE id IN (SELECT userId FROM usergroups_users WHERE `groupId` = 5);

It looks like this removes related entries from the users, usergroups_users and content tables by virtue of the foreign key/cascade constraints.

Is there anything else I need to clean up?

You've done it the correct way.  Assuming all of Craft's foreign keys and cascading deletes are all still in place, removing the user's element ID from the craft_elements table is the way to go and all related data will cascade delete from there.


How to merge multiple 'relatedTo' queries via query parameters I'm trying to augment a Commerce query with additional parameters like so, but I can't get 'colour' and 'range' working together. Clearly my and/relatedTo syntax is wrong but how exactly?

  {% set colour = craft.app.request.getQueryParam('colour') ?? null %}
  {% set range = craft.app.request.getQueryParam('range') ?? null %}

  {% set query = {
    type: 'fabric',
    limit: 999,
    orderBy: 'defaultSku asc'
  } %}

  {% set query = colour is defined ? query|merge({ relatedTo: ['and', { targetElement: craft.categories.slug(colour) }]}) : query %}

  {% set query = range is defined ? query|merge({ relatedTo: ['and', { targetElement: craft.categories.slug(range) }]}) : query %}

  {% set swatches = craft.products(query).all() %}
  {% for swatch in swatches %}

(Also need to add further queries params for texture etc which are also related to categories)

I figured it out with help from https://craftcms.stackexchange.com/a/5339/7356

This could probably be further refined but...

  {# Get query parameters from URL #}
  {% set colour = craft.app.request.getQueryParam('colour') ?? null %}
  {% set range = craft.app.request.getQueryParam('range') ?? null %}
  {% set texture = craft.app.request.getQueryParam('texture') ?? null %}

  {# Tee up the product query #}
  {% set queryParams = [colour, range, texture] %}
  {% set hasValidQueryParams = false %}
  {% set relationParam = ['and'] %}
  {% set query = {
    type: 'fabric',
    limit: 999,
    orderBy: 'defaultSku asc'
  } %}

  {# Store any valid query parameters #}
  {% for param in queryParams %}
    {% if param != null %}
      {% set hasValidQueryParams = true %}
      {% set relationParam = relationParam|merge([{targetElement: craft.categories.slug(param) }]) %}
    {% endif %}
  {% endfor %}

  {# Merge query parameters into the main product query  #}
  {% if hasValidQueryParams %}
    {% set query = query|merge({relatedTo: relationParam}) %}
  {% endif %}

  {# Display the result  #}
  {% set swatches = craft.products(query).all() %}
  {% for swatch in swatches %}
    {% include 'range/_fabric_swatch' with { 'visible': true } %}
  {% endfor %}


Craft 3 Upgrade having issues with rich text editor I know that Craft3 now requires Redactor or CKEditor plugins to handle rich text editing, however after installing the Redactor plugin through the store, I am getting this error in the 'Body'.
The title and everything else works, just the body gets the error:

  Unable to find component class 'RedactorI'.

Simple.json

{
  "buttons": ["bold", "italic"]
}

Standard.json

{
  "formatting": ["h2","h3","h4","h5","p", "blockquote"],
  "buttons": ["html","formatting","alignment","bold","italic","unorderedlist","orderedlist","link","file","image","video","table"],
  "plugins": ["fullscreen","video","table"],
  "toolbarFixed": true
}

I've checked my craft/config/redactor simple and standard JSON files and they're properly formatted.

Any ideas?

Thanks

Solved it by installing the Redactor plugin, going through admin/settings/fields on the admin page and changing the field types dropdown from Plain Text to Redactor.


Update Craft 2 to 3? Now Craft 3 is available as a download, do you need to use composer for any part of upgrading a Craft 2 site to Craft 3 (if Craft 3 has been downloaded)?

Detailed instructions are now provided here: https://docs.craftcms.com/v3/upgrade.html


How can I get the locales that are actually enabled for a given entry? I can use getLocales() off of the entry model to get all locales in the system, and whether they are enabled by default for that entry type, but it doesn't actually return which locales are enabled for that given entry. Am I missing something?

Actually, entry.getLocales() (or just entry.locales) will return an array of the locales enabled for the entry's section, not all locales in the system.

Unfortunately, there's no easy way to determine which locales a single entry is enabled for. One way to do it, is to use a craft.entries query per locale, and add the locale ids to an array whenever you get an element back from the query:

{% set localesEnabledForEntry = [entry.locale] %}
{% for locale in entry.locales|keys %}
    {% set localeEntry = locale not in localesEnabledForEntry ? craft.entries.id(entry.id).locale(locale).first() : null %}
    {% if localeEntry %}
        {% set localesEnabledForEntry = localesEnabledForEntry|merge([locale]) %}
    {% endif %}
{% endfor %}

Of course, if you're looping through a lot of entries (and/or you have a lot of locales enabled for the entries' section(s)), this will quickly become a performance issue (you're basically doing 1 additional database query per entry per locale, except for the current locale being viewed).


Case sensitive craft.entries.search() in Craft From Brad's answer to this question it's obvious that Craft doesn't have a case sensitive search from the start, but he mentions that it depends on MySQL database and table collation.

My question is however related to the way Craft saves keywords in craft_searchindex table. Here they are converted to lowercase. So my question is if there is a way to enable case sensitive search through MySQL collation changes?

My issue is that the client sees an issue when searching for a Persons name in an article content he also finds results which only include words starting the same. However fuzzy search on the right side is needed, so turning it off isn't an option.

My answer in that other question was wrong (I've updated it).

As you pointed out, Craft normalizes all search keywords to be lowercase.  Case  sensitive searches would rely on the database's underlying collation if Craft didn't do that normalization first.

Probably worth adding as a feature request, if you think that shouldn't be the default behavior.


Commerce Stripe Authorize Only - Capture partial amount in Craft admin panel It doesn't look possible but can you capture partial amounts using the Craft admin panel?  E.g. Authorize $1000, then capture $700.

Also, when performing Captures in the Stripe panel, these transactions do not show in Craft in the Order Transactions box.  This looks like a bug to me.

Last, if we can't perform partial captures in Craft and need to do it in Stripe, how can we mark Orders as paid?

As of Commerce 2.0.0-beta.7,  partial capture is not yet supported. Look out for it in the next release.


Get disabled related entry's data within plugin I'm looping through products ($rawProduct) within Craft Commerce, within a plugin, and returning products which fulfill a certain criteria. I'm then returning a $products array of objects with the following:

$product = new \stdClass;
$product->url = $rawProduct->url;
$product->courseTitle = $rawProduct->relatedFieldTitle[0]['title'];
$product->courseUrl = $rawProduct->relatedFieldTitle[0]['url'];
array_push($products, $product);

This is working great. However, when the target entry of the related field is disabled, lines three and four above are returning empty. I'd like to get this information no matter whether the target entry is disabled. Any ideas?

Came across this same situation myself. Was able to resolve with:

$entry->entriesFieldWithDisabledEntry->status(null)->first()


Why isn't my Twig replace filter working with craft.request.getUrl()? I'm rendering some HTML into a variable. On this HTML I want to replace a value using craft.request.getUrl() but the value doesn't seem to get replaced. Any idea what I'm doing wrong?

{% set pages %}
    {% set entries = craft.entries.section('pages') %}
    {% for entry in entries %}
         {{ entry.title }}
    {% endfor %}
{% endset %}

{{ pages|replace({'data-url="{{ craft.request.getUrl() }}"': 'class="active"'})|raw }}

Try:

{{ pages|replace({('data-url="' ~ craft.request.getUrl() ~ '"'): 'class="active"'})|raw }}

You were double nesting Twig tags {{ {{ }} }}, which is never necessary.  You'll want to use string concatenation instead. Also for dynamic keys in twig you need parentheses.