How do I get a random entry's URL from a Entries field? I have a Entries field and I'd like to return a URL for one randomly picked entry.

I could loop through all the entries, but I'd like to do something more efficient. Can I return an array of URLs? Or better yet, is it possible to randomly get one URL all at once?

It is possible to have the query pick a random entry.
From the Craft Entries Fields docs we see that entry.entriesFieldHandle is a shortcut for

craft.entries({
  relatedTo: { sourceElement: entry, field: "entriesFieldHandle" },
  order: "sortOrder",
  limit: null
})

And what we want is to order the entries randomly, and then limit the number we retrieve to only one:

craft.entries({
  relatedTo: { sourceElement: entry, field: "entriesFieldHandle" },
  order: "RAND()",
  limit: 1
})

So to retrieve one random entry and get its url:

{% set randomEntry = craft.entries({
      relatedTo: { sourceElement: entry, field: "entriesFieldHandle" },
      order: "RAND()",
      limit: 1
    }).first()
%}
{% if randomEntry %}
  {% set randomUrl = randomEntry.url %}
{% endif %}


How can I return the entry with the highest value? Each entry in posts has a field called value.  Value is a number.

For a category, how can I return the entry with the highest value?

This is not for Craft Commerce.  Value represents a budget figure.

Alternatively...

How can I return the top 3 entries (based on value)?

Sounds like you're looking for a combination of the orderBy and relatedTo entry query params.

This may put you on the right track?

{% set topThree = craft.entries({
  section: 'posts',
  relatedTo: { targetElement: myCategory },
  orderBy: 'myBudgetValueField desc',
  limit: 3
}).all %}

Alternatively, for just the entry with the highest value:

{% set topFigure = craft.entries({
  section: 'posts',
  relatedTo: { targetElement: myCategory },
  orderBy: 'myBudgetValueField desc'
}).one %}

Of course, this depends on myBudgetValueField being a number or some other easily-sortable value. If you need to format the value, I'd recommend storing it in the unit for comparison, and then visually treating it when you output it (i.e. store 300000, even if you eventually need to output $300,000).


How to create any code from google spreadsheet like {.label} by Craft CMS ex) original HTML source code

<link rel="exhibit/data" type="application/jsonp" href="https://spreadsheets.google.com/feeds/list/~~~~/od6/public/basic?alt=json-in-script" ex:converter="googleSpreadsheets" />

~~~~~

    Aired:

    Genre:

You can see .label, .start, and .genrem but on Craft CMS they are errors.

How do I create code with no errors?

Error message is,

Internal Server Error

Unexpected token "punctuation" of value ".".

*The error message displays like this on my PC's XAMPP
craft/templates/index,html

Thanks in advance!

ref image on google spreadsheet,

You need to use valid html/twig in your templates. Your “HTML Source Code” is not valid html. Removing the . from the beginning of your attributes i.e.: <span ex:content="genre"> should resolve the error, but it still wont be good html.

Best option, IMHO, is to start with a good solid foundation of valid html and work up from there.


Sprout Forms: Localized version of form with translated labels? Does  the Sprout Forms plugin tap into the internationalization feature of Craft Pro, i.e. does it support adding localized versions of existing forms, similar to translated section entries?

What I'm looking for is creating forms where all field names and values are identical between language variants, but labels and notifications may differ per locale. (This is opposed to setting up multiple forms that are not tied together and write to separate tables in the back-end.)

In the docs, all I can find is a reference to translated error messages, which are the smallest of my concerns. — That same approach might work for the main conent of the form as well, but it could not be managed via the plugin's control panel.

Currently, Sprout Forms (v1.1.0) is translatable, but we have not yet added support for Craft's localization feature.

You can find a template of a translation file on our Github Account.

We want to support localization in the long run. The main reason we have not yet is mostly just one of priority. In comparison to other advanced features, we have had very few requests for it (feel free to send us a note and advocate for how this needs to work for you) and development for it isn't documented anywhere (feel free to send Pixel and Tonic a request for documenting it better too!). At the time of this posting, I posted a question here about the topic 7 months ago [February 2015] and the question has received one upvote and 41 views:

How do you add support to manage content in multiple languages in a plugin with a custom Element Type?


Do email messages use control panel or translation file template when sending by key? When an email key is registered for use with craft()->email->sendEmailByKey, it shows up in the control panel at Email Settings->Messages. This seems like a great way to allow easy editing of the messages by clients.

If I have something hardcoded in my plugin's translations folder (e.g. /translations/en_us.php) corresponding to the email message key, will the subject and body always come from that file, or will it come from the data in the control panel? Specifically, if an update is made to the template in the control panel, does that completely override the template defined in the translations file? If so, is there a way to revert back to the version in the translation file?

The answer is both. It will use whatever’s in the translation file by default, until an admin goes to Settings > Email > Messages and customizes it.


Activate Users - privilege Is it possible to assign priveleges to a user group (not admin but with CP access) to manually 'Activate User's?

We have a few users who struggle with the email process but it would seem only top level admins can Activate - is that the case or is there an override?

Thanks
Dan

requireAdmin is hard coded into the actionActivateUser action in line 444 of the UsersService file, so I suspect that there is no way to over-ride this without creating your own plugin.


Craft 3 attachment email I need to add an "attachment" to an email sent by Craft CMS 3.

I used a custom "Module" for this with a "Model", "Service", "Record" and "Controller"

I did some research but did not find any clear answers on how to do it.

How to send a email with an attachment?

---- Update -----

Here's what I need to do

Example :

Person A
Fill the form with file a file ( like doc, pdf etc... )

Prepare the email with the custom "module"

Do I have to upload the file somehow on the server before do the attachement in the email ?

Send the email with the file in attachement to Person B

Assuming what you're trying to attach is on the local filesystem, you can see an example of this here: https://github.com/pixelandtonic/craftnet/blob/master/src/orders/OrderBehavior.php#L160-L182

Essentially, you'd just use attachContent, but there is also an attach method:

->attachContent($pdf, [
    'fileName' => $filename,
    'contentType' => 'application/pdf',
])


Output URL to section Is it possible to output the path to a given section?

I'm using this to define the section model for the contact page (a single):

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

But then, there doesn't seem to be a way to get the url from this model (according to section model page on the Craft website.

It seems this information does exist as on the backend there's a link to the Contact page next to the link to edit the section.

Many thanks.

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

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

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


Make an Ajax call to plug-in controller I am trying to send data to my plug-in controller using jquery $.post() method.
here is my form:

<form method="post" action="" accept-charset="UTF-8" id="testForm">
  {{ csrfInput() }}
  <input type="hidden" name="action" value="test/test">
  <button type="submit">Test</button>
</form>

and this is my js code:

<script type="text/javascript">
   window.csrfTokenName = "{{ craft.config.csrfTokenName|e('js') }}";
   window.csrfTokenValue = "{{ craft.request.csrfToken|e('js') }}";
</script>
<script>
$("#testForm").submit(function (e) {
    e.preventDefault();
    var data = [];
    data["test"] = "test";
    data[csrfTokenName] = csrfTokenValue;
    $.post('/', data, function(response) {
        console.log(response);
    });
});
</script>

The console keeps logging "400 Bad Request".
What am I doing wrong ?

You need to define a route via action param otherwise Craft has no idea where to route the request. Your data variable only only contains

data = [
    'test' => 'test',
    TOKEN_NAME => TOKEN_VALUE
]

and nothing else

You need to include action => plugin-handle/controller-id/function-name

You can see a working example at basic ajax how to


Craft 3 - Recommended development environment for Windows? I was wondering what people who are developing on Windows 10 are using as webserver environment in 2018? I have had ok results previously using ampps, but I'm having a lot of problems with Craft 3 as of lately. With 500 internal server errors etc. Also, I'm developing on several PCs, syncing the projects with Git.
A friend of mine recommended Laravel Valet and homestead, but he's on Mac. And installation on Windows seems to be a lot trickier. I've tried Mamp too, but have really bad experience with that one.

First of all, I am also a Mac user. But these should be available for Windows too.

Start reading about virtualization. So, you won't install the web server directly on your machine but on a virtual box installed on your machine.

A good starting point could be vagrant (which is becoming a bit antiquated more and more, but which is still worth a try since it's working like a charm).
What's getting more and more into many developers' focus is docker. Many of my customers have been introducing it in their developer teams the last years.

Hope that helps. It's a lot to read though…


How do I relate a user to a channel entry from a form? I have a channel which has a relate to user field, how do I setup the front-end form which is a user details update form so they can select a channel entry from a drop down and when saved, have it relate that user to the channel entry.

When saving an entry field type as part of your plug-in it needs to be an array of IDs in order to work correctly. This can either be handled via a plug-in or in the form by passing the value as an array to that field handle.

Plug-in:

$user->setContentFromPost(array(
    'entryField' => array(10)
));
$success = craft()->users->saveUser($user);

Front-end form:

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


AJAX CSRF Producing Inconsistent Results I am using CSRF tokens in a form on CraftCMS. Submissions are successful with a standard configuration.

Introducing "fresh" CSRF tokens via AJAX on page load is causing some trouble. This is necessary as production has caching.

Here are some observations:

Disabling CSRF validation in config/general.php resolves the issue entirely; however, of course, this is not the solution.
Disabling CSRF cookies does not resolve the issue.
Failed attempts appear most commonly in iOS on Safari. It also occurs sometimes on Edge. It appears to work always in Chrome.
Regarding Safari: one idea here was that the browser disrespects Cache-Control and thinks it should be caching this request, hence resulting in a failed CSRF validation. Adding in a timestamp to the request in a query string did not resolve the issue.
Failed attempts result in a "400 Bad Request" response. The body sometimes reads: Bad Request: Unable to verify your data submission.
Failed attempts occur regardless of server side caching. This has been tested on local environments (Homestead) with no non-standard caching configurations.
The token returned on the CSRF AJAX request is different each time.
The form is built with FreeForm, but I do not think that is of significance.

Questions:

How does one track the request further to find the reason for failure?
Is providing CSRF tokens via an AJAX request sensible? The typical response I see is adding in the token via an inline Javascript variable. (Read) That route is not an option here.

Any pointers here would be very appreciated. Thanks in advanced!

Trying to understand the issue in general. These are my thoughts, not sure if they will help you.

I assume that by caching, you mean some sort of full page cache and the comments below are based on that.

AJAX requests to support CSRF in craft, require the tokens name/value passed as a param in the request data.

In general, if you introduce a full page cache system on your system, you generally need a 'hole punching' mechanism to exclude from caching, any dynamically set variables.

This is a common use for eCommerce websites. For example where you might have a mini-cart feature on your page which needs refreshing when you perform an 'add to cart' action using AJAX. So the page does not refresh, but that bit of template needs refreshing.

Within Craft, I would try to exclude from caching the javascript lines that introduce the CSRF token, as well as excluding from cache any twig methods that generate the CSRF token in the templates

The way to perform 'hole punching' depends on the type of full page caching you are using. Each system have their own method.


How do I get a URL link to open in a new window once clicked I have a URL to an external website within one my site's pages.  I want this to open in a new window.  I don't want the viewer to move off our website but will want them to click on the link to our third party.
How do I get the link to open in a new window?
thanks

Add target="_blank" to the link.

Like so: Opens in new window


Plugin development - Adding Foundation 5 CSS changes Craft CMS control panel I am trying to embed a Google Map widget as a field in Craft. I am doing plugin development to achieve it.

Adding a foundation 5 css in a PluginName_FieldType.php file into the getInputHtml() function results in changes is Craft Control panel.

craft()->templates->includeCssResource('pluginhandle/foundation.css');

I apologise if it is something silly. I am a newbie to Craft.

I don't use Foundation 5. I've been using Foundation 6, but I'll offer a suggestion based on Foundation 6 usage.

It looks like your Foundation CSS is overriding the base Craft control panel CSS, specifically the button classes.

My guess is that because you're including all the Foundation classes available. If you're using the SASS version, you can comment out the parts you aren't using to minimize the size of what you're using from the base Foundation code. For example, you can try to exclude the button classes from Foundation.

Specifically, if you remove the .button styling rules from your foundation.css file, the Craft buttons would go back to normal.


What's the difference between {{ siteUrl }} and url()? Both of these things:

1.  {{ siteUrl }}path/to/template
2.  url('path/to/template')

... will generate this:

http://mywebsite.com/path/to/template

So I'm wondering, which method is preferred? Are there any pros/cons of either technique?

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

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

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

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

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


Method (plugin free?) to combine search results across multiple searches (and element types) So I have created a combined search for products and entries using the new Craft 2.5 search score.  It's working well, but...I was hoping to be able to do this without a plugin if possible ... but it doesn't seem immediately possible to do unless I am missing something.

If anyone knows a way, it would be much appreciated.  In the meantime I'll post the solution I have come up with as an answer below.

To get this working I submitted a patch to 'SortByField' - https://github.com/dannynimmo/craftcms-sortbyfield - to get this plugin to work with Commerce products - and I now do this:

    {% set product_results = craft.commerce.products.search(query).order('score') %}
    {% set article_results = craft.entries.search(query).order('score') %}
    {% set all_results = [] %}

    {% if product_results|length %}
        {% set all_results = all_results|merge(product_results) %}
    {% endif %}
    {% if article_results|length %}
        {% set all_results = all_results|merge(article_results) %}
    {% endif %}

    {% if all_results|length %}
        {% set all_results = all_results|sortByField('searchScore', 'desc') %}
    etc.

Which is working well and the combined results make sense to me.

I am just wondering if their is a better/recommended and ideally plugin free way of doing this - i.e. sorting the combined result set by score?


How can I push a result of entries/products from a loop into an array? In the grand scheme, I am trying to get all products that are not related to specific categories.

Since any product can belong to any given number of categories, I am trying to loop through all categories and then only query against the categories that I want.

This is what I have so far:

{% set excludeCategoryIds = [36, 44] %}
{% set allProducts = craft.commerce.products.type('myType').order('title asc') %}
{% set products = [] %}

{% for category in craft.categories.group('myCategories').relatedTo(allProducts) %}
    {% if category.id not in excludeCategoryIds %}
        {% set entries = craft.entries.relatedTo(category) %}

        {# push entires into products?? #}
        {% set products = products|merge([entries]) %} {# doesn't work #}
    {% endif %}
{% endfor %}

Once all products are found, then I'll loop through them.

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

I could also loop through each of the entires as described in the docs but it's starting to feel like this is getting out of control.

Is there a better way to only show products that are not related to specific categories?

Thank you for any suggestions!

This line doesn't return an array of items; it returns an ElementCriteriaModel:

{% set entries = craft.entries.relatedTo(category) %}

That's probably why you're having problems with the |merge.

Changing it to the following should do the trick:

{% set entries = craft.entries.relatedTo(category).find() %}


Is it possible to filter with hasDescendants? I'm building a navigation menu with 2 levels.

I have a contact page with a subpage thank you, which is hidden.

I hide pages from the menu using a lightswitch option and filter these pages out in my entries call.

However I check if a page has subpages using hasDescendants(), and if the page does, I add the class "has-dropdown" but my contact menu item contains the class "has-dropdown" too which technically is correct as it has a subpage but is it possible to filter with hasDescendants() ?

{% set pages = craft.entries.find({section: "page", genericHideFromNavigation: "[0]"}) %}
{% if pages | length %}

        {% nav page in pages %}

                {{ page.title }}

                {% ifchildren %}

                        {% children %}

                {% endifchildren %}

        {% endnav %}

{% endif %}

What you could do is to get all the descendants and loop them to check if at least one has that lightswitch not set.

{% set showDropdown = 0 %}
{% for subPage in page.getDescendants() if subPage.genericHideFromNavigation == 0 %}
    {% set showDropdown = 1 %}
{% endif %}


Render template from Module in twig template I have been searching around SE and the web in general for an answer to this. There seems to be plenty of solutions but none appear to be working for me.

I have a simple module that has a variable that gets called from a twig template in order to render a form.

The problem is no matter what I do I cannot get the module to render the HTML from within its own /templates directory.

The variable code is:

$oldMode = \Craft::$app->view->getTemplateMode();
\Craft::$app->view->setTemplateMode(View::TEMPLATE_MODE_SITE);
$html = \Craft::$app->view->renderTemplate('../templates/_journey-planner.html');
\Craft::$app->view->setTemplateMode($oldMode);
return $html;

This is taken from the Craft docs. I have also used:

Event::on(View::class,
          View::EVENT_REGISTER_SITE_TEMPLATE_ROOTS,
          function (RegisterTemplateRootsEvent $e) {
                $e->roots['journeyplannermodule'] = 'journeyplannermodule/src/templates';
            }
        );

Within the module's init() function (not sure if this is actually required or not).

What am I doing wrong and what do I need to do to simply display this template within the twig template?

I am calling the variable method with:
{{ craft.journeyPlannerModule.getJourneyPlanner }}

Craft Version: 3.2.0

Now working. Turned out to be user error on my part. I had neglected the alias that I had created so the path to the template directory was incorrect.


I can't get the first image to show on the homepage I'm sure this is a simple question, but I'm a newbie in this, so I'd greatly appreciate all the help I can get! :)

The site is carstensphotos.lumenage.com for now. It's a one page site, so I used the index as the template for the Gallery Section ('gallery'), where the photographer will be able to upload his pics. I'm trying to get the first image of the first entry to show with no success.

Code:

  {% for galleryEntries in craft.entries.section ('gallery') %}

{{ galleryEntries.title }}

  {% endfor %}

   {% for image in entry.galleryPhotos.first() %}

    {% endfor %}

Thank you very much!

Just a slight syntax issue it seems.

If you want just the first image - always test if there is an image, then get it like this:

{% if entry.galleryPhotos.first()|length %}
    {% set image = entry.galleryPhotos.first() %}`

{% endif %

Or if you want to loop over a few images...note here you don't need the |length test as the for loop will not be entered if there is no image:

{% for image in entry.galleryPhotos %}


Loop through fields of a matrix block I have a matrix field shaped as follows:

MatrixField

Block ( just 1 blocktype )

Field1
Field2
Field3
Field4
FieldN

I want to loop through all the fields inside a block, check if the field is set and other stuff. How can I do it?

Check if the matrixField is populated:

{% if entry.matrixField|length %}{% endif %}
There are two options to pull out fields from a block type.

Option A: use a for-loop pointed at your Matrix field

// If you want to output block of a certain type
{% if entry.matrixField|length %}
    {% for block in entry.matrixField.type('yourBlock') %}
        {{ block.field1 }}
        {{ block.field2 }}
        {{ block.fieldN }}
    {% endfor %}
{% endif %}

// OR multiple types
{% if entry.matrixField|length %}
    {% for block in entry.matrixField %}
        {% if block.type == "yourBlock" %}
            {{ block.field1 }}
            {{ block.field2 }}
            {{ block.fieldN }}
        {% elseif block.type == "yourBlock1" %}
            {{ block.field1 }}
            {{ block.field2 }}
            {{ block.fieldN }}
        {% endif %}
    {% endfor %}
{% endif %}

Option B: use simplified method of a for-loop

{% if entry.matrixField|length %}
    {% set yourBlock = entry.matrixField.type('yourBlock') %}
    {% for block in entry.matrixField %}
        {% switch block.type %}
            {% case "yourBlock" %}
                {{ block.field1 }}
                {{ block.field2 }}
                {{ block.fieldN }}
        {% endswitch %}
    {% endfor %}
{% endif %}

Also check Craft's documentation about Matrix Fields.


Discounts applied based on cart total Our client would like to run a promotion which would require a user to spend at least £30 in order to get a certain product for free.

We have setup a ‘codeless’ discount that has:

the product that they get free in the Product field in conditions
The Purchase Total set to 30 (although I think this means the total value of the above products)
The Base Discount amount to be the same as the value of the product (3.99).

I had assumed, that provided the cart > 30 and that product was in their cart, the 3.99 would be automatically removed from the total. Now I’m guessing it’s not doing that because of the way the Purchase Total works.

If that is the case, does anyone know how I’d achieve the desired outcome?

You are correct, purchase total is the total of items selected.

We will look to add a 'Total Order Price' condition in the future.

For now you would need to make your own custom discount adjuster to build special discount conditions.


Getting full native language name in Craft3 language switcher I'm porting across a multilingual project from Craft2 to Craft3 and have to rebuild the language switcher. I was previously using the .nativeName method but apparently this is deprecated. I've got a really basic one working for flipping between the English and French versions of my site :

{% set langSwitcher = craft.app.sites.getAllSites() %}

{% for lang in langSwitcher %}
   {# Get base URL #}
   {% set url = alias(lang.baseUrl) %}
   {{ lang.language }}
{% endfor %}

The {{ lang.language }} is outputting en & fr but how do I get it to display the full native language names i.e English & Francais?

I found the getDisplayName() function in the docs but can't seem to get it working properly: https://docs.craftcms.com/api/v3/craft-i18n-locale.html#public-methods

The site.language attribute is just a string, i.e. the language code or locale ID, e.g. 'en'.

To get the native name you'll need to go through the I18N service to pull the actual Locale object via that locale ID:

{% set locale = craft.app.i18n.getLocaleById(lang.language) %}
{{ locale.nativeName }}

Edit: As @Dr_Codswallop mentions in the comments, locale.nativeName is deprecated in Craft 3, and will be removed completely in Craft 4. locale.displayName should be used instead.


Pass Craft field object to JavaScript function I need to pass an entire Craft object into a JavaScript function. I followed the instructions in this post, however this only covers passing in a string.

{% includeJsFile "/js/homepage.js" %}
{% set myJs %}
   playlistData('{{myObject}}');
{% endset %}
{% includeJs myJs %}

Any ideas?

You have to break it up into individual values before you can pass it through to JS...

{% includeJsFile "/js/homepage.js" %}
{% set myJs %}
   playlistData({
      field1: '{{ myObject.field1 }}',
      field2: '{{ myObject.field2 }}',
      field3: '{{ myObject.field3 }}'
   });
{% endset %}
{% includeJs myJs %}


How safe is auto-updating? I have auto-updating currently disabled using the "allowAutoUpdates" config setting, due to concerns about plugin compatibility and unforeseen breakages, mainly due to experiences with other CMS's.

However, I'm starting to feel that having that button available for clients to update automatically is very tempting, especially as the number of Craft installations to keep up to date increases.

How safe is this mechanic to enable? For example, if a client was to auto-update and there was a breakage, and the database was not able to roll back to a previous version? Surely you can't guarantee that the internal API won't change in the future, and if it ever does, how can the auto-update feature prevent plugin breakages?

And if I was to enable it, would this just be a case of adding the app folder to my .gitignore and not including it in my git repo?

Ben gives some good practical updating advice.

And I agree with him that for the majority of cases, the best practice is to update locally, then push to production.

Just adding my 2 cents on top of that.

First, some background:

Being a self-hosted PHP web application is a hard life.  Your parents try to raise you correctly and equip you with the tools necessary to successfully go out into the world and live on some stranger's unknown, unfriendly and oftentimes hostile server environment so you can serve up web pages, but things are stacked against you.

For any given 1,000 web hosting providers, you will find 2,500 different environmental configurations... at least.  Different Linux distributions each with their own different libraries and versions.  Windows servers running IIS... or Apache.  Different permissions and user/group setups for each account.  Different versions of Apache and all of its modules... or nginx. Different MySQL versions each with different configurations.  Or "drop in" MySQL replacements that the host doesn't mention they're using, that's actually not a drop in replacement.  Or hosts that decide it's a good idea to store PHP sessions in memcached.

You'll find yourself living on fully-managed servers where you have limited to zero control of what you can do.  On boxes administered by weekend sysadmin warriors, running the bleeding edge of every piece of software on their box, because they read it on HackerNews.  You'll live on overloaded, underperforming, $5/month shared hosting accounts where the host has crammed 400 sites on one box and you get blamed for being slow.

Everything is broken.  It's amazing software works at all, much less the Internet.

How is a simple PHP script meant to survive is such as harsh world?!

Now that we've painted this picture of a horrible, bleak universe that Craft has to live in, let's look at some stats:

Auto-updating stats

Hard numbers:

Craft has successfully sent out over 8,100 auto-update requests.
94% of Craft installs with recent control panel usage are running Craft 2.
Since launch, we've received roughly 2,000 Craft-related support tickets.
About 370 of those tickets have been related to updating.

Soft, touchy-feely, by-the-gut numbers:

Of those 370 updating support tickets, I'd guess 90% of them fall into environmental issues that are mostly outside of Craft's control, but Craft tries to deal with as gracefully as possible.

Usually the culprits are either a) permissions aren't setup correctly and Craft can't download the update patch file, unzip it, or write to the craft/app folder to actually update the files b) during the update, Craft runs into a php.ini limitation... memory_limit and max_execution_time being the most common.

Both of these can be an issue if they are set low (32M and 30 seconds on older PHP installs or stingy hosts), or the size of your database has grown large enough that when Craft tries to automatically back it up during an update, it bumps into them.  That's a reason we added the backupDbonUpdate config setting.

We'll also see a spike in update errors related to these settings during bigger Craft updates (like 1.3 => 2.0) when we'll do an update to Yii, for example, that touches thousands of files.  More files in an update = more time to process the update = more of a chance of bumping into a limit.  Some people might prefer to do a manual update during those times, since that can finish executing quicker than an auto-update would.

Craft will also try to increase these limits for itself at runtime during potentially long running or memory intensive operations like updating, but that doesn't always work.  Some hosts have hard limits on them and things like FastCGI don't allow PHP scripts to use ini_set() in order to increase them at runtime.
5% of those tickets are related to bugs in a database migration that the update needs to run.  This usually occurs when we overlook some way that someone is using Craft and usually get fixed quickly.
The remaining 5% of the tickets were related to bugs in the updating logic in Craft itself.  We saw a few of these back in the 1.0, 1.1 and maybe 1.2 days, but honestly haven't ran into one in quite awhile (knocks on wood).

Does Craft practice safe-updating?

I think so.  We've got some ideas to try and further bullet-proof the process, but this is how it stands currently and is working out pretty well.

When Craft downloads an update patch file, it first validates the MD5 hash of the file to make sure that the file it received is the one it expected and nothing got corrupted during the transfer.  If a failure occurs here, we consider that a non-rollback failure - meaning, a failure has occurred, but no files have been updated, the database hasn't been touched and the site is still online - so no harm, no foul.
Craft will unzip that file to a temp location, grab the RequirementsChecker script from the recently unzipped file and run it, so that if any new requirements were added to be able to run Craft, and your server doesn't support them, you'll get a message stating so. If a failure occurs here, it's a non-rollback failure.
From the recently unzipped patch file, Craft will validate that all of the paths that it's about to update are still writable by PHP.  If a failure occurs here, it's a non-rollback failure.
Craft will now make a backup of all of the files/folders it's about to update by coping them from fileName.php to fileName.php.bak or folderName to folderName.bak.  If the update deleted a file/folder, it still gets a backup created.  If a failure occurs here, it's a non-rollback failure.
The recently updated files get coped over to their new homes.  If a file was deleted during the update, it gets deleted at this point.  If a failure occurs here, it's a file-only rollback failure and Craft will attempt to take all of the recently backed-up .bak files and put them back in their proper place and put the site back online.  The database hasn't been touched at this point.
If Craft is configured to backup the database during update, this is the point where a database backup gets created. If a failure occurs here, it will do a file-only rollback.
If the update came with any new database migrations (alter table schema, and/or data) to run, this is the point where they run.  If a migration fails, or any other error occurs, this is a full-rollback failure and Craft will attempt to restore the database from the backup it just made in step 6 to its last known working state, as well as perform the file rollback.
If we've made it this far, we're almost done.  All that is left is housekeeping.  Craft will try to delete all of the .bak files it created as well as flush various bits of info from cache.  If a failure occurs at this point, technically the upgrade is finished, so we don't attempt any rollback.


How can you use the jQuery pjax plugin with Craft? There is a jQuery plugin called pjax (https://github.com/defunkt/jquery-pjax/) for downloading page content via ajax.

How can you integrate pjax in Craft for downloading entries via ajax? Or are there other ways to download entries via ajax?

In order to make an AJAX call in Craft, you'll need to build a custom plugin. Within the context of your plugin, add a Controller as the end-point for your AJAX call. Once you've setup your controller, take a look at the EntriesService API methods to sort out exactly how to retrieve your entry data.

If you've never built a plugin or are unsure of where to begin, you can download this Business Logic template to use as a starting point. It comes pre-packaged with a controller containing a simple AJAX call (and a lot of "how-to" notes).

If you have any follow-up questions along the lines of "how do I collect the data for my AJAX call", those would be worthy of being their own Stack Exchange questions.


Conditional to see if an Entries field in a user profile contains a certain entry ID I've got a user profile field named Books. This is an Entries field that contains entries from the Books channel. The idea is that users will save books to their their profile to show they have read them.

I've also got a listing page which outputs all the books that are available.

I'd like to add a conditional that checks to see if the entry ID for a book is contained within the Books entries field in the current user's profile.

I've tried the following but it doesn't work. It outputs as true for every entry, even those that aren't saved to the user's profile. Any help would be appreciated, thanks.

{{ entry.title }}

{% if currentUser.booksField.contains("entry.id") %}
  I have read this book
{% else %}
  I haven't read this book
{% endif %}

My initial though was that you do not need to not put the "entry.id" in quotes because it's a variable reference, but the contains() method appear to not work as expected here even when this was corrected.

The booksField returns an ElementCriteriaModel, so you should be able to fetch the list of IDs as a plain array and then use Twig's in "containment operator" to search it:

{{ entry.title }}

{% if entry.id in currentUser.booksField.ids() %}
  I have read this book
{% else %}
  I haven't read this book
{% endif %}


Creating a modal warning for an external link? I'm attempting to return a pop-up warning for users who click an external link on my site. The issue is, the functionality must still be there if JS is disabled. I think this would leave PHP as my only option, so would this be accomplished with a custom plugin? I've seen sites accomplish something similar with a separate redirect php include with the link destination in a query string. My experience developing Craft plugins is virtually nil so forgive my ignorance- but would that look like a plugin that finds and rewrites all the external links' hrefs on the existing page, returns the html for the modal (appends a fullscreen div to the dom), and populates a "continue to external link" anchor based on the original link in the query string? Am I on the right track here?

Thank you!

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

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

You're actually dealing with conflicting requirements:

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

Those two requirements will never really be in harmony.


User confirmation email not being received by hotmail? Has anyone experienced any issues with hotmail not receiving user confirmation emails? Our site is set up on a staging server and confirmation emails seem to work for all other email addresses we have tested apart from hotmail. Can't see anything in the logs that would suggest any problem.

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


Is it possible to tell Craft to ignore requests to under a certain path? Unfortunately, I'm in a position where I need to run a Craft and WordPress installation out of the same directory. The WordPress install is under the sub-directory /blog.

When I visit http://mysite.dev/blog/ the WordPress blog loads as expected, but attempts to visit any routes within that result in Craft's 404 page. For instance, http://mysite.dev/blog/my-post.

Is it possible to convince Craft to ignore any requests under /blog?

Have a look at the Routing article in the Craft Documentation, it describes why Craft handles these request in the first place:

  The .htaccess file that comes with Craft will redirect all would-be 404 requests over to index.php behind the scenes, which is why Craft is able to respond to URLs that don’t point to any actual folder/file in your web root.

A fresh Craft install's .htaccess file looks like so:

<IfModule mod_rewrite.c>
    RewriteEngine On

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

You'll notice that favicons are removed from the redirect. Add a similar RewriteCond for blog/ to also exclude request to your  WordPress folder from this condition.

    RewriteCond %{REQUEST_URI} !blog [NC]


Commerce Order Model in Gateway Event Plugin Hook I am trying to add some logic that can stop an order transaction from happening depending on values stored in the Order Model. Due to how my client wants the purchase page setup, I need to be able to do last-minute validating through the commerce/payments/pay action, which I can intervene before it happens using the onBeforeGatewayRequestSend event.

Below is a simplified version of what I'm trying to do. The issue I am having is accessing the Order Model, It looks like it isn't available in the $event parameter - which is why the below doesn't work.

craft()->on('commerce_payments.onBeforeGatewayRequestSend', function($event) {

    // This doesn't work. No 'order' param available.
    $order = $event->params['order'];

    /* logic using $order,
    -- set $is_valid (boolean) */;

    if(!$is_valid) {

       $transaction = $event->params['transaction'];
       $transaction->message = "This order is not yet complete.";
       $event->performAction = false;
       return $event;

    }

});

Is it at all possible to get the order model inside of this hook? Or is this just not the right place to be doing this?

You have access to the order from the transaction like this:

craft()->on('commerce_payments.onBeforeGatewayRequestSend', function($event) {

    $transaction = $event->params['transaction'];
    $order = $transaction->order;

}


Creating Task Manager for Client Portal Background & Problem

I've taken over our company website which was created using Craft. I've never worked with Craft and I'm beginning to like it, but the higher-ups want it done ASAP and I'm struggling understanding some things.

I've been tasked to add a page for our clients (AKA Client Portal). Each one of these pages will look and feel exactly the same with the exception of three areas (Discovery, Website, Assets) where the project manager will need to add tasks. These tasks will be a brief description and will be a link to some outside page (Dropbox or something else...).

Progress

I've created a Channel and called it Client Portal which works great! I can create a portal for each client and so far so good. The problem is I need to add these sections (not sure the proper Craft term) where they can add a Discovery task, Website task, Assets task. These are unique to the client, but will be styled exactly the same, but the content (text) will be different for each task/card. I'm not sure where to start with these sections (or whatever Craft calls them).

Can someone point me in the right direction on how I would create these sections?

I've created a JSFIDDLE to give someone a visual on what I'm trying to achieve.

https://jsfiddle.net/9goqgabp/

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

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

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

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

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

https://craftcms.com/community#slack


Craft Commerce "state" dropdown field fails to populate with states for new customer addresses I'm having an issue with addresses on Craft Commerce 3 (specifically the State field).
When a new customer adds an address, the State field defaults to a text field (not the expected Select field).
If you save the address and then go back, the State field turns back into the Select field (and defaults to Alabama). This is an issue because the form isn't actually collecting a valid State the first time through.
You can see reproduce this issue at https://renewable-lubricants.net/products/checkout/addresses
This issue is happening both on my modified templates as well as the latest stock Sample Templates, with no modifications.
The problem seems to be with this block of twig code below in "addresses/form.twig". Any idea what would make "options" fail the first time through?
State
                    {% set options = (model and states[model.countryId] is defined ? states[model.countryId] : []) %}
                    <select id="{{ modelName }}-stateId" data-modelname="{{ modelName }}" class="js-address-stateId w-full {% if options|length == 0 %}hidden{% endif %}" name="{{ modelName }}[stateValue]">
                        {% for key, option in options %}
                            {% set optionValue = (model ? model.stateId : '') %}
                            <option value="{{ key }}" {% if key == optionValue %}selected{% endif %}>{{ option }}</option>
                        {% endfor %}
                    </select>
                    <input type="text" data-modelname="{{ modelName }}" id="{{ modelName }}-stateName" class="js-address-stateName {% if options|length > 0 %}hidden{% endif %} w-full" {% if options|length == 0 %}name="{{ modelName }}[stateValue]"{% endif %} value="{{ model ? model.stateName : '' }}">
                    {% if model and model.getErrors('stateValue') %}
                        {{ model.getErrors('stateValue')|join }}
                    {% endif %}

This is caused by the model.countryId not being defined on first page load, which means the options defaults to an empty array. Once the address is saved, the selected country that is saved will provide the countryId and therefore your states dropdown is populated the second time around.
IIRC, the sample Commerce templates hide the text field and show the states dropdown field via JavaScript based on the selected value of the country dropdown.
If you know you're always going to default to United States as the initially selected country, you could ensure your state text field is hidden by default and set a default country ID:
{# Note: example country ID #}
{% set defaultCountryId = 51 %}

{% set options = (model and states[model.countryId] is defined ? states[model.countryId] : states[defaultCountryId]) %}

I think you could get the correct country ID for the USA from craft.commerce.countries.allEnabledCountriesAsList to use with your default var.


How can I convert text into a URL-friendly string? If I want to convert text into a URL friendly string for sharing text in a social media link, how would I go about that?

I was about to ask this question, but realized that it's closely related to this question.

The answer, like in the above referenced question lies with Twig filters.

Specifically, in this case, one needs to use the url_encode filter to convert the text needed.

Example

<a href="http://www.linkedin.com/shareArticle?mini=true&url={{ entry.url|url_encode }}&title={{ entry.title|url_encode }}&source=Xavier%20Creative%20House&summary={{ entry.question|url_encode|striptags }}" target="_blank">

In any case, I hope that helps others with this. I know how easy it is to forget that the answers sometimes like over in the Twig docs, and not Craft’s.


Use twig's {% spaceless %} tag only under certain conditions Is there a way to use Twig's {% spaceless %} tag only under certain conditions?

For example, say you wanted the HTML to be spaceless in the live environment but wanted it uncompressed in the dev environment. I tried something like:

{% if isDev %}
    {% spaceless %}
{% endif %}
{# Some code... #}
{% if isDev %}
    {% endspaceless %}
{% endif %}

But this just throws a Twig error.

You could do it by buffering your output, i.e.

{% set output %}
{# Your code here #}
{% endset %}

{% if isDev %}
     {{ output }}
{% else %}
    {% spaceless %}
        {{ output }}
    {% endspaceless %}
{% endif %}


Customize activation and other system emails Just as the title indicates, I'm looking for a way to customize the email template of the "click here to activate your account" email that is sent to users when they register. I would also like to know if its possible and how to do this with other system email templates, such as the reset password link email.

Edit:
I see you can edit the plain text emails at Settings > Email > Messages however I would like to be able to define a twig template to handle creating HTML versions of these.

Actually Brad, I was able to figure out a way to do this with some help from @carlcs in the slack channel.

I defined an "HTML Template" in the main email settings screen, then in that template I extend a basic HTML email wrapper, then inside my content block I did this:

{% if emailKey == 'account_activation' %}
    {% include 'mail/activation' %}
{% endif %}
{% if emailKey == 'forgot_password' %}
    {% include 'mail/forgot-password' %}
{% endif %}
{% if emailKey == 'test_email' %}
    {% include 'mail/test-email' %}
{% endif %}
{% if emailKey == 'verify_new_email' %}
    {% include 'mail/verify-new-email' %}
{% endif %}

Then I just created HTML versions of each email within the context of my wrapper.

It works perfectly!


Check if file exists I have a simple rss feed in my Templates directory, appropriately named "feed.rss". I'm trying to create a link to that file but I don't want that to show up if the file doesn't exist. How might be the best way to only show the link, if the file exists?

I don't think it's possible to do with out-of-the-box Twig/Craft, but it's a super-easy plugin to write.

All you'd need is to give your plugin a Template Variable so that you could do:

{% if craft.myAwesomePlugin.fileExists('somePath') %}
    YES
{% endif %}

And your MyAwesomePluginVariable class has a method like:

public function fileExists($path)
{
    return IOHelper::fileExists($path);
}


Display list of countries in form using a dropdown So I'm using this territories plugin to display a list of countries in a dropdown. The issue I'm having is showing these countries within my front-end entry form.

I've used this example but it doesn't work:

{% for option in entry.territoryFieldHandle.options %}

{{ option }}

{% endfor %}

Here's my whole form. The other dropdowns work fine.

             {% set jobTypeDropdown = craft.fields.getFieldbyHandle('jobType') %}
        Job Type
        <select name="fields[jobType]">
            {% for option in jobTypeDropdown.settings.options %}
                <option value="{{ option.value }}">{{ option.label }}</option>
            {% endfor %}
        </select>

        {% set jobCategoryDropdown = craft.fields.getFieldbyHandle('jobCategory') %}
        Job Category
        <select name="fields[jobCategory]">
            {% for option in jobCategoryDropdown.settings.options %}
                <option value="{{ option.value }}">{{ option.label }}</option>
            {% endfor %}
        </select>

        Country
        <select name="fields[country]">
            {% for option in entry.country.options %}
                <option value="{{ option }}">{{ option }}</option>
            {% endfor %}
        </select>

This is not the answer you were looking for, but if you decide to just go with a normal drop-down, then you can paste the following into the dropdown field in the database. This would go in the craft_fields table, yourCountryField row, settings column. After editing the list the way you need it I would suggest removing all line-breaks using grep find/replace ('\n', ''), but it may not matter either.

{"options":[
{"label":"Afghanistan","value":"AF","default":""},
{"label":"Aland Islands","value":"AX","default":""},
{"label":"Albania","value":"AL","default":""},
{"label":"Algeria","value":"DZ","default":""},
{"label":"American Samoa","value":"AS","default":""},
{"label":"Andorra","value":"AD","default":""},
{"label":"Angola","value":"AO","default":""},
{"label":"Anguilla","value":"AI","default":""},
{"label":"Antarctica","value":"AQ","default":""},
{"label":"Antigua and Barbuda","value":"AG","default":""},
{"label":"Argentina","value":"AR","default":""},
{"label":"Armenia","value":"AM","default":""},
{"label":"Aruba","value":"AW","default":""},
{"label":"Australia","value":"AU","default":""},
{"label":"Austria","value":"AT","default":""},
{"label":"Azerbaijan","value":"AZ","default":""},
{"label":"Bahamas","value":"BS","default":""},
{"label":"Bahrain","value":"BH","default":""},
{"label":"Bangladesh","value":"BD","default":""},
{"label":"Barbados","value":"BB","default":""},
{"label":"Belarus","value":"BY","default":""},
{"label":"Belgium","value":"BE","default":""},
{"label":"Belize","value":"BZ","default":""},
{"label":"Benin","value":"BJ","default":""},
{"label":"Bermuda","value":"BM","default":""},
{"label":"Bhutan","value":"BT","default":""},
{"label":"Bolivia","value":"BO","default":""},
{"label":"Bosnia and Herzegovina","value":"BA","default":""},
{"label":"Botswana","value":"BW","default":""},
{"label":"Bouvet Island","value":"BV","default":""},
{"label":"Brazil","value":"BR","default":""},
{"label":"British Indian Ocean Territory","value":"IO","default":""},
{"label":"Brunei Darussalam","value":"BN","default":""},
{"label":"Bulgaria","value":"BG","default":""},
{"label":"Burkina Faso","value":"BF","default":""},
{"label":"Burundi","value":"BI","default":""},
{"label":"Cambodia","value":"KH","default":""},
{"label":"Cameroon","value":"CM","default":""},
{"label":"Canada","value":"CA","default":""},
{"label":"Cape Verde","value":"CV","default":""},
{"label":"Cayman Islands","value":"KY","default":""},
{"label":"Central African Republic","value":"CF","default":""},
{"label":"Chad","value":"TD","default":""},
{"label":"Chile","value":"CL","default":""},
{"label":"China","value":"CN","default":""},
{"label":"Christmas Island","value":"CX","default":""},
{"label":"Cocos (Keeling) Islands","value":"CC","default":""},
{"label":"Colombia","value":"CO","default":""},
{"label":"Comoros","value":"KM","default":""},
{"label":"Congo","value":"CG","default":""},
{"label":"Congo, The Democratic Republic of the","value":"CD","default":""},
{"label":"Cook Islands","value":"CK","default":""},
{"label":"Costa Rica","value":"CR","default":""},
{"label":"Cote D'Ivoire","value":"CI","default":""},
{"label":"Croatia","value":"HR","default":""},
{"label":"Cuba","value":"CU","default":""},
{"label":"Cyprus","value":"CY","default":""},
{"label":"Czech Republic","value":"CZ","default":""},
{"label":"Denmark","value":"DK","default":""},
{"label":"Djibouti","value":"DJ","default":""},
{"label":"Dominica","value":"DM","default":""},
{"label":"Dominican Republic","value":"DO","default":""},
{"label":"Ecuador","value":"EC","default":""},
{"label":"Egypt","value":"EG","default":""},
{"label":"El Salvador","value":"SV","default":""},
{"label":"Equatorial Guinea","value":"GQ","default":""},
{"label":"Eritrea","value":"ER","default":""},
{"label":"Estonia","value":"EE","default":""},
{"label":"Ethiopia","value":"ET","default":""},
{"label":"Falkland Islands (Malvinas)","value":"FK","default":""},
{"label":"Faroe Islands","value":"FO","default":""},
{"label":"Fiji","value":"FJ","default":""},
{"label":"Finland","value":"FI","default":""},
{"label":"France","value":"FR","default":""},
{"label":"French Guiana","value":"GF","default":""},
{"label":"French Polynesia","value":"PF","default":""},
{"label":"French Southern Territories","value":"TF","default":""},
{"label":"Gabon","value":"GA","default":""},
{"label":"Gambia","value":"GM","default":""},
{"label":"Georgia","value":"GE","default":""},
{"label":"Germany","value":"DE","default":""},
{"label":"Ghana","value":"GH","default":""},
{"label":"Gibraltar","value":"GI","default":""},
{"label":"Greece","value":"GR","default":""},
{"label":"Greenland","value":"GL","default":""},
{"label":"Grenada","value":"GD","default":""},
{"label":"Guadeloupe","value":"GP","default":""},
{"label":"Guam","value":"GU","default":""},
{"label":"Guatemala","value":"GT","default":""},
{"label":"Guernsey","value":"GG","default":""},
{"label":"Guinea","value":"GN","default":""},
{"label":"Guinea-Bissau","value":"GW","default":""},
{"label":"Guyana","value":"GY","default":""},
{"label":"Haiti","value":"HT","default":""},
{"label":"Heard Island and Mcdonald Islands","value":"HM","default":""},
{"label":"Holy See (Vatican City State)","value":"VA","default":""},
{"label":"Honduras","value":"HN","default":""},
{"label":"Hong Kong","value":"HK","default":""},
{"label":"Hungary","value":"HU","default":""},
{"label":"Iceland","value":"IS","default":""},
{"label":"India","value":"IN","default":""},
{"label":"Indonesia","value":"ID","default":""},
{"label":"Iran, Islamic Republic Of","value":"IR","default":""},
{"label":"Iraq","value":"IQ","default":""},
{"label":"Ireland","value":"IE","default":""},
{"label":"Isle of Man","value":"IM","default":""},
{"label":"Israel","value":"IL","default":""},
{"label":"Italy","value":"IT","default":""},
{"label":"Jamaica","value":"JM","default":""},
{"label":"Japan","value":"JP","default":""},
{"label":"Jersey","value":"JE","default":""},
{"label":"Jordan","value":"JO","default":""},
{"label":"Kazakhstan","value":"KZ","default":""},
{"label":"Kenya","value":"KE","default":""},
{"label":"Kiribati","value":"KI","default":""},
{"label":"Korea, Democratic People's Republic of","value":"KP","default":""},
{"label":"Korea, Republic of","value":"KR","default":""},
{"label":"Kuwait","value":"KW","default":""},
{"label":"Kyrgyzstan","value":"KG","default":""},
{"label":"Lao People's Democratic Republic","value":"LA","default":""},
{"label":"Latvia","value":"LV","default":""},
{"label":"Lebanon","value":"LB","default":""},
{"label":"Lesotho","value":"LS","default":""},
{"label":"Liberia","value":"LR","default":""},
{"label":"Libyan Arab Jamahiriya","value":"LY","default":""},
{"label":"Liechtenstein","value":"LI","default":""},
{"label":"Lithuania","value":"LT","default":""},
{"label":"Luxembourg","value":"LU","default":""},
{"label":"Macao","value":"MO","default":""},
{"label":"Macedonia, The Former Yugoslav Republic of","value":"MK","default":""},
{"label":"Madagascar","value":"MG","default":""},
{"label":"Malawi","value":"MW","default":""},
{"label":"Malaysia","value":"MY","default":""},
{"label":"Maldives","value":"MV","default":""},
{"label":"Mali","value":"ML","default":""},
{"label":"Malta","value":"MT","default":""},
{"label":"Marshall Islands","value":"MH","default":""},
{"label":"Martinique","value":"MQ","default":""},
{"label":"Mauritania","value":"MR","default":""},
{"label":"Mauritius","value":"MU","default":""},
{"label":"Mayotte","value":"YT","default":""},
{"label":"Mexico","value":"MX","default":""},
{"label":"Micronesia, Federated States of","value":"FM","default":""},
{"label":"Moldova, Republic of","value":"MD","default":""},
{"label":"Monaco","value":"MC","default":""},
{"label":"Mongolia","value":"MN","default":""},
{"label":"Montserrat","value":"MS","default":""},
{"label":"Morocco","value":"MA","default":""},
{"label":"Mozambique","value":"MZ","default":""},
{"label":"Myanmar","value":"MM","default":""},
{"label":"Namibia","value":"NA","default":""},
{"label":"Nauru","value":"NR","default":""},
{"label":"Nepal","value":"NP","default":""},
{"label":"Netherlands","value":"NL","default":""},
{"label":"Netherlands Antilles","value":"AN","default":""},
{"label":"New Caledonia","value":"NC","default":""},
{"label":"New Zealand","value":"NZ","default":""},
{"label":"Nicaragua","value":"NI","default":""},
{"label":"Niger","value":"NE","default":""},
{"label":"Nigeria","value":"NG","default":""},
{"label":"Niue","value":"NU","default":""},
{"label":"Norfolk Island","value":"NF","default":""},
{"label":"Northern Mariana Islands","value":"MP","default":""},
{"label":"Norway","value":"NO","default":""},
{"label":"Oman","value":"OM","default":""},
{"label":"Pakistan","value":"PK","default":""},
{"label":"Palau","value":"PW","default":""},
{"label":"Palestinian Territory, Occupied","value":"PS","default":""},
{"label":"Panama","value":"PA","default":""},
{"label":"Papua New Guinea","value":"PG","default":""},
{"label":"Paraguay","value":"PY","default":""},
{"label":"Peru","value":"PE","default":""},
{"label":"Philippines","value":"PH","default":""},
{"label":"Pitcairn","value":"PN","default":""},
{"label":"Poland","value":"PL","default":""},
{"label":"Portugal","value":"PT","default":""},
{"label":"Puerto Rico","value":"PR","default":""},
{"label":"Qatar","value":"QA","default":""},
{"label":"Reunion","value":"RE","default":""},
{"label":"Romania","value":"RO","default":""},
{"label":"Russian Federation","value":"RU","default":""},
{"label":"Rwanda","value":"RW","default":""},
{"label":"Saint Helena","value":"SH","default":""},
{"label":"Saint Kitts and Nevis","value":"KN","default":""},
{"label":"Saint Lucia","value":"LC","default":""},
{"label":"Saint Pierre and Miquelon","value":"PM","default":""},
{"label":"Saint Vincent and the Grenadines","value":"VC","default":""},
{"label":"Samoa","value":"WS","default":""},
{"label":"San Marino","value":"SM","default":""},
{"label":"Sao Tome and Principe","value":"ST","default":""},
{"label":"Saudi Arabia","value":"SA","default":""},
{"label":"Senegal","value":"SN","default":""},
{"label":"Serbia and Montenegro","value":"CS","default":""},
{"label":"Seychelles","value":"SC","default":""},
{"label":"Sierra Leone","value":"SL","default":""},
{"label":"Singapore","value":"SG","default":""},
{"label":"Slovakia","value":"SK","default":""},
{"label":"Slovenia","value":"SI","default":""},
{"label":"Solomon Islands","value":"SB","default":""},
{"label":"Somalia","value":"SO","default":""},
{"label":"South Africa","value":"ZA","default":""},
{"label":"South Georgia and the South Sandwich Islands","value":"GS","default":""},
{"label":"Spain","value":"ES","default":""},
{"label":"Sri Lanka","value":"LK","default":""},
{"label":"Sudan","value":"SD","default":""},
{"label":"Suriname","value":"SR","default":""},
{"label":"Svalbard and Jan Mayen","value":"SJ","default":""},
{"label":"Swaziland","value":"SZ","default":""},
{"label":"Sweden","value":"SE","default":""},
{"label":"Switzerland","value":"CH","default":""},
{"label":"Syrian Arab Republic","value":"SY","default":""},
{"label":"Taiwan, Province of China","value":"TW","default":""},
{"label":"Tajikistan","value":"TJ","default":""},
{"label":"Tanzania, United Republic of","value":"TZ","default":""},
{"label":"Thailand","value":"TH","default":""},
{"label":"Timor-Leste","value":"TL","default":""},
{"label":"Togo","value":"TG","default":""},
{"label":"Tokelau","value":"TK","default":""},
{"label":"Tonga","value":"TO","default":""},
{"label":"Trinidad and Tobago","value":"TT","default":""},
{"label":"Tunisia","value":"TN","default":""},
{"label":"Turkey","value":"TR","default":""},
{"label":"Turkmenistan","value":"TM","default":""},
{"label":"Turks and Caicos Islands","value":"TC","default":""},
{"label":"Tuvalu","value":"TV","default":""},
{"label":"Uganda","value":"UG","default":""},
{"label":"Ukraine","value":"UA","default":""},
{"label":"United Arab Emirates","value":"AE","default":""},
{"label":"United Kingdom","value":"GB","default":""},
{"label":"United States","value":"US","default":""},
{"label":"United States Minor Outlying Islands","value":"UM","default":""},
{"label":"Uruguay","value":"UY","default":""},
{"label":"Uzbekistan","value":"UZ","default":""},
{"label":"Vanuatu","value":"VU","default":""},
{"label":"Venezuela","value":"VE","default":""},
{"label":"Viet Nam","value":"VN","default":""},
{"label":"Virgin Islands, British","value":"VG","default":""},
{"label":"Virgin Islands, U.S.","value":"VI","default":""},
{"label":"Wallis and Futuna","value":"WF","default":""},
{"label":"Western Sahara","value":"EH","default":""},
{"label":"Yemen","value":"YE","default":""},
{"label":"Zambia","value":"ZM","default":""},
{"label":"Zimbabwe","value":"ZW","default":""}
]}


Monthly subscription with Stripe using iDEAL Does anybody know if I can use Stripe to facilitate subscription payments using iDEAL (Dutch payment method). For instance using the Charge plugin or Sprout Commerce? Thanks in advance.

Have you tried having a look at the API Docs for Stripe? They have written about ideal integration:

https://stripe.com/docs/sources/ideal

If its in your budget you should probably also have a look at Craft commerce which has partial Mollie integration which should, in turn, facilitate the iDeal payments solution that you are looking for. Though they do say it is only partially supported so you may need to investigate if this is exactly what you are looking for.


Event or hook when user account email validated Is there an event or hook we can leverage after a user verifies their email address? It looks like this is handled in UsersController::actionVerifyEmail() which calls $this->_onAfterActivateUser which calls $this->_redirectUserAfterAccountActivation. The specific users being created will not have CP access, so they will be redirected to craft()->config->getLocalized('activateAccountSuccessPath') in that method.

I would like to be able to set a flash message to confirm the email verification and informing them they need to log in to access all of the site, but I don't see any events or hooks to tie into. Any suggestions?

There currently aren't any verification events, but if the user is in a pending state (i.e. they haven't been activated yet), verification will trigger activation, which triggers the onBeforeActivateUser and onActivateUser events.


Duplicate a Structure "Section" I have a Structure area where there will be 20-24 top level pages for degrees, each with similar (but different) subpages…

Masters in Accountancy

Courses by Year
Degree Requirements
…etc. x12 or so.

Masters in Business Administration

Courses by Semester
Degree Requirements
…etc. x12 or so.

…etc.

It would be super ideal (and save a lot of time) is if I could setup the tree for just on of the degrees, then duplicate it 20 times and use it as a starting point for the others degrees. Has anybody managed to pull something like this off? Guessing I'd have to do it directly in the DB?

(I should mention that because of the variety/flexibility in content around each degree, having a degree channel isn't a good fit for this case. In total, it's much more like a docs section.)

I tend to try hard to avoid making changes directly to the DB if at all possible. It's a good feature idea that isn't built into Craft, so I think a custom plugin might be a good option. It'd be easy enough to build and then you'd have it readily available for other projects in the future.


Running Craft Console Commands on Webfaction I'm trying to run a few of Craft's console commands on a Webfaction server to automate running Craft migrations and resolving Project Config changes, and it's throwing an error.
Here's what I'm doing:
php craft migrate/all
php craft project-config/sync

Turns out this was a problem with running the right version of PHP. I was able to fix the issue by changing my command from php to php74, directly specifying the version of PHP that I want to run. This should work with php71 php73 and future versions like php80 too.
Here's what my commands look like now:
php74 craft migrate/all
php74 craft project-config/sync


front end date field format doesn't work? fields[dateField][date] There are a number of answers on this forum for getting a front-end form to have a DateTime field that splits date and time into separate fields; It's not working for me.

If I strip back to absolute basics - hardcoded, as a test:

<input type="hidden" id="endDate" name="fields[endDate]" value="2017-12-30 02:15:00" />

Works, and a date & time is stored in the back-end field, displaying correctly.

But, if I try to split it so the date and time fields are separate (so that I can use a date picker on one and a select drop down on the other) - it doesn't save a value into the field. Even stripped back to hard-coded hidden fields...

<input type="hidden" id="endDate" name="fields[endDate][date]" value="2017-12-30" />

<input type="hidden" id="endTime" name="fields[endDate][time]" value="02:15:00" />

What am I doing wrong? The is the same format that works in the Craft back-end...

I suspect it might be your values. Try testing with this hard coded in and see if it works:

<input type="hidden" id="endDate" name="fields[endDate][date]" value="12/30/2017" />
<input type="hidden" id="endTime" name="fields[endDate][time]" value="2:15 AM" />

I always reference what's on this StraightUpCraft guide, and I try to be as exact as possible to the examples. You can also just inspect date fields inside a saved entry in the CMS to see what the values look like and mimic that on the front end.


How to Access the Twig Attribute Name from the Fieldtype Class I want to be able to output different values for my fieldtype depending on the twig attribute. So {{ entry.myField }} would output AK by default, but {{ entry.myField.label }} would output Alaska. Currently I'm using the normalizeValue() method to handle all this, but I need to know which attribute (if any) is being called by the twig template. How do I get that information?

A very basic example of what I'm thinking of would be:

public function normalizeValue($value, ElementInterface $element = null)
{
    $states = array(
        'AK' => 'Alaska',
        'AL' => 'Alabama'
    );

    if( twig.attribute == 'label' )
    {
        return $states[$value];
    }
    else
    {
        return $value;
    }
}

Robin's answer is technically correct but I wanted to add a little more detail on how I got it working.

TL;DR

public function normalizeValue($value, ElementInterface $element = null)
{
    if ( $value instanceof SingleOptionFieldData )
    {
        return $value;
    }

    $nakedOpts = array
    (
        "AL" => "Alabama",
        "AK" => "Alaska",
        "AS" => "American Samoa",
        "AZ" => "Arizona",
        "AR" => "Arkansas"
    );

    foreach( $nakedOpts as $optval => $label )
    {
        $isSelected = ($value == $optval) ? true : false;
        $this->options[] = new OptionData($label, $optval, $isSelected);
    }

    if( !empty($value) )
    {
        $value = new SingleOptionFieldData($nakedOpts[$value], $value, true);
        $value->setOptions($this->options);
    }

    return $value;
}

Full Explanation

I ended up using Craft's native OptionData and SingleOptionFieldData classes to convert my values and options into objects that Craft knows how to work with.

So to start with I added these declarations at the top of my fieldtype file:

use craft\fields\data\OptionData;
use craft\fields\data\SingleOptionFieldData;

Now in your fieldtype file you need to do two things:

Convert your options to an array of OptionData objects
Convert the $value to a SingleOptionFieldData object

So we need to take our "naked" option array (our array of US states) and convert it to an array of objects, and we also need to mark which of the options is our selected value. The OptionData object accepts 3 parameters: $label, $value, and $selected:

$nakedOpts = array
(
    "AL" => "Alabama",
    "AK" => "Alaska",
    "AS" => "American Samoa",
    "AZ" => "Arizona",
    "AR" => "Arkansas"
);

foreach( $nakedOpts as $optval => $label )
{
    // is this array item the selected value?
    $isSelected = ($value == $optval) ? true : false;
    // create a new object for each item
    $this->options[] = new OptionData($label, $optval, $isSelected);
}

So now we need to convert our field $value to an object so Craft can compare it to the objects in the options list. Again, SingleOptionFieldData accepts the parameters of $label, $value, and $selected:

$value = new SingleOptionFieldData($nakedOpts[$value], $value, true);

The normalizeValue() method gets called once when the field is loaded on the publish page, and again when the entry is saved. So you have to check if you've already converted the $value to an object and bypass the rest of the code if so:

if ( $value instanceof SingleOptionFieldData )
{
    return $value;
}

The advantage of using a Craft object for this instead of a regular array is that Craft already knows how to use this type of data in the template. So the tag {{ entry.region }} will output AK without having to add the .value attribute. And just like a native Craft dropdown field, you can get the label with {{ entry.region.label }}.

To loop through all of your options in the template, just add this to normalizeValue() after you've converted the $value to an object and created your list of option objects:

$value->setOptions($this->options);

Now you can output a list of your options in your template:

{% for option in entry.region.options %}
    <option value="{{ option }}"{% if option.selected %} selected{% endif %}>{{ option.label }}</option>
{% endfor %}


Is there a way to get categories relating to a specific entry within a plugin? When I get an Entry Object that has been set, I notice all of my fields except the Category fields are available to me. For example:

[_behaviors:yii\base\Component:private] => Array
    (
        [customFields] => craft\behaviors\ContentBehavior Object
            (
                [adjustedRemainingLife] => 100%
                [adjustedRemainingYears] => 116
                [answerSets] => [{"col3":"Paving and curbs are less than 3 years old, and in good condition. No repairs are needed, preventative maintenance ","col1":"Paving and curbs are in good condition, and only require routine maintenance - 90%","col2":"Minor repairs and patching are required, not exceeding 30% of value -\r\n60%","col4":"Significant repairs are needed to as much as 60% of value. - 30%","col5":"All or majority of systems should be replaced - 0%"}]
                [groundsQuestions] =>

Where groundsQuestions is my category field, I figure if it isn't flowing through, there must be some way to get that value in a plugin?

Since groundsQuestions is a category field, calling it will return an element query on which you can call one(), all(), etc.

For example:

$groundsQuestions = $entry->groundsQuestions->all();


Can a user edit another user So I'm setting up a system with 3 tiers of users.

Admin
Officers
Managers

I want Officers to be able to administer managers. Any of you know if this is doable?

So let's say an Officer could login (not in the CP) and view a list of its managers and change let's say, their password...

Any light on this would be great :)

You can do what you're looking for with some caveats from the front-end of a site.

If officers have the editUsers permissions, then they can edit most other things about other users.

The two exceptions are their email address, which requires the changeUserEmails permission and the password, which they can't change at all.  The only person that can change the password is the user it belongs to.


Craft Commerce — Update order status from frontend? Following on from this question Commerce: How to update an order status via the frontend
We'd like to make it easy for delivery drivers to update the status of a craft commerce order, from a frontend page. Doing it via the CP on mobile is a bit cumbersome as it involves multiple steps.
We've created a user group call couriers.
{% extends '_layouts/_logistics' %}

{% block logistics %}
    {% if currentUser and currentUser.isInGroup('courier') %}
        {% include 'logistics/_orders' %}
    {% else %}
        {% redirect 'account' %}
    {% endif %}
{% endblock %}

In the _orders include we'd like to show a list of orders, each with a 'Mark as Delivered' button, which can be clicked as the orders are fullfilled.
<dl>
    {% if order.shippingAddress %}
        {% include 'shop/_includes/addresses/address' with { address: order.shippingAddress } %}
    {% endif %}
    <dt>{{ order.reference }}</dt>
</dl>
<form method="POST">
    <input type="hidden" name="action" value="">
    {{ redirectInput('logistics') }}
    {{ csrfInput() }}
    <input type="hidden" name="orderStatusId" value="4">
    <input class="button button--primary" type="submit" value='Mark as Delivered'>
</form>

I'm wondering if this can be done, without the need to build a plugin or module? Else is there a plan to include the ability to do this in a future Craft Commerce release.
Many thanks,
Andrew

This feels a bit dirty, but you can actually do this directly in a Twig template like this:
{% set order = craft.orders.id(123).one() %}
{% do order.setAttributes({orderStatusId: 4}, false) %}
{% do craft.app.getElements().saveElement(order) %}

-- naturally you'd need a way to fetch which order you want to update, but you could easily grab that from your POST data or from the URL or localStorage or whatever.


Number field when empty and value=0 Is there a way to differentiate the number field value empty and 0?

I would like to display this field only when there's a value in the field even though the value is 0.

But when I input 0 into the field, it seems that Craft thinks the value is empty... so doesn't still display the field.

Thanks.

Twig's is not null should work for this.  Assuming you have a Number field called number and you're looping through a list of entries, something like this should work:

{% for entry in entries if entry.number is not null %}
    {{ entry.number }}
{% endfor %}


How do I access the properties of an object which triggered an event? I'm trying my first plug-in; it's to automatically create an entry in a section when a user belonging to a specific user group is activated. However I'm not that hot at PHP and I can't figure out how I would check that the user being activated belongs to a given user group. Here's my basic code from in the main plugin file's init() function:

public function init() {
    craft()->on('users.onActivateUser', function(Event $event) {
        // check the user being activated belongs to the user group 'artist'
        // ???

        // now save an entry on their behalf
        $entry = new EntryModel();
        ...

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

        if (!$success)
        {
            Craft::log('Couldn’t save the entry "'.$entry->title.'"', LogLevel::Error);
        }
    }
}

Within the context of that event, you will have access to:

$event->params['user']

... which is:

  A UserModel instance representing the user that has just been activated.

Once you've got your user model, you can do something like this:

$event->params['user']->isInGroup('artists')

On a separate note, I believe the correct syntax is:

craft()->on('users.activateUser' ...

You can ditch the "on" in onActivateUser. Check out the official example...


live and pending entries together not working Craft 3.0.37

I have the following code which I expect to output all entries (live and pending) but it doesn't

  {% for entry in craft.entries.section('podcast').status('live','pending').relatedTo(season).orderBy('postDate', 'asc').all() %}

{{ entry.episodeNumber }}  {{ entry.title }}

  {% endfor %}

If I change the status to only pending it outputs pending entries, if live, outputs live. However it will not output both pending and live.

Please advise.

Use status(['live','pending']) to get all entries with both states.

Later, to get the linked entry you need to setup a custom route like `podcasts/{slug}. In the template you query the entry like this:

{% set slug = craft.request.lastSegment() %}
{% set entry = craft.entries.slug(slug).status(['live', 'pending']).one() %}


Allow user to change or delete their photo for their profile from the front end How can I allow a user to change or delete their photo for their profile from the front end?

I currently have a form setup for the user to edit their profile but I want to load their current photo (or a default) and then allow them to change it or delete it.

Before you can allow a user to manage their profile photo in your front-end profile edit form, be sure to update your form tag with the enctype="multipart/form-data" parameter:

<form method="post" enctype="multipart/form-data">

You can access a users profile photo using the currentUser global and fallback to a different image like so:

{% if currentUser.photoUrl %}

{% else %}

{% endif %}

The upload and manage part becomes a bit trickier.  Setting up a basic use case is fairly straightforward but if you want to begin giving the user a better UI and more feedback as to the status of the uploaded image, you'll have to get into some css and javascript.

For example, when you delete a photo you might want to swap in the fallback image.  When an image is uploaded, you may want to display the image instead of just the filename for the user. Before a user has uploaded an image, you probably don't want to display the delete button.

I'm not going to go into those items here, but here's one approach to get you started with the functionality:

{# Check to see if the user has a photo  #}
{% if currentUser.photoUrl %}

    {# If a photo exists, give the option to change the user photo #}
    <input type="file" name="userPhoto" value="Change Photo">

{% else %}

    {# If no photo exists, give the option to upload a new one #}
    <input type="file" name="userPhoto" value="Upload">

{% endif %}

If you want to be more brief, you can do the same using a ternary operator:

<input type="file" name="userPhoto" value="{{ (currentUser.photoUrl ? 'Change Photo' : 'Upload') }}">

In  both cases, at different points in the process, you may want to give the user an option to remove their photo. To delete a photo, you can pass any value to an input field called deleteUserPhoto.

{# Setup a delete action (see javascript snippet below) #}
Delete

{# Setup a hidden deleteUserPhoto field with no value #}
<input type="hidden" name="deleteUserPhoto" id="deleteUserPhotoInput" value="">

When a user clicks the delete button you want to update the deleteUserPhoto input field to have a value.  Any value works.  Here's an example using jQuery:

(function() {

    // Bind an action to the deleteUserPhotoAction click event
    $("#deleteUserPhotoAction").on('click', function() {

        // Add the value 'zap' to the deleteUserPhoto input
        document.getElementById("deleteUserPhotoInput").value = 'zap';

    });

})();


Images from tumblr post I successfully imported my tumblr blog with the amazing Feedme plugin over the rss feed of the blog. The plugin creates posts and feeds the "title", "date", "tag" and of course the "content" inside my craft and I can assign a field to each of those elements.

Here is the thing: The images in tumblr are included in the content. Feedme isnt able to crawl for img tags and make an asset out of it in craft. So the images are still on tumblr and are just linked in the html:

für Hotels und Gastronomie.

Does anyone have an idea how I can get the first image in my template? the prettiest solution would be of course if I find a way to make it an asset. But if not, it would be nice if I could crawl the html content for img tags and get the link to the image on the tumblr server......

I know this is of course not an elegant solution, but it works for now. I used twig filters to extract url and alt tag of the image.

            {% if entry.featuredImage|length %}
                {{ snippets.image( entry.featuredImage.first(),entry.url )}}
            {% else %} {# For the tumblr imports, extract first image #}
                {# Extract the src #}
                {% set spliter = entry.articleBody.type('text').first().text|split('src="') %}
                {% set spliter = spliter[1]|split('"') %}
                {% set firstTumblrImage = spliter[0] %}

                {# Extract the alt-Tag of the Featured Image#}
                {% set spliter = entry.articleBody.type('text').first().text|split('alt="') %}
                {% set spliter = spliter[1]|split('"') %}
                {% set imageAltTag = spliter[0] %}

            {% endif %}


Set duration of 'newpassword' link validity via config/general? Is it possible to modify how long the 'newpassword' links are valid for via a setting in config/general.php?
(I've found defaultTokenDuration but it sounds like this might only be for the live preview tokens?)

The setting you're looking for is verificationCodeDuration which defaults to 24 hours (86400 seconds).
https://docs.craftcms.com/api/v3/craft-config-generalconfig.html#verificationcodeduration
(And see craft\helpers\ConfigHelper::durationInSeconds() for a list of supported value types)


Overriding Craft Commerce config files Is there a way to override the Craft Commerce config files ?

I'm specifically talking about this one, deep inside the plugin craft/plugins/commerce/etc/currencies.php

I'd like to change the default amount of decimals for Euros

For that particular file, the answer is no... not without hacking the core Commerce plugin file, which we don't recommend.

If you think there's a bug in the file, send an email to support@craftcommerce.com.  If you'd like to create a feature request to open up that file so it is configurable, you can do that here.


Language link not working for me I've tried the LanguageLink and the last solution described here: How can I build a language switcher? but it never returns any URI. I'm not using translated slugs.

As setup I've used: http://buildwithcraft.com/docs/localization-guide. The language dropdown is part of top.html which I've included in each page

Things I have checked:

/config/general.php and that looks fine
index.php in public_html/stagingtest/ (for english) and public_html/stagingtest/es/ and public_html/stagingtest/nl/ and appears to be ok
when I go to www.example.com/stagingtest/es/report/ its loading fine. craft.locale appears to be ok, but the language uri's are still blank. I can see siteUrl is displaying the correct uri.

Any suggestions?

I have accidentally add "return array.." two times in my config/general.php file. I removed one and its working fine now.


High volume category list causes slow load My customer has 3500 categories in a 3 level hierarchy. This is causing some significant pain when adding categories to an entry. The server delivers the categories via ajax in 9sec, but the browser then takes 3-5 minutes to push the html segment into the modal dialog.

Is there any way to handle this a little more efficiently? I need to be able to select from any of the 3500 categories, but would love to limit the initial display to only the top one or two levels of the hierarchy.

This is a known issue with category and structured section UI in the control panel.

Performance actually starts degrading around the 3-400 item mark, but it will be addressed in the upcoming 2.2 release.


craft.commerce.products.ids() possible bug? I'm using the following code on a category listing page to list the sub-categories that contain products:

{% set entryIds = craft.commerce.products.ids() %}
{% if category is defined %}
    {% set currentCategory = craft.request.getSegment(2) %}
    {% set categories = craft.categories.descendantOf(category).relatedTo({ sourceElement: entryIds }).groupId(1).order('title asc').find() %}
{% else %}
    {% set categories = craft.categories.relatedTo({ sourceElement: entryIds }).groupId(1).level(1).order('title asc').find() %}
{% endif %}

What I'm experiencing is that craft.commerce.products.ids() only returns the ids for products that have a Post Date in the current month. This is not ideal since some products might've been added months ago but still remain active on the site.

Is this normal behaviour for craft.commerce.products.ids() or is this a possible bug ? Any ideas on a workaround ?

Are you sure you're not simply hitting the default limit which is 100?

Try this

{% set entryIds = craft.commerce.products({limit: null}).ids() %}


Feed Me: Importing a relationship between elements I want to import a bunch of films, which all have certain genres. The genres have already been set up as Categories in Craft, so each genre already has an Element ID (if that's relevant).

Here's a glance at my JSON feed...

{
    'title': "Epic Film",
    'genre': "action adventure"
},
{
    'title': "Sappy Love Story",
    'genre': "romance"
}

Unfortunately, that doesn't seem to work. I keep getting the following error:

  Genre cannot be blank.

How do I format data in a JSON field, to ensure that it's treated as a relationship between two elements?

Have you set the type of data you're providing for the category field? Each element field allows you to state what attribute the data you're trying to import. Title, ID or slug, which are shown in a small dropdown field on the feed mapping page.

Can you check this?


Check if current page is the homepage I'm trying to run a check within my _layout.html' to remove the navigation bar if the user is on the homepage. I've tried with the following code below, but browsing to a page which is theindex.html` of a Channel breaks the code with the following error:

  Variable "entry" does not exist.

This is the code within my _layout.html

{% set handle = entry.section.handle %}
{% if handle == 'homepage' %}
{% else %}
  {% if not craft.app.user.isGuest %}
      {% set users = craft.users %}
      {% include '_navigation'%}
    {% else %}
  {% endif %}
{% endif %}

I'd rather:

{% if entry.uri == "__home__" %}

{% endif %}


Authorize.net not connecting in Craft Commerce? I'm very lost with the gateway. It seems that Authorize.net is highly supported with Craft Commerce but the gateway isn't working. I had the dummy gateway working perfectly fine so that when I'd go through the whole processes and the order would show up. I put in authorize.net AIM as a new gateway and now when I get to the payment it does nothing at all. I put in this code

{% if craft.config.devMode and (craft.session.hasFlash('notice') or craft.session.hasFlash('error')) %}

  {% set noticeFlash = craft.session.getFlash('notice')|join('|') %}
  {% set errorFlash = craft.session.getFlash('error')|join('|') %}

    Notice: [{{  noticeFlash }}]
    Error: [{{  errorFlash }}]

 {% endif %}

and I get back

  Error: [Payment method does not exist or is not allowed.]

I've put in the API user and key and the link at the bottom. Am I supposed to set the gateway as default somewhere?

That error is from the cart service when trying to set the payment method ID on the cart during payment.

There are 2 possible reasons the error would appear:

1) The payment ID you are submitting is wrong

<input type="hidden" name="paymentMethodId" value="theIDhere"/>

2) In the settings (for a correctly submitted payment ID), the "Enabled to select on front-end" setting has been turned off. Screenshot: http://jmp.sh/AxoM1tI You need this on, to allow customers to use the method on checkout.

Hope that helps.


Is it possible to break out of a loop in twig? Is it possible to break out of a loop in twig? If it is, how would I do it?

Currently there is no special build-in command to do it (unless you want to use a plugin, as stated by Brandon Kelly). There is a workaround, however. The workaround is to check for additional condition.

{% set break = 0 %}

{# this variable we will set to 1 when we do not want code in our loop to run anymore #}

{% for i in 20..100 if break == 0 %}
    ...
    {# on some condition we will set break to 1 to prevent running of further code #}
    {% set break = 1 %}
    ...
{% endfor %}


Less complicated local development w/Craft 3, is it possible? I do not really care for WordPress, but one thing that it has going for is a dead simple local development environment. In fact, it free software called "Local". It took all of five minutes to get running.

Meanwhile, it took several hours to do a basic set up of Vagrant on Windows, configure Craft to run locally, and then there was various back and forth over obscure server issues until I could finally get it to work. And when it did, the control panel ran rather slowly. I gave up and went back to mapping an FTP connection as a network drive, and just working on files locally, saving them, and then hitting the live site.

I recognize these are different programs, but is there any way to set up Craft for local development that doesn't require an advanced degree in Apache/Vagrant/Docker/whatever the flavor of the month is?

I don't really care if I'm using WAMP, Docker, or whatever, but I would like to find something that is straightforward, with repeatable results, so the next time I have to spin up an install, I don't have to remember 50 steps to do so.

And yes, I am sticking to Windows 10.

Thanks in advance.

If you're used to Local you can also use that for Craft.

Here's 2 articles to get you started:

https://medium.com/@madebyraygun/a-quick-and-easy-local-environment-for-craft-3-4fd7c7ff5815

and

https://www.tyssendesign.com.au/articles/craft/using-local-by-flywheel-with-other-cms/

I'm also hearing good things about https://ddev.readthedocs.io/en/stable/
but haven't tried that one myself.

And it looks like Pixel and Tonic have developed something of their own: Craft Nitro

https://craftcms.com/blog/craft-nitro


Can Matrix fields be added/shown on the entries listing of the control panel? Is it possible to add a related matrix field and show the first entry in that field on the http://domain.com/admin/entries section of the control panel?

That's not possible, Matrix blocks (and also Tags) don't have an element index view in the CP.

You could write a plugin that adds such a page to the CP. It would list all the Matrix blocks that meet your requirements (owner ID, owner entry, ...).

Another idea would be to just use an Entries field instead; the entries section you'd set up for the field comes with an index view for free.


Why I can't upload a favicon.ico as an Asset? I'm unable to upload the favicon.ico thought Craft because it says:

Upload failed for favicon.ico. The error message was: ”Error uploading the file: This file type is not allowed“

Why does that restriction exists? I just couldn't find a list of forbidden files.
Can I change that restriction?

I know I can use a FTP client to put the file in the folder, but since I'm doing this site for a friend I just wanted to leave her an easy way of managing the icon.

1) It's not allowed because it's currently not in the allowedFileExtensions config setting.

2) Just add 'ico' to the extraAllowedFileExtensions config setting and you'll be able to upload .ico file.


How to return a specific entry? Hopefully this is a simple question but I couldn't find a clear answer anywhere - I just want to be able to pull in data from a specific entry, where I know the identifier.

In this particular case, the entry is a single. Currently I'm doing this:

{% set entry = craft.entries.section('myChosenSection').first() %}

Is this correct, or is there a more concise way?

This is the correct way.
Examples:
Singles:
{% set entry = craft.entries.section('section_handle').one() %}

Channels / Structures:
{% set entry = craft.entries.section('section_handle').slug('my_slug').one() %}

General:
{% set entry = craft.entries.id(5).one() %}

See craft.entries for a list of all properties.


Make use of wrapping layouts in Craft I am a beginner when it comes to Craft and I have a hard time finding good detailed tutorials when it comes to specific questions. I know that Craft has it's own documentation but for me it's a little hard to find exactly what I want. So what I would like to know is how you can embed the header and the footer in every page with a simple tag.

I know that in Expression Engine all you had to do is was the following:

<html>
  <head>
    <title>News Site</title>
  </head>
  <body>
    {layout:contents}
  </body>
</html>

And on any other page you could add this tag and you were done.

{layout="site/.html-layout"}

{exp:channel:entries channel="news"}
  <h2>{title}</h2>
  {summary}
{/exp:channel:entries}

How can I achieve the same thing in Craft? Thank you for your time and help :)

Craft's uses the Twig templating language. The official Twig documentation http://twig.sensiolabs.org is really good, highly recommended to read most of it!

For your specific problem have a look at the section about the extends tag. It explains how to define blocks and extend other template files. Another important technique is including partials into a template with the include tag.

For a good and rather simple example I would recommend to read the source code of Pixel and Tonic's On The Rocks Craft demo page.