How to output entries related to a locale, IF a section is targeted to all locales? The documentation doesn't say much about it, only How to access it.

What I'm trying to achieve here?

Display entries only related to a locale.

I'll present it you with an example.

There are 3 targeted locales enabled in 3 sections. 1 entry in each section, created by 3 local users. So math says, that one locale has 3 entries, where the whole example.com has 9 entries together.

So, When I try to index entries on selected section I get that:

example.com/section1/ -> all entries from all locales are outputted, because entries are targeted in all locales of a section.
example.com/locale1/section1/ -> the same situation as with example.com/section1/, except with two differences, that entries's URL has /locale1/section1/{slug} and the locale is matched with active one.

I've looked into database, and all entries published are linked with each locale, even when Local User1 published to Local1 only. If that is gonna work, I don't know, if that will have any impact on storage efficiency.

Craft always outputs entries in one locale only. If you really want to list all entries in all of their enabled locales you would need to explicitly query for them using the locale parameter and then merge the results.

What probably confuses you is that Craft automatically clones an entry on the first save to all other locales. Try to edit an entry / disable it for one locale only and see the differences on you index pages!

If you really don't get the locale specific content for your different URL formats

example.com
example.com/locale1

there probably goes something wrong with your setup. The first thing I would check is the index.php files (→ Localization guide – Step 5: Set up the files)!


How to use alterColumn to change the values of an ENUM field in a DB Migration I need to add a value to my plugin database for an ENUM field but I am struggling to find the correct syntax for the alterColumn method.

I want to do this but with alterColumn if possible?

ALTER TABLE tableName CHANGE columnName columnName ENUM('existingOption1', 'existingOption2', 'newOption') DEFAULT NULL;

Cheers

Something like this should work:

$this->alterColumn('tableName', 'columnName', "enum('existingOption1','existingOption2','newOption') NULL");


Uncheck "Use this field’s values as search keywords?" by default? Is there a way to have the "Use this field’s values as search keywords?" option unchecked by default when creating a new field? Our searchindex table is getting bloated by data that doesn't need to be in there. I'm clearing it out now, but it would be really cool to have that checkbox be unchecked unless someone specifically wants it to be a keyword for search.

Thanks.

As of Craft 3.5, that setting will be disabled by default when creating new fields (see craftcms/cms#6390).


Getting the n-th entry in a structure I guess I could always loop through the structure but is there a simple way to directly get the n-th entry in a structure? (at a given level)
Something like:

{% set $fifth_listing = craft.entries.section('listing').level('1').pos('5') %}

You're close! This should work:

 {% set $fifth_listing = craft.entries.section('listing').level('1').nth(5) %}


How to loop through multiple entries fields I'm creating a dynamic side navigation where pages can choose which sidebar it wants to use. This is selected by an entries field called 'sidebar' - called in line 2.
To create this I've made a structure called 'Sidebars' with an entry for each sidebar type.
Each Sidebars entry has an entries field in it which can select any number of pages.
I've got it fully working, but it's giving me deprecation errors.
Here's the working (but deprecated code on line 4):
(lines 5-12 figure out whether the path includes 'whats-on' or 'who-we-are' and adds them to the path to the entry if needed).

  {% set sidebarChoice = entry.sidebar.one() %}
  {% for rel in sidebarChoice %}
    {% for sidebarEntry in rel %}
      {% set myEntryQueryUrl = sidebarEntry.url %}
      {% if 'whats-on' in myEntryQueryUrl %}
        {% set myEntryQueryPath = '/whats-on/' %}
      {% elseif 'who-we-are' in myEntryQueryUrl %}
        {% set myEntryQueryPath = '/who-we-are/' %}
      {% else %}
        {% set myEntryQueryPath = '/' %}
      {% endif %}

{{ sidebarEntry.title }}

{{ sidebarEntry.title }} text

    {% endfor %}
  {% endfor %}

You don't mention what your related entries field handle is, but remember that calling any related element (entries/assets/categories/users/tags) will require a .all() (or .one() or .ids() or one of the other query-executing methods) unless the related elements are eager-loaded. With that in mind I can't see anywhere in your code where you're executing a call to fetch the related entries from sidebarChoice, and you also seem to have a redundant inner loop. With eager-loading it might look like this:

  {% set sidebarChoice = entry.sidebar.with(['sidebar.yourRelatedEntriesHandle']).one() %}
  {% for sidebarEntry in sidebarChoice.yourRelatedEntriesHandle %}
      {% set myEntryQueryUrl = sidebarEntry.url %}
      {% if 'whats-on' in myEntryQueryUrl %}
        {% set myEntryQueryPath = '/whats-on/' %}
      {% elseif 'who-we-are' in myEntryQueryUrl %}
        {% set myEntryQueryPath = '/who-we-are/' %}
      {% else %}
        {% set myEntryQueryPath = '/' %}
      {% endif %}

{{ sidebarEntry.title }}

{{ sidebarEntry.title }} text

  {% endfor %}


I can't get Tags and Archive pages to appear Necessary disclaimer. Web design dilettante, so I ll probably have trouble following your answers if they get too technical.

I am building a blog. I am am trying to use tags bellow posts and when the user clicks on them, go on a page that shows all the relevant posts containing that tag.

I followed the instructions on this page and while I can get the tags bellow the blog post, when I click on them, I am getting a 404 page.

Similarly, I tried creating an archive page by following the instructions on this page but while I can get the code to appear if I append it at the end of my index.html page, I cannot get it to appear on a separate web page.

I suspect I am making a blindingly obvious mistake, but I can't figure out what. Do you have any suggestions of things to try?

Thanks

Sounds like you are missing a few tags, which we can fix when you post your code. Meanwhile, if you can spare the time, checkout Mijingo.com Craft Essentials, it's like being in the matrix as within one day you'll know lots about Craft!

It will safe you lots of time figuring out the basics....


How would you import content with embedded images, ideally using FeedMe? More of a general question rather than a specific issue I have right now. I want to migrate a site from a bespoke CMS, which relies heavily on CKEditor for embedding inline images into HTML content.

Obviously I'd like to import the html content, but somehow translate the embedded images into proper Craft asset uploads, embedded into a Redactor field (obviously I know that keeping images separate from text is fine, but that is a bigger issue than I'm prepared to deal with!).

Would love to know if anyone has done this before, and how they approached it. Extra points for doing it with FeedMe, which works very well for me.

There's nothing through Feed Me that handles this elegantly at the moment, and you'd need to either parse your html data before or after the import.

We've done this a few times on an import, where we've created a trivial PHP script which extracts images out of HTML content. Something like:

$html = '
Some text

More text
.';

// Start scraping!
$doc = new DOMDocument();
$doc->loadHTML($html);
$xpath = new DOMXPath($doc);

// Extract all  tags from our HTML content
foreach ($xpath->query('//img') as $key => $node) {

    // Save the image for later - just get the filename though
    $contentImages[] = $node->getAttribute('src');

    // Remove the 'img' tag from the content node
    $node->parentNode->removeChild($node);
}

// Store our parse HTML content (without img tags)
$content = $doc->saveHTML();

$json[] = array(
    'contentImages' => $contentImages,
    'content' => $content,
);

echo json_encode($json);

Normally this is because most scenarios go from a single WYSIWYG content block (looking at your Wordpress), to a Matrix content-builder field. In our cases, we like to create a Rich Text 'Content' block, and an 'Image' content block. As such, they're two different bits of data, and extracted out as above.

If you're wanting to keep your images in your Redactor fields, but have them hooked up to Craft's Assets - thats much more complicated. You'd need to upload the asset to Craft, get the ID from the uploaded asset, and replace the  tags in your content with a Redactor Asset placeholder.


Using Solspace Craft Calendar plugin, how can I get random events within a defined timeframe? I'm trying to achieve the following (without much luck), using Solspace Calendar plugin:

All events (no calendar specified)
A defined timeframe (one week)
Only unique events, that have at least 1 occurrence in that week, so no reoccurrences
In a random order
Limited to a specified number

I tried, without satisfying result:

{% set events = craft.calendar.events({
    dateRangeStart: now |date('Y-m-d'),
    dateRangeEnd: now |date_modify('+7 days') |date('Y-m-d'),
    order: 'RAND()',
    loadOccurrences: false,
    limit: 3,
}) %}

Any Calendar experts out there?

UPDATE: This issue has been fixed as of Calendar 1.8.4 on April 21, 2017.
https://solspace.com/craft/calendar

Your above code should work. I think there might be a bug with the loadOccurrences: false parameter used in conjunction with the limit: 3 parameter. Try increasing the limit to something higher and see if you get results. :)

In the meantime, I've logged this bug and we'll have a bug fix for this in the near future. Sorry for the inconvenience.


Auto-populate login form when accessed via client intranet My client has a private Craft site only accessible to their employees. To access the site they all use the same username and password on a front-end login form. They are now wanting to link to this site from their intranet and have the username and password form values auto-populated (only when accessed from the intranet). I have come up with a way using a Craft route (example.com/login/user/username/password/actualpassword) and craft.request.segment to auto-populate the form input values. This works but I was wondering if anyone else has a solution that doesn't require the password being in the URL.

Thanks!

Couldn't you set the password to a variable on the login page if it is the correct intranet url?

{% if craft.request.getUrl() == "intranet.net" %}
 {% set pass = "password" %}
{% endif %}

<input type="password" value="{{ pass|default('') }} name="password" />


Using Dynamic values in the Reply To field in Sprout Forms Notifications I'm looking to have a Dynamic 'Reply To' for a notification when an entry is saved from a form submissions.

I'm using the below which is what the field is named in my form, but it seems it's not allowed?

{email}

Ran into the same issue, asked the support team, and they confirmed it's a bug.

Workaround is to comment out this line:
https://github.com/barrelstrength/craft-sprout-base/blob/v2/src/app/email/elements/NotificationEmail.php#L481

Tried it and it works fine.

They said it would be fixed in an upcoming release.


Craft 3 Deprecation Error from Twig/Extension/Core.php. How to fix? I'm getting a deprecation error from not using .all() to query my elements:

Looping through element queries directly has been deprecated. Use the all() function to fetch the query results before looping over them.

This is usually very easy to fix because Craft normally tells you which template and line to add the .all() to.  However, when looking at the origin, I see:

/Users/Me/Sites/Project/vendor/twig/twig/lib/Twig/Extension/Core.php:577

This is pointing to something in Twig's vendor library, which I obviously don't want to fix for updating reasons.  Does anyone know what this is referring to in my templates?

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


Channel entry: Slug from field pattern? I have defined an entry for a channel, let's say of persons, to have some fields, let's say firstname, lastname and bio, but no title.

When I created the first real entry, craft complained it had no slug. Apparently, that's drawn from the title.

I expected I could define the structure of the entry's slug to be pulled from any field, like {firstname}-{lastname}.

But I didn't find that option in the backend. Am I looking in the wrong place?

Ah I found it: the option to enter the custom slug is displayed when you uncheck the Title.

And I set

    // don't accept umlauts for slugs
    'limitAutoSlugsToAscii' => true,

in the config.


How can I programmatically change the system's status? I have a console controller action that needs to change the site's status under certain conditions. I have not been able to find any documentation or even questions out there about how to do this. Is it even possible?

There are two existing console commands you can use, ./craft on and ./craft off (on and off).
If you want/need to implement your own, take a look at the commit.


Using modifyElementsQuery to get plugin's custom table data I need to join my plugin's custom table to a an ElementCriteriaModel (ECM). I am trying to use modifyElementsQuery.

In the plugin's custom table, rows can share an element/entry via a separate id.

Can I achieve this by adding to the modifyElementsQuery? What would the query be to accomplish this?

*My intention is to have an array of models for each row of my custom table, and each model will include my row data, in addition to the element's content it is related to.

I found out I was not able to accomplish what I needed by using modifyElementsQuery.  So I created my own ElementCriteriaModel & buildElementsQuery for my plugin. This allows the criteria to be built from my table directly instead of elements table.


Issues upgrading Craft 2 to 3 - Keep seeing Install Screen not Update screen I'm trying to update my development site on MAMP from Craft 2 to 3. I've installed Composer and tried both upgrade methods (keeping the current directory structure & using the new structure). But with both options, I keep getting shown the install craft screen instead of the update screen. Which is not what I want to do.

I've added my info to the .env file, but the only way I can seem to get the update screen is by using my old db.php file from craft 2. But then that means that I can use the .env file.

If I then go to complete the update, I tells me that craft can't do a database backup. If I then continue the update to craft 3, when I log in I'm shown the following dependency error:

The auto-generated validation key stored at /Applications/MAMP/htdocs/lorindafontainefarris/craft3/storage/runtime/validation.key has been deprecated. Copy its value to the “securityKey” config setting in config/general.php.

I don't see a validation key to copy, but I already have one that was created for the .env file. Its just not being used because I've used the old db.php file from my craft 2 build. I'm assuming that I shouldn't have to use my old db.php file to get the update to work.

So can anyone shed some light on why I keep seeing the Install screen when I go to update my craft2 project?

Thanks in advance,

Richard

If you've seeing any install screen instead of an update screen, that means that Craft can connect to the database server specified in craft/config/db.php file, but it either can't find the database you've specified or it can't find the craft_info table.  A common cause of this is the tablePrefix database config setting changed, for example.


How to add two variables into one conditional I'm using Freeform Pro to manually output a select field, but I think my question is a general Craft/Twig conditional question so I'm posting it here.

The option values in my dropdown field are made up of two variables outputted together - an entry title and a category title.

I'm trying to add a conditional for the 'selected' state of the dropdown but I can't get the conditional to work as I'm not sure of the proper syntax to for a concatenated value like this.

I've tried each of the following but none of them work:

<option value="{{ entry.title }} {{ category.entryAlternativeTitle }}" {% if requestTeam.value == 'entry.title category.title' %}selected{% endif %}>{{ entry.title }} {{ category.entryAlternativeTitle }}</option>

<option value="{{ entry.title }} {{ category.entryAlternativeTitle }}" {% if requestTeam.value == entry.title category.title %}selected{% endif %}>{{ entry.title }} {{ category.entryAlternativeTitle }}</option>

<option value="{{ entry.title }} {{ category.entryAlternativeTitle }}" {% if requestTeam.value == entry.title ~ category.title %}selected{% endif %}>{{ entry.title }} {{ category.entryAlternativeTitle }}</option>

<option value="{{ entry.title }} {{ category.entryAlternativeTitle }}" {% if requestTeam.value == {{ entry.title }} {{ category.title }} %}selected{% endif %}>{{ entry.title }} {{ category.entryAlternativeTitle }}</option>

Thanks for any help with this.

It looks like according to your code this (and Aran's) solution should work except for one small difference... if you are testing for this:

entry.title ~ category.title

The value parameter (what is getting stored in the database) should match by removing the space, so from this:

{{ entry.title }} {{ category.entryAlternativeTitle }}

To this:

{{ entry.title }}{{ category.entryAlternativeTitle }}

Or you could also test for the space if you want:

{% if requestTeam.value == entry.title ~ ' ' ~ category.title %}

Update: Also want to note that you may need to test for the "entryAlternativeTitle" variable. Can't know for sure without seeing all of your code but if this is all being executed in the same chunk it should most likely be:

{% if requestTeam.value == entry.title ~ ' ' ~ category.entryAlternativeTitle %}


Update Asset Indexes not working for large number of assets I am trying to index 1.8GB of assets to an asset source on Craft.

I have created an Asset Source which points to the folder with all of the assets. When I select the Asset Source I want to update the index for and select "Go" the loading screen runs for a while, then shows me a confirmation checkbox, but nothing has happened.

While Craft appears to give you a success message when the Update Asset Index modal displays a pretty checkbox, when working with a large number of assets, if you don't see a loading bar appear or see the indexed assets afterwards, it's possible you are running into a memory issue, and that pretty checkbox is lying.

Likely, if you look at your craft/storage/logs/phperrors.log you will find a memory error. Try increasing the memory available to your Craft install or increasing the memory_limit in your php.ini settings and trying again.


Redactor or another HTML editor that can inherit actual page styles? is it possible for Redactor or any of the other editors to actually inherit the styles from the (front end) page it is editing?  My client has bootstrap columns etc and the pages have some elements with backgrounds and i wanted to make the content look more like the actual website they are editing rather than one long block of text.

I hacked around in the Redactor CSS files and i can kind of get it working by importing my sites stylesheets into the Redactor one but then that affects the whole Entry page's styles and also hacking in Redactors styles doesn't seem the best.

I do realise probably the best way to do this properly would be to create blocks for each type of content with Matrix (2 col or 1 col etc) and recreate all page elements but the site is coming from another system with lots of static pages and i just wanted my client to have a simple way to edit the existing content.

Anyone any ideas if this is possible at all?

Malcolm

The best solution I know of is to install the Control Panel CSS plugin. When you add the css you'll want to target the elements inside Redactor so you don't change the whole Craft CP. For example, add ".redactor-box " before any elements you need to style.

.redactor-box p {
    margin-bottom: 50px;
}


Best way to handle large amount of records What is the best way to handle 20,000 simple records?  The records need to be searchable and linked to categories.  What is the best way to handle so many records when each records or entry would be a simple phrase 5-10 words max.

I thought of categories but thinking 20k anything has to be thought out.  Since categories may or may not be most efficient, any ideas or way that you have done this in the past before with success?

In sake of performance it would be better to create a custom field type and one or two record(s).

You can store your information/records in a separate table and link them with their ID to a category. Craft CMS will create a record in at least 4 tables for every elements and it has to join those tables to populate it. So an additional amount of 20k will decrease your performance for sure.

It's better to create a separate table rather than using categories for this task. You can combine your records with other elements with an normal Query like Craft does it with it's  ElementCriteriaModel.

It's going to be much more work if you are not used to Craft but it will help you in the future as a good practice


Can structure entries have their own entries? I have a bunch of categories within a section on my website, but I want each category item within that section to be able to have an additional slug. For example:

mywebsite.com/categories/category/information (information being the additional slug)

Is this possible with Craft?

Update

Following your comment, and if I understand well, you already are using a URL for the categories, but want to create kind of a subpage "information" for them. It is a bit more complicated but it can be achieved. What you can do is create a route, either from the control panel or the config/routes.php file in craft/config. It may be easier to do it from the control panel first. If you go to Settings > Routes and click on "New route" you can enter the following information:

It will create a new URI endpoint for the "information" pages that you want and map them to a _information.html template in the "categories" folder.

You can then create _information.html template and retrieve your category using the following code:

{% set category = craft.categories({ group: 'categoryName', slug: craft.request.segments[1] }) %}

Assuming the handle of your category is categoryName of course.
craft.request.segments is an array containing all parts of your URI, starting from 0. Thus, the second part of the URI, which is the selected category's slug, is stored in craft.request.segments[1].
The variable category will then contain all the fields assigned to the category that you want to display in the information page.

It is possible and quite easy to do in Craft.
You can create a new text field named "External link" for example, and assign it to the category.

To do that, go to Settings > Categories > {Name of your category} and select the "Field layout" tab. You can then assign the "External link" field to the category like you would for a section.

You can now edit your categories and add the external link for each one of them.


Strange Font Issue with Control Panel There seems to be an issue with HelveticaNeue in chrome, on Windows 7. If I manually edit the fontface using dev tools I can get the text to display in the default font. Doing a bit of searching online and this seems to be a bit of chrome bug for certain people, so is there any way to change the font altogether for the cp? Or a chrome fix?

Its probably not a good idea to go in and change the fonts for Craft yourself.

Please submit a bug report to support@pixelandtonic.com, and they will have a look into the issue.


Get asset by extension or mime type? Is it possible to query assets by it's filetype?

Example: I have a generic asset field, but I want to get the first asset that's an .mp4 file.

To get all .mp4 files:

{% set mp4s = craft.assets.filename('*.mp4').find() %}

To get the first .mp4:

{% set mp4 = craft.assets.filename('*.mp4').first() %}


Generating thumbnails when using a memcache server for session storage frequently signs users out I can't figure out why, but when I'm connected to a memcache server the thumbnail generation process in Assets hangs for long periods of time, the getElements process throws 403 errors, the generating thumbnails throw 401 errors and then the user is signed out.

This happens in 2 different AWS environments and on my local environment configured using MAMP. In total, three different memcache servers (production, stage, local) have this same thing occur.

The only thing I can find in the logs that seems like it could be related is an error message that reads:

Tried to restore session from a cookie, but the given login name does not match the given uid.
UID: LONG_UID_HASH_HERE and loginName: MY_EMAIL_ADDRESS.

I'm currently running Craft CMS 2.6.3019 (most current version of 2.x at the moment).

Edit: I also wanted to mention these assets all reside in an Amazon S3 bucket. Thought that might be relevant here, too.

Edit 2: I forced hasThumb() to always return false by commenting out these lines. The thumbnails don't generate 401 errors (because no thumbnails are being generated and the placeholder images are being used instead). And getElements runs much quicker, but it stills throws 403 errors after clicking around for some time.

My solution to this was to swap memcache for Redis. I realize that doesn't resolve why memcache wasn't working for us, but swapping it corrected this issue.

My best guess is either:

We were caching data to memcache that was too large for it to optimally handle.
Memcache was being overwhelmed when asked to cache the thumbnails for images that Craft was generating.

These are completely unfounded, but just some best guesses on what was happening.


Next/Previous Asset or Image within Entry I'm looking to create a way to navigate to the next/previous image in an entry's asset range and display only the current asset at one time(starting from first asset).

{% extends '_layout.html' %}

{% block main %}

    {{ entry.title }}

        Emily Ashcroft

    Commissions
    Portraits
    Personal
    Info

        {% for photo in entry.photos %}

  {% endfor %}

{% endblock %}

Click on left side of screen and the previous asset is displayed, click on the right and the next asset is output. I'm struggling to figure if I should use a method similar to paginating links to next/prev entries (but I don't think that would work for assets).

This code is taken from _entry.html page of a section.

Thanks for any help provided.

Given that your assets are within an entry, it seems that a gallery browsing mechanism may fit well. I'd suggest a javascript framework such as Fancybox: http://fancyapps.com/fancybox/

Alternatively and perhaps more in line with your specific question, have a look at this related thread: Best way to access getPrev and getNext asset fields


How to handle payments on a multicurrency website using Mollie gateway? We built a multicurrency website on Craft Commerce that uses both Euros and Dollars. The base currency is EUR. We use Mollie as payment gateway. However, Mollie only supports Euros on their platform and does not convert other currencies to euros. The conversion has to take place on the website before the user arrives on their platform.

The problem is: when a user checks out on our website with dollars, say 100USD, the amount will show up on Mollie as 100EUR. Obviously this is a big issue as the amounts will be off by several percents.

How do we properly fix this?

We found a quickfix by editing the Commerce_PaymentsService.php file in craft/plugins/services/.

We changed to following:

$request = [
    'amount'               => $transaction->paymentAmount,
    'currency'             => $transaction->paymentCurrency,
    'transactionId'        => $transaction->id,
    'description'          => Craft::t('Order').' #'.$transaction->orderId,
    'clientIp'             => craft()->request->getIpAddress(),
    'transactionReference' => $transaction->hash,
    'returnUrl'            => UrlHelper::getActionUrl('commerce/payments/completePayment', ['commerceTransactionId' => $transaction->id, 'commerceTransactionHash' => $transaction->hash]),
    'cancelUrl'            => UrlHelper::getSiteUrl($transaction->order->cancelUrl),
];

To:

$request = [
    'amount'               => $transaction->amount,
    'currency'             => $transaction->currency,
    'transactionId'        => $transaction->id,
    'description'          => Craft::t('Order').' #'.$transaction->orderId,
    'clientIp'             => craft()->request->getIpAddress(),
    'transactionReference' => $transaction->hash,
    'returnUrl'            => UrlHelper::getActionUrl('commerce/payments/completePayment', ['commerceTransactionId' => $transaction->id, 'commerceTransactionHash' => $transaction->hash]),
    'cancelUrl'            => UrlHelper::getSiteUrl($transaction->order->cancelUrl),
];

This way the request sends the amount based on the base currency (in our case EUR) to Mollie.

This seems a bit hacky to us so maybe an exception for the Mollie gateway can be added to future updates to Craft Commerce.


Check length of textfield in header file Some links in the menu should only be shown if the textfield is not empty. For example:

{% if craft.entries.section('aboutus').textField|length == 0 %} style="display: none;" {% endif %}.

But craft.entries.section('aboutus').textField|length always returns 1. I also tried is empty.

So, how I get the real length of this textfield?

And I have the same problem with a matrix. How can I check if the Matrix field has any blocks?

This should do it for a text field:

craft.entries.section('aboutus').textField(':empty:')|length

To see if a Matrix field has any blocks, it's not as pretty.  There's probably a better way, but it's all I can think of at the moment:

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

{% set validEntries = [] %}

{% for entry in entries %}
    {% if entry.matrixField|length %}
        {% set validEntries = valid|merge([entry]) %}
    {% endif %}
{% endfor %}

validEntries is now an array of entries that have at least one block.


Multiple Queries with differing CSS in Paginated output {% set query = craft.entries.businessAddress(params).orderBy('Premium desc, distance').limit(12) %}

{% paginate query as pageInfo, pageEntries %}

    {% for entry in pageEntries %}

    {% endfor %}

{% include 'includes/_sect-pagination' %}

I have the above code, which outputs paginated results of a section ordered by whether they are a STANDARD or PREMIUM entry, then by a distance calculation.
Within the entry output an IF statement adds more CSS to the output depending if STANDARD or PREMIUM, all of this works fine, however, id like to add more CSS to the results.
I would like to have the PREMIUM entries output in a separate ROW to the STANDARD entries so the ROWS can have different CSS applied, but still remain part of the total pagnination.
For example, if there are 3 premium and 14 standard,
The first page would be:-

<did class="col-lg-4">PREM ENTRY 1

<did class="col-lg-4">PREM ENTRY 2

<did class="col-lg-4">PREM ENTRY 3

<did class="col-lg-4">STANDARD ENTRY 1

<did class="col-lg-4">STANDARD ENTRY 2

<did class="col-lg-4">STANDARD ENTRY 3

<did class="col-lg-4">STANDARD ENTRY 4

<did class="col-lg-4">STANDARD ENTRY 5

<did class="col-lg-4">STANDARD ENTRY 6

<did class="col-lg-4">STANDARD ENTRY 7

<did class="col-lg-4">STANDARD ENTRY 8

<did class="col-lg-4">STANDARD ENTRY 9

Second page would be:-

<did class="col-lg-4">STANDARD ENTRY 1

<did class="col-lg-4">STANDARD ENTRY 2

Can anyone say if that is possible within paginated results, if so how?
Any help would be greatly appreciated.

Well after a brain melting, I have come up with an answer, im not sure how pretty it is, any comments on how to tidy it up are most welcome.

{% set premEntries = craft.entries.section("test").relatedTo(category).Premium('yes').orderBy('RAND()').ids() %}

{% set standEntries = craft.entries.section("test").relatedTo(category).Premium('no').orderBy('RAND()').ids() %}

{% set premCount = craft.entries.section("test").relatedTo(category).Premium('yes').orderBy('RAND()').count() %}

{% set limitTotal = premCount / 12 %}

{% set limitRoundUp = ceil(limitTotal) %}

<1-- This gives me the number of premium entries on the last page they appear -->
{% set limitRoundDown = floor(limitTotal) %}
{% set lim3 = limitRoundDown * 12 %}
{% set lim4 = premCount - lim3 %}

{% set allEntries = standEntries |merge(premEntries) %}
{% set posts = craft.entries.id( allEntries ) %}
{% paginate posts.limit(12).orderby('Premium desc') as pageInfo, pageEntries %}
{% set pageCount = pageInfo.totalPages %}

    <div class="container-fluid greyouter {% if premCount <= 12 %}whiteouter{% endif %}">

                {% for entry in pageEntries %}

                    {% if pageInfo.currentPage != '1' %}

                    {% endif %}

        {% if pageInfo.currentPage == '1' and premCount == '0' %}

        {% endif %}

    {% if pageInfo.currentPage == limitRoundUp and loop.index == lim4 %}

{% endif %}

{% endfor %}

    {% include 'includes/_sect-pagination' %}


Best way to effect part word searching by default I want to use the standard site search but much prefer that (first) part word search is in place by default. By this I mean if a user searches for dog they will also find dogs, so the term Craft uses would then be dog*.

My strategy would then be to take the search string (e.g. 'dog fee') and remove any commas or fullstops unless the string is in quotes ("dog fee"). I would then split the string using spaces and throw away any empty strings ('dog', 'fee'), and then append the * to each word and send 'dog* fee*' to the search system.

Is this the best approach to get what I want, or have I missed a glaringly obvious and easy way of doing it?

This sounds like a good approach and could be done using a twig filter on your search string.

Here are the first two lines of the example from the docs:

{% set query = craft.request.getParam('q') %}
{% set entries = craft.entries.search(query|customFilter).order('score') %}

In this example query is now modified by customFilter and can be updated in your Twig filter to behave however you like.


Change author of entry within Craft Client licence I created some sample blog posts during development, and now want to change the author of those posts to the client. Yet, only I'm listed in the dropdown box when I try and change an entry's author.

Any ideas? Besides editing it in the database.

Update the database: author_id column in the craft_entries table.


How do you prevent user lockout? When a user forgets their password multiple times on one my front-end login screen, they sometimes get locked out of the system until an admin can unlock them in the control panel. Is there any way to prevent this behaviour?

It’s not currently possible to disable that behavior altogether, but you can increase the number of times the user can enter the incorrect password before their account gets locked using the maxInvalidLogins config setting.

You can also customize how long Craft will track invalid logins before that maxInvalidLogins counter resets using the invalidLoginWindowDuration config setting.

For example you, if you wanted the users to get locked out if they entered more than two* incorrect passwords in 10 seconds, you could set these in craft/config/general.php:

'maxInvalidLogins' => 3, // see the note below
'invalidLoginWindowDuration' => 'PT10S',

You can also customize what happens when a user gets locked out with the cooldownDuration config setting. By default they will only be locked out for 5 minutes, so it’s not actually necessary for an admin to log in and unlock their account. That would only happen if the config setting was set to 0.

*There’s actually a bug in Craft right now where a user will get locked out as soon as they’ve hit the maxInvalidLogins count, which I think is incorrect; if the setting is set to 2, they should be able to login incorrectly 2 times, and still have a 6th chance to get it right. I’ve just adjusted that behavior for the upcoming 2.2 release.


One select search for Users in user.group I'm a complete newby on Craft CMS and twig templating so please bear with me.

I currently have a users base which I want to filter by category (a custom field)

This would be my only input search element:

<select name="professionalita">
    <option value="" disabled selected>Professionalità</option>
    {% for category in craft.categories.group('professionalita') %}
    <option value="{{category.url}}">{{ category.title }}</option>
    {% endfor %}
</select>

This is what I tried to build on results.html page.

{# Get the search data #}
{% set profParam = craft.request.getParam('professionalita') %}

{% extends "_inc/layout" %}

{% block main %}
    {# Find and list matching entries #}
    {% set members = craft.users.group.('members').relatedTo(profParam) %}

    {% if members|length %}

            {% for member in members %}

{{ member.firstName }}

            {% endfor %}

    {% else %}
        No members found.
    {% endif %}
{% endblock %}

I get no results even if there are actually correspondencies between the users and the category name being searched for.

I suggest you to read the docs about relations. You can search for relations by the following parameter

In its simplest form, you can pass in one of these things to it:
An AssetFileModel, CategoryModel, EntryModel, UserModel, or TagModel object
An element’s ID
An array of element objects and/or IDs

What you pass is a string or to be more specific a url
<option value="{{category.url}}">{{ category.title }}</option>

What you have to do is:
<option value="{{category.id}}">{{ category.title }}</option>

In order to find users related to a category id.
However I strongly suggest you to build your search with PHP if you are going to include multiple parameters (more categories/search terms/complex and+or bindings) it is going to be a mess with twig


Craft CMS not working on server I had my Craft CMS site working on my local hosting. I then moved it over to bluehost VPS. I moved the database and uploaded the files to the server. I've put the database user information in the .env file and the server location. But site comes back on domain:

  Service Unavailable
  Our site is temporarily unavailable. Please try again later.

When I try to admin in it tells me:

  Service Unavailable
  Craft isn’t installed yet.

Any suggestions would be of great help.

Service Unavailable Craft isn’t installed yet.

If you're getting that message, then Craft can connect to the database with the credentials you've provided, but it can't find the info table, so it thinks it's not installed.

Maybe the tablePrefix config setting is set incorrectly in your .env file?


Sprout Forms - Redirect to same page with query string I'm looking to redirect the user to the same page that they were on, with an additional query string.

Is this possible?

Thanks
Adam

Sure, in the control panel for sprout forms you can set the redirect page. Say the url for your contact page is /contact you can do something like redirect to:

contact?message=thank-you

and then in your contact template do something like:

{# Check if we should display a thank you message #}
{% if craft.request.getParam('message') == 'thank-you' %}
 //do stuff here
{% endif %}

Sprout installs a bunch of sample forms, there's plenty to gleam and learn from these.


Filtering out section entries I'm quite new to Craft CMS and have takeen over an application (using Twig templates).  I'm trying to run a filter but not having much joy so maybe I might get some help!

So, there is a people section (craft.entries.section('people')) with over 1000 entries. These are displayed in an HTML table, each row has 3 columns (handled using the batch() call). I want to exclude certain entries that match a particular condition.

For example, I want to exclude all 'people' that partially match a list of names (e.g 'xyz', 'zzzz', 'joebloggs')

{% for people in craft.entries.section('people').order('title asc').limit(500)|batch(3) %}

Is it possible to do a query like this before the loop? Or is it something I need to check on each iteration inside the loop? Doing this might make the batch() unusable?

If you want to search for entries, you can use the search parameter:

{% set people = craft.entries
    .section('people')
    .search('*xyz* OR *zzzz*')
%}

Then, you can loop through those people like this:

{% for person in people |batch(3) %}
    {{ person.name }}
{% endfor %}

By default, search doesn't do fuzzy search, that's where the *s come in. You can, however, enable fuzzy search by default.

If you want to limit your search to a field, do:

{% craft.entries.search('fieldHandle:xyz OR fieldHandle:zzzz') %}


Matrix field in user-profile front-end I created matrix field, put it in the user field. In the front-end page as usually write

{% for block in user.myMatrixfield.type('myType') %}
   ................
{% endfor %}

but there is no output!
try to write {% user.myMatrixfield|length %} - outputs 0

In administration panel everything works.
How to get matrix field in user-profile front-end page?

It works identically to entries.

Here are a couple things you can do to troubleshoot:

Make sure that user is set to the user account you’re expecting it is. You can double check that by outputting {{ user.username }}.
Make sure that you’re calling the right Matrix field handle, with the correct capitalization.
If you’re passing the type param, make sure you’re passing in the right Block Type handle.


When I flip the "Featured Entry" switch, disable it on other entries Assuming I'm using a lightswitch to denote an entry as "Featured," how can I then disable that lightswitch on every other entry, so that no matter how many times I flip these switches only one entry can be "Featured?"

Thanks!

Edit: There are some plugin options, and that might be the only way to go but I'm hoping that someone can find a better way through Twig filters or something.

It depends on your sort order. If your goal is to only display the most recent 'featured' entry, then you could add the .first parameter to your template code.

Craft would simply grab the first entry it finds

OR, you could limit your query by using the Limit parameter. See: https://craftcms.com/docs/templating/craft.entries#limit

Edit (addition):
Here's an example of how you could display the single, most recent entry which has been marked as Featured, using a lightswitch field.

{% set featuredNews = craft.entries.section('news').featured('not 0').order('dateUpdated desc').limit(1) %}
{% for entry in featuredNews %}
    {{ entry.title }}
{% endfor %}

(Some valuable insight here: craft.entries and lightswitch and here: https://craftcms.com/docs/lightswitch-fields)

Hope it helps


How do you set up Craft CMS to back up your site automatically? I am considering having my site moved from WordPress to Craft CMS (feel free, by all means, to weigh in on this consideration), and wondered how one goes about setting up automatic backups within Craft. Thanks!

Options:

1) Craft will automatically run a backup of the database anytime an update is performed and save it to craft/storage/backups

2) You can manually create a database backup by going to Settings->Tools->Create Database Backup.

3) You can install something like the Dump plugin and create a cron job that points to it to run the backup on a automated schedule.


How do I sort and display by a matrix date field? I have an entries in a section called 'garden', with a matrix field called 'sowing' - this matrix has a block called 'locationDate' and two fields 'sowingDate' and 'sowingLocation'.

I want to loop through and show the last 5 things sown in the garden, so based on other examples and using low blocks, I have this code:

{% set allSown = craft.lowblocks.blocks.fieldId(12).type("locationDate").order("sowingDate").limit(5) %}
{% set entryIds = [] %}

{% for sown in allSown %}
    {% set entry = sown.title %}
    {% set entryIds = entryIds | merge([entry.id]) %}
{% endfor %}

{% set entries = craft.entries.section("garden").id(entryIds).fixedOrder(true).status("live,pending") %}

{% for sown in entries %}
    {{ sown.title }}<br />
{% endfor %}

So my question is, why can't I view the entries, and what do I need to do to display the date of the matrix field? It seems like it should working, but I am missing something for sure.

** note I need to have a matix date there as there are often multiple sowing locations and dates per entry.

I have not worked with Lowblocks yet, but it looks like it returns an array of Matrix block models. To get to the related entries you need to access the owner property.

{% set entryIds = [] %}
{% for sown in allSown %}
    {% set blockId = sown.id %}
    {% set entryIds = entryIds|merge([blockId.owner.id]) %}
{% endfor %}

But do you really need those entry IDs? You could just display the blocks?

{% for sown in allSown %}
    {{ sown.owner.title }}
    {{ sown.sowingLocation }}
    {{ sown.sowingDate }}
{% endfor %}


Change page elements based on geolocation We would like to geolocate visitor IP addresses, and for US-based addresses render a portion of the page to display state-specific options. I actually have the PHP working well to pull the 2-letter state value from a Geocoding API, but am wondering the best way to plug that into Craft PRO.

I'm assuming the logic should look something like this in the end:

Check user for geo-cookie.
If not present, geolocate the user with their 2-letter abbreviation and set the geo-cookie.
If present, read the geo-cookie.
With that value in hand, render page elements accordingly, using the 2-letter abbreviation as a filter. If the user has no 2-letter value (perhaps an international user), present some fall-back "default" content in those areas of the page. (And yes, I am well aware that these services aren't 100% accurate but some providers are fairly close and we can live with that.)

I have found Khalwat's cookie plugin for Craft, which looks like it should suit nicely. But as a newbie to both Craft and Twig, how do I now bring it all together?

OR should we just adapt Craft PRO's localization options for this instead, since it's built in? And if so, how would we pass the 2-letter value along to use that?

Let's get the easy question out of the way first... Don't use Craft's localization to handle this task. While the localization feature is amazing and powerful, it doesn't fit the needs you're describing. Localization is mainly geared towards handling different languages for different countries.

So what's the best way to handle this? Fortunately, it sounds like you've already worked out the hard part:

  I actually have the PHP working well to pull the 2-letter state value from a Geocoding API

All that's left now is to integrate that business logic into your Craft site! There are a few different ways to approach this, but I'll lay it out in a way that's simple, straightforward, and best fits your current scenario...

Grab and install the Business Logic plugin (unless you've already got a custom plugin installed, in which case you can just build on that).
Create a new function in the Variable file. Let's name it something like detectState.
Put all of your existing PHP logic into that function. You can even get, set, and check your cookies straight from this function. Using a separate cookie plugin may not even be necessary in this situation, since it's easy to manage cookies directly from PHP.
Have your function return the 2-letter state code.
In Twig, you'd call your new function similarly to this:

{% set stateCode = craft.businessLogic.detectState %}

Voila! You can now use stateCode to handle whatever Twig switching logic you need.


How do I get the current user’s info over Ajax? I created an Ajax-based login form based on this gist: https://gist.github.com/keithmancuso/29e8446ec5fa66fb2b01.

After the user has logged in, how can I get some info about them over Ajax?

For the redirect I agree, I could not get it too from ajax response, so I just saved it before the ajax call.
var returnUrl = $("input[name='redirect']").val();

Then I can make the redirection :

.success(function(data) {
    if (data.success) {
        window.location.href = returnUrl;
    }

For the user's data could you precise what you want to do?


How to programmatically translate an entry in craft 3 I'm trying to write a plugin that translate entries programmatically based on subsites that have different language setup.
Normally what happens is this: you setup multi-site, set each sub-site as having a different language and a different url (like @web/de, @web/sv etc), you set a field as translatable by language, then you edit an entry on each of those sub-sites. And the system knows to separate entries by siteId.
Now, I tried the same approach programmatically. I get all the entries for all the subsites like this:
$sites = Craft::$app->getSites()
                    ->getAllSites();
/** @var Entry[] $entries */
$entries = [];
foreach ($sites as $site) {
    /** @var Entry $entry */
    $entries[$site->language] = Entry::find()
                                     ->id($id)
                                     ->siteId($site->id)
                                     ->one();
}

The I go and get all the fields for the English entry (in my setup is safe to assume that all the sub-sites respect the same field layout/structure). To test this, I dumped the values to compare the English version of the field, with the Swedish version. Values were different, which means I'm looking at the correct fields for the correct sub-entry.
//this is how we get the english fields
$fields = $entries['en']->getType()
                        ->getFieldLayout()
                        ->getFields();

//this is how we translate each field for each language
foreach ($fields as $field) {
    if ($field->translationMethod === \craft\base\Field::TRANSLATION_METHOD_LANGUAGE) {
        //get english value
        $enValue = $entries['en']->getFieldValue($field->handle);
        if (!empty($enValue)) {
            //translate in all languages
            $translations = $this->translate($enValue, array_keys($entries));
            foreach ($entries as $lang => $entry) {
                $fieldValue = $entry->getFieldValue($field->handle);
                //only translate if the destination language/field is in English (not translated yet)
                if (('en' !== $lang) && !empty($enValue) && ($enValue === $fieldValue)) {
                    if (!empty($translations[$lang])) {
                        //setFieldValue for each language
                        $entry->setFieldValue($field->handle, $translations[$lang]);
                    }
                }
            }
        }
    }
}

This is how I try to save the entries at the end of it all
//save all non-eng entries
$elements = new Elements();
foreach ($entries as $lang => $entry) {
    if (('en' !== $lang) && !$elements->saveElement($entry)) {
        echo json_encode($entry->getErrorSummary(true));
        die();
    }
}

The issue is that it saves the last translated language in all the sub-sites, for some reason, and I don't understand what I'm doing wrong.

There's no clear question here, instead you've thrown up a bunch of code and said that it's not working. My suggestion would be to double check that the entry fields are indeed being populated with the appropriate translations. So double check whether the following line is actually executed.
$entry->setFieldValue($field->handle, $translations[$lang]);

If it is, then I would expect the save to work. One thing to be aware of, is that the saveElement method accepts a boolean value as the third parameter which specifies whether to propagate the entry. This is true by default, meaning that the entry is propogated for each site each time you save it. Maybe consider setting it to false or better yet, modifying your saving strategy to be more performant.
if (('en' !== $lang) && !$elements->saveElement($entry, true, false)) {

See the method signature at: https://github.com/craftcms/cms/blob/e55041d4c24ea827b13ee4367d3fae52df6ab80f/src/services/Elements.php#L746


Craft equivalent to Rails runner The Rails cli has a runner feature that allows you to run a file (or a string of code) from the command line.

E.g. rails runner my-script.rb (where my-script.rb will run in the context of a fully bootstrapped Rails application). It's a fantastic way to write scripts/backfills/etc without needing to alter your application.

I know that craft includesyiic but it seems to be focused on migrations or code generation and not necessarily providing the same bootstrapped playground.

Is there an easy way to give an arbitrary script access to a bootstrapped craft application? My specific use case is that I want access to models and plugins to be able to migrate fields from one event plugin to another (this is actual content, not just a schema migration).

Maybe you're just looking for a bootstrapped Craft instance?

Something like:

$craft = require '/path/to/craft/app/bootstrap.php';

From there you'll have access to the Craft instance as usual:

$craft->entries->saveEntry();

Along with your models, records, etc.


Populating tables and matrix fields using GuestEntries Is it possible to populate a Matrix Field, Table and Lightbox using the GuestEntries plugin from an HTML form?

I'm trying to build an RSVP form, and am not having a lot of luck with different field types.

Using the syntax from Brad's answer is working to create rows in the table on new entries, but it's not populating them. The below code creates two rows in the table, but they're empty.

<input type="text" name="fields[guests][0][name]" placeholder="Name" />
<input type="text" name="fields[guests][1][name]" placeholder="Name" />

See here for example front-end HTML code for all of Craft's default field types:  https://straightupcraft.com/articles/craft-cms-field-guide-twig?view=input

Matrix:

{# You need to include the 'type' input to identify the matrix block type you are submitting #}
<input type="hidden" name="fields[fieldHandle][new1][type]" value="contacts">

{# All of your custom fields must be within a 'fields' array. #}
<input type="text" name="fields[fieldHandle][new1][fields][field1Handle]">
<input type="text" name="fields[fieldHandle][new1][fields][field2Handle]" >
<input type="text" name="fields[fieldHandle][new1][fields][field3Handle]" >

{# For New Entries, you'll want to use the naming convention

'new1', 'new2', 'new3' for each of your blocks.  For existing entries you
can update those values to be the block IDs #}

Table:

<input type="hidden" name="fields[fieldHandle]" value="">
<textarea name="fields[fieldHandle][0][col1]" rows="1"></textarea>
<textarea name="fields[fieldHandle][0][col2]" rows="1"></textarea>
<textarea name="fields[fieldHandle][0][col3]" rows="1"></textarea>
<input type="hidden" name="fields[fieldHandle][0][col4]">
<input type="checkbox" name="fields[fieldHandle][0][col4]" value="1">

<textarea name="fields[fieldHandle][1][col1]" rows="1"></textarea>
<textarea name="fields[fieldHandle][1][col2]" rows="1"></textarea>
<textarea name="fields[fieldHandle][1][col3]" rows="1"></textarea>
<input type="hidden" name="fields[fieldHandle][1][col4]">
<input type="checkbox" name="fields[fieldHandle][1][col4]" value="1">

Lightswitch:

<input type="hidden" name="fields[fieldHandle]" value="1">


Get a specific product with Element API, Commerce and Craft 2 How do I get a specific product via Element API?

Here's what i have so far

'api/product' => function() {
    $productId = craft()->request->getRequiredQuery( 'productId' );

    return [
        'elementType' => Product::class,
        // This provides Element API the fully qualified Element namespace + class.
        'pretty'      => true,
        'criteria'    => [
            'relatedTo' => [ 'targetElement' => $categoryIds ],
        ],
        'transformer' => function( Product $product ) {
            return [
                'title' => $product->title,
                'url'   => $product->url
            ];
        }

    ];
}

If you want to get a specific product and it's variants by the productId you could simply do:

'api/product/<productId>' => function( $productId ) {
    return [
        'elementType' => Product::class,
        'criteria'    => [
            'id' => $productId
        ],
        'pretty'      => true,
        'transformer' => function( Product $product ) {
            foreach ( $product->getVariants() as $variant ) {
                $variants = [
                    'title'         => $variant->title,
                    'description'   => $variant->description,
                    'productId'     => (int) $variant->productId,
                    'purchasableId' => (int) $variant->purchasableId,
                    'status'        => $variant->status,
                    'type'          => $product->type->name,
                    'url'           => $product->url,
                ];
            }

            return $variants;
        },
    ];
},

you are able to get the product then via yourshop.domain/product/1234


What is the difference between siteUrl and baseUrl? What is the difference between siteUrl and baseUrl in Craft 3? Is there any?

When you take a look into Craft you'll see this

 /**
 * @var string|string[] The base URL to the site(s). If set, it will take precedence over the Base URL settings in Settings → Sites → [Site Name].
 *
 * This can be set to a string, which will override the primary site’s base URL only, or an array with site handles used as the keys.
 *
 * The URL(s) must begin with either `http://`, `https://`, or `//` (protocol-relative).
 */
public $siteUrl

So the baseUrl is what you insert in your site settings, the siteUrl can overwrite these values from your config

The Site.php (model) has a this function as well

/**
 * Overrides the base URL while keeping track of the original one.
 *
 * @param string $baseUrl
 *
 * @return void
 */
public function overrideBaseUrl(string $baseUrl)
{
    $this->originalBaseUrl = (string)$this->baseUrl;
    $this->baseUrl = rtrim($baseUrl, '/').'/';
}

which is called in the Site service

$site->overrideBaseUrl($generalConfig->siteUrl);


Get parent entry from a section using the Element API How can you access the parent of a section using the Element API? I have the following where I use the getParent() function which does return an empty object when an entry has a parent.

Do I need to pass in the element criteria model or something?

Also could someone expand on this to show how you just get the level 1 parent or the level 2 parent please.

return [
  'endpoints' => [
    'brands.json' => [
      'elementType' => 'Entry',
      'criteria' => ['section' => 'brand'],
      'transformer' => function(EntryModel $entry) {
        return [
            'title' => $entry->title,
            'url' => $entry->url,
            'level' => $entry->level,
            'parent' => $entry->getParent()->first(),
        ];
      },
    ],
  ]
];

A couple of issues:

First, the EntryModel::getParent() method returns an EntryModel, not an ElementCriteriaModel, which means that calling getParent()->first() will throw an exception. In other words, you'll need to remove the call to first().

Second, you'll need to be specific about which fields you want to return from your parent entry – just passing in the raw EntryModel won't work – so your code should look something like this:

'transformer' => function(EntryModel $entry) {
    $parent = $entry->getParent();
    return [
        'title' => $entry->title,
        'url' => $entry->url,
        'level' => $entry->level,
        'parent' => $parent ? [
            'title' => $parent->title,
            'url' => $parent->url,
            'someCustomField' => $parent->someCustomField,
        ] : null,
    ];
  },

In the above, I'm using a ternary operator to conditionally include the array containing the parent entry's data (the condition being if the parent entry exists or not). If you want your code to be less "inline", you could also do something like this:

'transformer' => function (EntryModel $entry) {
    $parent = $entry->getParent();
    $return = [
        'title' => $entry->title,
        'url' => $entry->url,
        'level' => $entry->level
    ];
    if ($parent) {
        $return['parent'] = [
            'title' => $parent->title,
            'url' => $parent->url,
            'someCustomField' => $parent->someCustomField,
        ];
    }
    return $return;
},

Finally, if you need to be specific about the parent entry's level, you'll need to swap out the getParent() method for EntryMode::getAncestors() (which does return an ElementCriteriaModel). Here's how you'd get the top level parent:

$parent = $entry->getAncestors()->first();

...and since getAncestors() returns an ECM, pulling a parent entry with a specific level is trivial:

$parent = $entry->getAncestors()->level(2)->first();


Generating responsive images from cropped source file I've been trying to adapt this helpful post to work with Image Transforms, so that the starting point for generating the responsive images is a cropped high resolution original.

I've defined a Transform called 'fullWidth' in the CMS, and have tried calling:

{% do image.setTransform('fullWidth') %}

Tearing my hair out, would someone be kind enough to assist?

Original code:

{% macro srcset(image, maxCssWidth, includeDimensions) %}
{%- spaceless %}
    {# Is this a 2X image? #}
    {% set is2x = image.filename matches '/@2x\\.\\w+$/' %}

    {# Determine the CSS width for the image, if it were output at 100% #}
    {% set cssWidth = (is2x ? round(image.width / 2) : image.width) %}

    {# Determine the image size that 1X screens should get #}
    {% set width = (cssWidth > maxCssWidth ? maxCssWidth : cssWidth) %}

    {# Determine the image size that 2X screens should get #}
    {% set width2x = (width * 2) > image.width ? image.width : (width * 2) %}

    {# Output the srcset= attribute value #}
    srcset="{{ image.getUrl(image.width != width ? { width: width }) }}, {{ image.getUrl(image.width != width2x ? { width: width2x }) }} 2x"

    {#- Output the width= and height= attributes if needed #}
    {%- if includeDimensions %} width="{{ width }}" height="{{ image.getHeight({ width: width }) }}"{% endif %}
{% endspaceless -%}
{% endmacro %}

Here's what I've ended up with:

{% macro srcset(image, maxCssWidth, maxCssHeight, includeDimensions) %}
{%- spaceless %}

    {# Is this a 2X image? #}
    {% set is2x = image.is2x %}

    {# Determine the CSS width for the image, if it were output at 100% #}
    {% set cssWidth = (is2x ? round(image.width / 2) : image.width) %}

    {# Determine the image size that 1X screens should get #}
    {% set width = (cssWidth > maxCssWidth ? maxCssWidth : cssWidth) %}
    {% set height = maxCssHeight %}

    {# Determine the image size that 2X screens should get #}
    {% set width2x = (width * 2) > image.width ? image.width : (width * 2) %}
    {% set height2x = (height * 2) > image.height ? image.height : (height * 2) %}

    {# Output the srcset= attribute value #}
    srcset="{{ image.getUrl(image.width != width ? { width: width, height: height, mode: 'crop' }) }}, {{ image.getUrl(image.width != width2x ? { width: width2x, height: height2x, mode: 'crop' }) }} 2x"

    {#- Output the width= and height= attributes if needed #}
    {%- if includeDimensions %} width="{{ width }}" height="{{ image.getHeight({ width: width }) }}"{% endif %}
{% endspaceless -%}
{% endmacro %}


help changing footer on home page I wonder if you can help. I need to make some changes to the text on the bottom part of our home-page but I'm not sure how to. This site was designed for us by another agency and although I have access to the template and the back of it I can't seem to figure out how to edit the text on the footer of the site. help please!
Thanks,
Carolina

It seems like you're not a web developer? This is a very broad question unfortunately which will make helping hard. It depends almost entirely on how the previous agency decided to build your website, as "a footer" is not built-in functionality, but instead part of the design.

Typically, a footer would be controlled from a _layout.twig file in the templates directory. The content inside it may be "hard coded" or dynamically controlled from the CMS - there's no way for me to know. You'd need to look at the content of that file and see if you can find any text matching the text you see in your footer. Be aware though, that a footer template is usually site wide and not specific to individual pages; a change in _layout.twig would most often mean a change everywhere on your website.

You may be best off getting in touch with the prior agency, or perhaps a freelancer, and asking them to take a look.


Craft 3 Multi Language Setup Okay, I am here because I would like to have a site in the following structure:

https://site.com  (default english version)
https://site.com/ko (korean)
https://site.com/pt (portuguese)

I would like to use ONE uploads folder to store all of the assets for all 3 languages(plus any additional languages added after), use all of the same templates, and use all of the same css and js files.

My current directory structure is the craft 3 default(I used the cli installer, which is great). Here is the important pieces of what my directory looks like:

-templates
- web
   - dist
      - js
      - css
   - uploads
   - ko
   - pt

Lets say I have the following templates:

- home.html
- newsroom.html
- whitepapers.html
- help.html

I would expect to be able to visit each in the following manner:

(Home)
- https://site.com
- https:///site.com/ko
- https://site.com/pt

(Newsroom)
- https://site.com/newsroom
- https:///site.com/ko/newsroom
- https://site.com/pt/newsroom

...etc hopefully you get the picture.

Is this at all possible with Craft 3? I keep running into issues where each languages site is trying to pull in the uploads or css/js assets from within their respective folders:

Also, here is the sites config in general.php:

'dev' => [
        'siteUrl' => [
          'default' => 'https://site.test',
          'korean' => 'https://site.test/ko',
          'brazil' => 'https://site.test/pt'
        ],
        'devMode' => true,
 ]

SOLUTION
For anyone visiting this in the future, here are the updates to my config that solved the problem. Please refer to this after you have read Robin and Jolle's answers, they are both very helpful.

'dev' => [
        'siteUrl' => [
          'default' => 'http://site.test',
          'korean' => 'http://site.test/ko',
          'brazil' => 'http://site.test/bz'
        ],
        'aliases' => [
            'basePath' => '/Users/dzuz/localhost/site/web',
            'baseUrl'  => 'http://site.test/',
        ],
        'devMode' => true,
    ],

First of all you should remove all "language" subfolders from your web directory because your web server will route directly in those instead of your default web/index.php. Craft will determinate the CurrentSite depending on your url not on the location of the file.

Second: make sure to insert an array with aliases in your config/general.php
I'll show a "complex" solution for multiple asset sources for multiple sites. If your site shares the same resources you'll just need the first array element but I want to show the concept

$publicPath = realpath(dirname(__DIR__) . '/web');
// ....
'aliases' => [
    'assetPath1'    => $publicPath . DIRECTORY_SEPARATOR . 'assets' . DIRECTORY_SEPARATOR . 'folder1' . DIRECTORY_SEPARATOR,
    'assetPath2'    => $publicPath . DIRECTORY_SEPARATOR . 'assets' . DIRECTORY_SEPARATOR . 'folder2' . DIRECTORY_SEPARATOR,
    //....
]

You should never access those files with

<script src="`{{ siteUrl }}/assets/folder1/jquery.js`">

Because this will use the current site url and append the structure. Therefore you have the alias function

<script src="`{{ alias('assetPath1') }}/assets/folder1/jquery.js`">

Now you can do some fancy stuff like

<script src="`{{ alias('assetPath' ~ currentSite.id) }}/assets/folder1/jquery.js`">

Or whatever identifier you like to access your asset files dynamically.


How is "craft()->fileCache" different from using cookies? Just looking for a little clarification on the craft()->fileCache method...

Everybody already knows that when a cookie is set, that cookie only exists on the end-user's computer. No one else using the website can access that cookie.

But if I were to replace that cookie getter/setter with the craft()->fileCache getter/setter methods, is that data now available to everyone? Where a cookie is stored on the client machine, the fileCache data is stored on the server?

This is what I suspect is happening, just trying to be sure that I'm interpreting this correctly.

Correct... craft()->fileCache will save to your craft/storage/runtime/cache folder by default, which will have a .bin file that has a hash of the key you provided when calling set() and the contents will be a serialized version of the value you passed in.

Also worth noting that while craft()->fileCache still exists, as of Craft 2.0, it is simply a shortcut to craft()->cache, when the cacheMethod config setting is set to file.


Does Craft support international urls? If I create an entry with international characters in urls? e.g. for Polish language?

If I create an entry with the word "ułatwienia" in the url, it doesn't work (I get Craft serving up the 404 page), I take out the special ł character and it's fine.

Although interestingly, the Live Preview url works fine with the special character included.

Have I missed something?

That should work fine and I just tested locally with a fresh Craft installation on the latest build and ułatwienia works in the slug for me.

Maybe you've got the limitAutoSlugsToAscii config setting set to true and ł gets changed to l in the slug, but you're still entering ł in the URL?


Pass content of system messages to HTML Email Template I know I can set the template in the email settings to use a HTML template but how do I pass the content of the system messages (activate your account, reset your password, etc) to this template?

I've added this to the html template but then the email that is sent is blank:

{% block content %}
{% endblock %}

EmailService->sendEmailByKey() sets the htmlBody property of EmailModel to this:

$emailModel->htmlBody = "{% extends '{$template}' %}\n".
    "{% set body %}\n".
        $emailModel->htmlBody.
    "{% endset %}\n";

So if you've got a custom email template in craft/templates/email.html, in the control panel under Settings → Email → HTML Email Template, you'd set the value to email.html.

And you'd simply output the dynamic email content in your template by using {{ body }} like so:

<html>
    <body>
        <div>
            {{ body }}
        </div>
    </body>
</html>


Craft Commerce stock not updated when order deleted Is this deliberate, or a bug? Delete an order and the products within the order don't have their stock updated again.

I'm only running Craft Commerce 1.2.1327 but I don't see any mention of it in the update notes to the current version so I'm not sure updating is the answer. I'm also cautious about updating at the moment in case it breaks my third-party payment gateway plugin.

Definitely deliberate.  Inventory reduction when an order is placed is a "convenience" thing.

There are a million reasons why an order might be deleted and only a handful of them would have anything to do with inventory.

But as André points out... you could write a simple plugin to have whatever behavior you wanted around this.


Order by related entries count I have a channel with a related users field. I want to output all channel entries ordered by the number of related users, this is what i have so far:

{%
    set entries = craft.entries.find({
        section:  'MyChannel',
        orderBy:  'relatedUsers'
    })
%}

What do i do to order by the number of related users?

Any native solution is likely to be slow - I would recommend using the Preparse field plugin.

It lets you use Twig to dynamically generate a field at the time an entry is saved — you could have Preparse count up the number of related users on save, and then sort by that custom field.


How to create a simple shopping list (but not ecommerce) I'm trying to create a way to create a list of items, similar in appearance to a cart. You have products, you add them to a list and can adjust quantity. The list will follow you throughout the site. However, price is not a factor, there's no payment processing. You're essentially creating a list of products that you want, where then you can submit them to the company. You'll then get a call from them. The products are bespoke so a standard x = $4 situation won't work here. I think something like the Commerce plugin seems like overkill and not sure it can do this (without payments anyway). Any ideas?

Never used it before, but it sounds like maybe the Shortlist plugin might do what you're looking for.

Outside of that, sounds like it'd be a fairly simple plugin to custom develop.


Craft Admin CSS Broken..? I have had Craft CMS installed for a while. then today, I created some new pages, and pushed them with git to the templates folder, added them in sections etc, then, when I go to edit the entry, it comes out like this..?

That is my main sites styling/CSS, but craft shouldn't be using it...should it?

Every other admin page shows okay, and the frontend is fine... just when I edit the entries.

Are you sure you didn't push something to craft/app/templates if you did go check out the folder and remove anything that shouldn't belong there. You can check side by side which files shouldnt be in there with a fresh craft environment. Or just replace the app folder with a fresh one.


Output section and tag name with URL in entry loop I'm trying to loop through entries in specific sections and output Entry's:
    - URL
    - Title
    - Type
    - Asset's image
    - asset's URL
    - Section's name
    - Section's URL
    - Tag's name
    - Tag's URL

So far I came to this with having difficulties with section's URL and tags that belongs to relative entry.

        {% set entries = craft.entries.section(['worldTechnology','worldTravel']) %}
        {% for entry in entries %}

{{ entry.title}}

                    in
                    {{ entry.section.name }}
                    {{ entry.getType.name }}

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

                            {{ tag.title }}

                        {% else %}

                            No tags found

                    {% endfor %}

        {% endfor %}

I'm working on it only in evenings and I'm starting to like Craft and Twig. Hopefully some of you guys, will advice me or give me some direction to go after.

Thanks for viewing it.

Sections do not have URLs, so section.getUrl will not return anything for you.

If you are trying to get an index page of all the entries in a section that has a URI, try slicing off the last segment of the entry's URL, and make sure you have an index.html template in that section's template folder. Take a look at the templating documentation for more information on this.

For the tags, make sure you call  {% for tag in craft.tags.relatedTo(entry) %} instead of {% for tag in craft.tags.relatedTo(entries) %} to get the tags related to the entry you are currently focused on in the for loop.

Hope this helps!


Show all images from Matrix Block I'm trying to bring in all images from a matrix field but I can only get it to work with first() or last() but obviously it only shows 1 image.

I've found a few article explaining it but I can't seem to get it working.

Because logoSlider.image is an array of images (even if there's only one image in the array) you need an additional 'for' loop to catch all of the images (not just the first or last). Try something like this:

{% for logoSlider in entry.logoSlider %}
   {% if logoSlider.type == 'logo' %}
     {% for image in logoSlider.image %}

     {% endfor %}
   {% endif %}
 {% endfor %}


Freeform check box group from entries Is is possible to populate a FreeForm checkbox group by an entries listing? I've got a series of courses with an entry for each one, and I'd like to create a series of checkboxes and values for each course.

The value of the checkbox gets shown in the email notification but not in the control panel. Is this possible to change?

This my solution, although it's not perfect. I set-up an entry loop within the form and included the following for a series of checkboxes:

{% if loop.index == "2" %}

<label>
    <input type="checkbox"
        name="{{ course2.handle }}[]"
        value="{{ course2.value }}"
        {{ course2.checked ? "checked" : "" }}
    />
</label>

<input type="hidden" name="{{ courseName2.handle }}" value="{{ entry.title
}} | {{ entry.courseDate|date('j.n.y') }}"  />

{% endif %}

So in the form submission the entry title in loop 2 is attached to the Course 2 checkbox. It would have been better if {loop.index} could be used within the handle name so the 'if' conditional is not needed. As pointed out above, the value of the checkbox can be set dynamically from the entry loop, but the result is not shown in the FreeForm control panel, just the email notification. Therefore is was necessary to include the hidden field to record the entry title. Hope that all makes sense.


How to Properly Use Controller and Service in Custom Plugin I am making some progress with creating a custom plugin, and am curious as to whether I am following proper "Craft standards". Here is my scenario:

A user needs to submit a one field form that contains their email address. Upon button click, I would like to prevent the default action, and send the email address via AJAX to my plugin for processing.

After reading through the Craft Plugin Docs, I am under the impression that my plugin requires the following functionality(and in this order).

Send email address via AJAX to a Controller.
The controller will then extract the email, and send it off to a
Service.
The Service, is where I should write my code that connects to the MailChimp API
Send the result of whether the Mailchimp API request was successful from the Service, back to the Controller.
The Controller will then send back the response to my JavaScript, where I will ultimately display a success or error message to the user.

I have been successful in sending an AJAX request from my JavaScript code to my Controller via the following code, and receiving some dumby test text.

function sendAjax() {
    var xhr = new XMLHttpRequest()
    xhr.open('POST', siteUrl + 'ajax/ajax-mailchimp.html')
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8')

    xhr.onload = function() {
      if(xhr.status === 200) {
        console.log(xhr.responseText)
      }
    }
    xhr.send(encodeURI('action=/craftMailchimped/submittal/receiveEmail&email=fakeemailaddress@yahoo.com'))
  }

In my controller, I have the following:

<?php
namespace Craft;

class CraftMailchimped_SubmittalController extends BaseController {

    public function actionReceiveEmail() {
        echo 'Wuzup?';
    }
}

In case you are wondering what 'ajax/ajax-mailchimp.html' is, its an empty template file, with no code in it. I did this, because I didn't really know what to put in as the URL in the xhr.POST method in my JavaScript code.

I am concerned I am not going about this in the right way, as I wouldn't even know how I would extract the email address inside my controller.

Any help on this?

My Form HTML for reference:

<form id="updates" class="mchimp">

      {{ entry.connectNewsletterCta }}

      <input type="email" placeholder="Enter your email" required>
      <button class="btn">
        {{ entry.connectNewsletterButtonText }}
      </button>

  </form>

It's actually quite simple.
First you need a form:

<form method="post" id="myForm">
    <!-- insert your route as an action parameter in camelCase -->
    <!-- pluginName/controllerName/methodName -->
    <input type="hidden" name="action" value="craftMailchimped/submittal/receiveEmail">
    <input type="text" name="email">
    <input type="button" id="submit" value="Submit">
</form>

Then you have your javascript (I'll use jQuery ajax for that)

$("#submit").click(function(e){
    e.preventDefault();
    $.ajax({
        type: "post",
        url: '', //<- leave the url blank.. always...
        data: $("#myForm").serialize(),
        success: function(data){
            console.log(data);
            if(data.success === true){
                alert(data.message);
            }else{
                //display your data.errors here
            }
        },
        error: function (XMLHttpRequest, textStatus) {
            console.log("Status: " + textStatus);
        }
    });
});

And your controller and this model

public function actionReceiveEmail() {
    $response = [
        'success'   => false,
        'message'   => Craft::t('something went wrong')
    ];

    $emailModel = new CraftMailchimped_EmailModel();
    $emailModel->email = craft()->request->getParam('email');

    if(craft()->yourServiceName->subscribe($emailModel)){
        $response['success'] = true;
        $response['message'] = Craft::t('wuhu great :D');
    }else{
        $response['errors'] = $emailModel->getErrors();
    }

    $this->returnJson($response);
}

Your service could contain this method

public function subscribe(CraftMailchimped_EmailModel $emailModel){
    if($success = $emailModel->validate()){
        //make your API calls
        $response = ......;
        if($response['error'] === 444){
            $emailModel->addError('email', Craft::t('Email is already taken'));
            $success = false;
        }
    }

    return $success;
}

So you are totally right with your points. In case you want to see how to manage records in your database take a look at this plugin Click I created it for learning purposes for someone else in this thread. Maybe you'll find it useful to learn some stuff like fetching objects from the database and inserting.

Edit
to resume

You should always leave the url blank, define an action parameter for your route. The request type does not matter, it's the same for ajax and normal requests
Your Route is always pluginHandle/controllerName/functionName in camelCase
Your messages and responses should always be defined in your Controllers, your Services are just for logic that return true or false (or some objects like craft()->entries->getEntryById()), you can create models with validations for error messages you can use them like that: (validators will provide the translated messages)

// in your controller
$mailChimpModel;
if(craft()->mailchimp->subscribe($mailChimpModel)){
    $response['success'] = true;
}else{
    $response['errors'] = $mailChimpModel->getErrors();
}

$response['errors'] is an array with all field handles and the corresponding translated error messages like 'email' => ['This Mail is already in the list']
Crafts RequestService has all the methods you need to access the request variables. Those values are all safely escaped and secure, so you can be sure there won't be security measures. You can access parameters with craft()->request->getParam('key', default value);


Login Modal - How to handle incorrect password / credentials? I'm developing a site in Craft 2, using a modal to display the login form. The modal can be seen by clicking the Login button at top right.

I'm essentially using the form as outlined in the Craft 2 docs here. But it's not set up to work properly with a modal behavior. Currently, if a user types the wrong password credentials, the form still executes, refreshing to the homepage. It's only when the user once again clicks the "login" button that the modal is once again revealed, now showing the error message.

How might I check whether the user's credentials are valid before submitting the form? If credentials are incorrect, I'd like to prevent execution of the form and keep the modal on screen for the user to try again.

Thanks

You may use some ajax to send your form so your modal will not validate and/or close and your page wont reload.

Here's a working example of what you will need to do in JS (this example use jQuery):

$('#yourFormId').submit( function (e ) {
      e.preventDefault();
      var data = $(this).serialize();
      $.ajax({
        method: 'POST',
        url: '/',
        data: data,
        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
      })
    .success(function(data) {
          console.log('success', data);
    })
      .error(function(data) {
        console.log('error', data);
      });
    });

If validation errors happen, you will see that in the data object folowwing the .error.


some assets have volumeId set to NULL in database I noticed that some of my assets have volemeId column set to NULL in the database table assets.

Is it normal? Should I attach them manually to some volume?

Is it normal?

Yes. It's a nullable column in the database.

  Should I attach them manually to some volume?

Nope. There are many scenarios where Craft creates temporary volumes and temporary assets where they won't belong to an "official" volume.


Craft CMS V3 Create New User Having difficulties creating a new user in a custom controller, here's my implementation:

use craft\records\User;

$user = new User;
$user->firstName = $userData['firstName'];
$user->lastName = $userData['lastName'];
$user->username = $userData['loginName'];
$user->email = $userData['loginName'];
$user->password = $userData['password'];

$response = $user->insert();

Response:

SQLSTATE[HY000]: General error: 1364 Field 'id' doesn't have a default value
The SQL being executed was: INSERT INTO `craft_users` (`firstName`, `lastName`, `username`, `email`, `password`, `dateCreated`, `uid`, `dateUpdated`) VALUES ('Tristan', 'Gemus', 'registertest@gmail.com', 'registertest@gmail.com', 'password', '2019-03-28 15:53:10', '85468ad6-63cc-499d-baf4-32aaaf55bfb2', '2019-03-28 15:53:10')

The response returns false. Thoughts?

Take a look at Craft's own UsersController->actionSaveUser().

You're probably looking for something closer to this:

$user = new craft\elements\User();

$user->firstName = $firstName;
$user->lastName = $lastName;
$user->username = $userName;
$user->email = $email;
$user->password = $password;

if ($user->validate(null, false)) {
    Craft::$app->getElements()->saveElement($user, false);
}


Trouble with merging Numbers in an Advanced Search I have a search form where a user can enter width, height and depth and the search results will return any item that will "fit" into those dimensions. It works, but for some reason only if the depth is not set.

Form:

<input type="search" name="q" value="{{ craft.request.getParam('q') }}">
Width
  <input type="number" name="w" value="{{ searchWidth }}">
Height
  <input type="number" name="h" value="{{ searchHeight }}">
Depth
  <input type="number" name="d" value="{{ searchDepth }}">

The resulting query looks like this search3?q=&w=43&h=44&d=1000

For Results

{% set queryParams = {
  section: 'products',
  order: 'postDate desc',
  limit: 15
  } %}

{% set searchWidth = craft.request.getParam('w') %}
{% set searchHeight = craft.request.getParam('h') %}
{% set searchDepth = craft.request.getParam('d') %}

{% if searchWidth > 0 %}
  {% set finalWidth = searchWidth + 1 %}
  {% set queryParams = queryParams | merge({
    width: '<= ' ~ finalWidth
    }) %}
{% endif %}

{% if searchHeight > 0 %}
  {% set finalHeight = searchHeight + 1 %}
  {% set queryParams = queryParams | merge({
    height: '<= ' ~ finalHeight
    }) %}
{% endif %}

{% if searchDepth > 0 %}
  {% set finalDepth = searchDepth + 1 %}
  {% set queryParams = queryParams | merge({
    depth: '<= ' ~ finalDepth
    }) %}
{% endif %}

Which I merge with my original search:

{% set searchQ = craft.request.getParam('q') %}
{% if searchQ is not empty %}
{% set queryParams = queryParams | merge({
  search: {
  query: searchQ,
  subLeft: true,
  subRight: true
   }
 }) %}
{% endif %}

Everything works fine. If I enter 44 for h and 43 for w it does what it should, if finds all items smaller than the width and height. If I add something in the d, even 1,000 I get 0 results. If I output {{ finalDepth }} somewhere in the template it outputs without issue, but it finds 0 results when something is entered in the d search.

All three fields are number fields named width, height and depth. I have checked and rechecked and I am at a loss.

Rename the field handle to something else, depth is a deprecated attribute for ElementCriteriaModel.


Show products based on custom field I have a custom field enabled on a product - it is a user field that associates a product with a user.

What would the correct setup be to only display products that pertain to the currentUser - as this would match the custom user field?

Depends on whether the user field is on the product or a variant.

If the custom field is on the product:

{% set products = craft.commerce.products.relatedTo({
    sourceElement: currentUser,
    field: 'userFieldName'
}) %}

If the custom field is on the variant:

{% set variantCriteria = craft.commerce.variants.relatedTo({
    sourceElement: currentUser,
    field: 'userFieldName'
}) %}

{% set products = craft.commerce.products.hasVariant(variantCriteria) %}


How do you add tags to tag field when saving an entry? I'm working on a custom import plugin which needs to import a load of content to fields including categories and tags. Categories is working fine using a comma separated list of category ids:

        $entry = new EntryModel();
        $entry->authorId  = $eventObject->author;
        $entry->enabled   = true;
        $entry->postDate   = $eventObject->postDate;
        $entry->getContent()->title = $eventObject->title;
        $entry->getContent()->setAttributes(array(
            'slug' => $eventObject->slug,
            'locationText' => $eventObject->locationText,
            'date' => $eventObject->eventDate,
            'overview' => $eventObject->overview,
            'eventWebsite' => $eventObject->eventWebsite,
            'eventCategories' => $eventObject->categories,
            'location' => $eventObject->location,
            'eventTags' => 1453,
        ));

I just can't get tags importing at all, also need to create new tags where a tag doesn't already exist! Testing with the id 1453which is an existing tag id.

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

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

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

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

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

// ...

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

// ...

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


Output Locale URLs in hreflang Just adding hreflang tags to the head on all pages of my multi-locale site...

{% for locale in craft.i18n.getSiteLocales() %}
    <link rel="alternate" href="{{ entry.url }}" hreflang="{{ locale }}">
{% endfor %}

Nearly there, but obviously this outputs my list of locales with the entry url for the current locale only. What I need is to output the entry url for each locale. Anyone done this before?

Have you tried using {{ craft.entries.id(entry.id).locale(locale.id).first().url }} inside the for loop you have made?


Slow performance/Long response times I am running Craft CMS 3 and Commerce 2 on a virtual machine composed of Centos 7, Apache 2.4, PHP 7.2 and MySQL 5.7.22. It seems almost impossible working with the control panel with such huge response times:

http://craftcms/admin/dashboard takes 2.6s to load. (500ms on localhost MAMP)
http://craftcms/admin/settings takes 3s to load (350ms on localhost MAMP).

I've tried the following stuff:

assigned php memory_limit to 512M in php.ini
connecting to MySQL using 127.0.0.1 instead of localhost (.env)
set HostnameLookup Off in apache httpd.conf
set ServerName 10.10.0.20 in apache httpd.conf
accessing the page via 10.10.0.20 instead of virtual host craftcms
removed usage of .htaccess file following this guide
unloaded unnecessary apache modules
disabling cgi apache module

Looking at the network statistic the TTFB takes 4.28s and whole page loads in 5.01s. I am assuming it's the configuration issue since when running MAMP on windows everything responds a lot quicker. Any ideas what I should be looking at or is this performance as intended?

What strikes me the most is that phpmyadmin responds very quickly. I tried running a standalone (non-Craft) page with and without PHP. Page with PHP loaded cca 20ms longer. I would assume PHP doesn't cause mentioned problems.

craftcms.conf:

<VirtualHost *:80>
    DocumentRoot "/opt/webroot/craftcms/web/"
    ServerName craftcms
    ErrorLog "/var/log/httpd/craftcms-error_log"
    CustomLog "/var/log/httpd/craftcms-access_log" combined

    <Directory "/opt/webroot/craftcms/web/">
        Options FollowSymLinks
        AllowOverride None

        ## Removes index.php from Craft URLs ##
        <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>
    </Directory>
</VirtualHost>

Update:

After disabling unnecessary apache modules responses are a lot faster. I also tried using worker and even MPM, changes in timings were neglectable.

Update2:

Craft3 debug toolbar shows the following critical timings when loading settings page:

11:43:00.140  1098.4 ms   craft\web\twig\Template::display    settings
11:43:00.154  1083.8 ms   craft\web\twig\Template::display    →_layouts/cp
11:43:00.374  863.6 ms    craft\web\twig\Template::display    →→_layouts/basecp
11:43:00.375  862.4 ms    craft\web\twig\Template::display    →→→_layouts/base

This is output of same data on localhost:

11:52:46.713  124.0 ms    craft\web\twig\Template::display    settings
11:52:46.716  121.4 ms    craft\web\twig\Template::display    →_layouts/cp
11:52:46.743  94.4 ms craft\web\twig\Template::display    →→_layouts/basecp
11:52:46.743  93.9 ms craft\web\twig\Template::display    →→→_layouts/base

The difference in timings is quite big.

So something is definitely wrong; you should be seeing response times of around 300-500ms or so. What I'd suggest doing is profiling things on the Craft side as per the Profiling your Website with Craft CMS 3’s Debug Toolbar article.

You'll at least be able to see exactly what the bottlenecks are from a Craft perspective, and then see how much overhead is being added by the webserver.

If you find that it's slow on the Craft end of things, you may consider making sure that you are properly utilizing the cache tag


Send a block... into a block? I'm fiddling around with Twig and CraftCMS, trying to create a component-based structure... of sorts.

All good so far, except this one thing I got stuck on.

Here's an excerpt from my main layout:

<body>
    {% include 'components/header.twig' %}

    {% block content %}
        woops...
    {% endblock %}

    {% include 'components/footer.twig' %}
</body>

Which currently works.

But, I'd like to do something like this...

<body>
    {% include 'components/header.twig' %}
    {% include 'components/main-wrapper.twig' %}
    {% include 'components/footer.twig' %}
</body>

Where the main-wrapper.twig is like this, for example:

<main class="main">
    {% block content %}
        woops...
    {% endblock %}
</main>

But it does not work. "woops..." from main-wrapper.twig is displayed.

I've tried a different route without success as well:

<body>
    {% include 'components/header.twig' %}

    {% embed 'components/main-wrapper.twig' %}
        {% block children %}
            {# I want to have the block content here... #}
        {% endblock %}
    {% endembed %}

    {% include 'components/footer.twig' %}
</body>

Where the main-wrapper.twig has a block named children instead... but no dice.

It does appear that what I'm trying to do is not possible, which is why I'm asking here as a last resort :)

EDIT:

For those interested, here's what I ended up with, stripped for clarity:

{# default.twig - default layout #}

<!DOCTYPE html>
<html>
    <head>
       ...
    </head>
    <body>
        {% include 'components/header.twig' %}
        {% block wrappedContent %}{% endblock %}
        {% include 'components/footer.twig' %}
    </body>
</html>

{# regular.twig - base page referred in the admin panel #}

{% extends "components/main.twig" %}

{% block content %}
    --- stuff for a page ---
{% endblock %}

{# main.twig - wrapper component! :D #}

{% extends "layouts/default.twig" %}

{% block wrappedContent %}
    <main class="main">
        <div class="main__wrapper">
            {% block content %}
                wooops...
            {% endblock %}
        </div>
    </main>
{% endblock %}

It seems to be what you need is Twigs extend functionality. What you have here is a very common template structure so there is nothing out of the ordinary!

Firstly, going from your code I'd recommend your main layout template file looks something like this. The idea here being that these elements will not change for each page, but the content or information displayed inside them will. This template file is where you would also load in your CSS, Javascript etc.

    {% include 'components/header' %}

        {% block content %}{% endblock %}

    {% include 'components/footer' %}

Say you have a page that will sit on www.yoursite.co.uk/about. You could create a template file in your templates folder called about.twig, and to use your base template file it would look something like this:

{% extends "path/to/main/layout" %}

{% block content %}

The content for your about page

{% endblock %}

Hope that clears it up for you!