How can I make an entries query based on currentUser is author or relatedTo currentUser My project requires a notifications area. I want to list all notification entries that were created by currentUser or sent to currentUser.
I can do created by = craft.entries().section('thename').authorId(currentUser.id).all()
I can do sent to = craft.entries().section('thename').relatedTo({ targetElement: currentUser, field: 'thefield' }).all()
But is there a single query that will get both?

A blanket relatedTo query should do the trick.
craft.entries().section('thename').relatedTo(currentUser).all()


Craft 3 vs Apache directory structure I am new to Craft CMS and am struggling with what and how to get the correct files in the right places. I started out with a LAMP stack on a Ubuntu 18.04 Digital Ocean droplet and proceeded with the Craft CMS setup. Currently I get a 404 ERROR stating "The requested URL /index.php was not found on this server".

Where should I put it? Does this answer help and still work in this case : https://stackoverflow.com/questions/5891802/how-do-i-change-the-root-directory-of-an-apache-server/23175981#23175981?

My VH file:

<VirtualHost *:80>
     ServerAdmin admin@example.com
     DocumentRoot /var/www/html/craftcms
     ServerName example.com
     ServerAlias www.example.com

     <Directory /var/www/html/craftcms/>
          Options FollowSymlinks
          AllowOverride All
          Require all granted
     </Directory>

     ErrorLog ${APACHE_LOG_DIR}/error.log
     CustomLog ${APACHE_LOG_DIR}/access.log combined

     <Directory /var/www/html/craftcms/>
            RewriteEngine on
            RewriteBase /
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteRule ^(.*) index.php [PT,L]
    </Directory>
</VirtualHost>

If the craftcms folder is more or less the out-of-the-box Craft 3 installation, you should be able to just point your Directory blocks and DocumentRoot at /var/www/html/craftcms/web!

Only the web folder is intended to be public—everything else should be hidden, above the web root—think of it as sandboxing access to just one folder of your application.


Dynamic route returning 404 error I've set up some dynamic routes to work with categories, so for example the route is set up to load a specific template if the work category appears in the URI, thus:

news-events/image-gallery/category/[slug]

However, if I test with the following URL I get a 404 error:

/news-events/image-gallery/category/drama

Other dynamic routes are working fine. Thoughts on how to debug/resolve appreciated.

Cole

I ran into a similar problem with categories and routing a while ago and Marion's answer in this thread worked for me

How would I include the first category slug in the section's entry URL format?

Darrell


Matrix Field Count Records Is there an easy way to return the total number of entries in a Super Table within a Matrix field?

You mean how many rows the table has?

{{ matrixblock.superTableFieldHandle|length }}

Or the number of blocks of a matrix field?

{{ parent.matrixFieldHandle|length }}

To get the number of blocks for each row

{% for row in entry.superTableMatrix %}
    {{ row.matrix|length %}
{% endfor %}


How do you create a front-end form for users to submit content? I'd like to create a form for users to load events (that I will moderate and publish).

How do I do this?

If the users are authenticated and have permission to post to the event section, you would use an entry form to accept posts from the front end.

Example from the above linked page...

<form method="post" action="" accept-charset="UTF-8">
    <input type="hidden" name="action" value="entries/saveEntry">
    <input type="hidden" name="redirect" value="viewentry/{id}">
    <input type="hidden" name="sectionId" value="10">

    Title
    <input id="title" type="text" name="title">

    Body
    <textarea id="body" name="fields[body]"></textarea>

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

Deliberately removed from the example above is this <input type="hidden" name="enabled" value="0">, since it'd be redundant and make it more obvious how one might tamper with the form. Setting enabled to 1 would allow submitted posts to go live immediately.

If you'd like to accept guest entries you can use Pixel and Tonic's GuestEntries plugin. Keep in mind that the submissions will still be assigned to the Craft author (user with appropriate permissions) that you designate. The front-end form would look nearly identical, with a hidden action of guestEntries/saveEntry...

<form method="post" action="" accept-charset="UTF-8">
    <input type="hidden" name="action" value="guestEntries/saveEntry">
    <input type="hidden" name="redirect" value="viewentry/{id}">
    <input type="hidden" name="sectionId" value="10">

    Title
    <input id="title" type="text" name="title">

    Body
    <textarea id="body" name="fields[body]"></textarea>

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

The plugin's settings let you define default authors and entry statuses for each channel:

GuestEntries also adds a guestEntries.beforeSave event that you can hook into with your own plugin and further act on submissions before they're added to the database.


Commerce Product - show shipping category in template I have setup some Shipping Categories (8 weeks, 4 weeks etc) and these appear down the side bar of a product when editing in admin next to 'Shipping' . How do i bring this value out via a tag on a product page/template?

Product:

Shipping Category: {{ product.shippingCategory.name ?? 'None' }}

Tax Category: {{ product.taxCategory.name ?? 'None'}}

Variant:

Shipping Category: {{ variant.product.shippingCategory.name ?? 'None' }}

Tax Category: {{ variant.product.taxCategory.name ?? 'None' }}


Pass hardcoded path to getUrl() I am migrating a static HTML site to Craft, and trying to apply image transforms to specific images without running them through a Craft field.

In other words, I have the image path hardcoded in the template, and would like to apply an existing transform to it.

I have tried to set my image path as a Twig variable and then call getUrl('medium') on that - but i get the error because I am passing a String value.

I also tried to store the image path in an array variable, but it's not working either.

Is there anyway to achieve this and pass a static path to getUrl()?

I don't think that Craft can do this natively, and would guess that it needs an AssetModel in order to determine where to create the image transforms, etc. Your best bet would be to add the images to Craft.

Assuming the images are stored locally, this is pretty easy:

create an asset source that points to the folder where your images are stored
go to settings and update asset indexes for the new asset source

If your filenames are all unique then you can reference the image by filename in your template:

{% set asset = craft.assets.filename('filename.jpg').first() %}
{% if asset is defined %}
    <img src="{{ asset.getUrl('medium') }}">
{% endif %}

Otherwise, you will need to add folderId to the criteria, or add the asset to the current entry via an assetField and reference through the assetField.

(Another option, although not recommended, would be to add the images to an asset source as above; update indexes; then create a template that just renders all images in the asset source (using source('assetSource') criteria), rendered with the given transform. You can then just hard code the path to the image using the image transform folder ('myimages/_medium' folder). But you could just as easily use photoshop for this.)


Can I manage/change the default flash message text? I am looking to customise the default flash message text for certain behaviours but cannot seem to find any reference to them in the code or control panel - does this exist anywhere? And could it be made editable in the CP?

I know I could do something like this but it feels hacky:

{% if craft.app.session.getFlash('notice') == 'User registered.' %}
  {% do craft.app.session.setFlash('notice', 'User registered - please check your email to activate your account.') %}
{% endif %}

Thanks.

You could for example just edit the translation file with the specific user registered flash message.

You can read more about the static translation in the docs.


Where are Matrix Entries Fields Relationships in the Database? I can see the simple matrix field data in the craft_matrixcontent_MYMATRIXtable.

craft_matrixcontent_MYMATRIX
---------------------------
id | elementId | locale | field_BLOCKTYPE_FIELDHANDLE | field_BLOCKTYPE_FIELDHANDLE | dateCreated | dateUpdated | uid

If I need to query upon those fields, I can thanks to some of the great posts to this site. But those fields are simple text fields.

I have an Entries field in my matrix. Where can I find this relationship in the database? It doesn't exist in the craft_matrixcontent_MYMATRIX table.

I think I've figured it out. The sourceId of the craft_relations table is the elementId of the custom matrix table. And the targetId of the craft_content table is the elementId of the `craft_content table.

Code example

Here's what I was trying to do. I needed to filter entries based on a field value in an Entries matrix field on another entry. Whew.

$criteria = craft()->elements->getCriteria(ElementType::Entry);
$criteria->section = 'FIRSTCOOLTHING';

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

$query->join('matrixblocks matrixblocks', 'matrixblocks.ownerId = entries.id');
$query->join('matrixcontent_MYMATRIX matrixcontent_MYMATRIX', 'matrixcontent_MYMATRIX.elementId = matrixblocks.id');
$query->join('relations relations', 'relations.sourceId = matrixcontent_MYMATRIX.elementId');
$query->join('content SECONDCOOLTHING', 'SECONDCOOLTHING.elementId = relations.targetId');

$query->andWhere('SECONDCOOLTHING.field_FIELDHANDLE = '.$THINGTOSEARCHFOR);

$query->order('title asc');

$queryResults = $query->queryAll();
return EntryModel::populateModels($queryResults);


Craft Commerce 2 - extend Order details page Let's say we're on the order details page with the 3 tabs - Order Details, Transactions, Status History

How do I add an extra tab with content?

Craft V3 / Commerce V2

Thanks

To include additional tabs you can include several different field layout tabs in your field layout designer. When you open /admin/commerce/settings/ordersettings you can see the field layout for your orders. There you can click on + New Tab and drag and drop the fields you like


Calling variables, dynamically I've got a parent template which contains the following code:

{% include '_layout' with {'countryCode': 'au'} %}

I have a global set with the handle au_Variables, and within that a field with the handle vimeoVideoId_au

The problem I'm having is with trying to render the following global: {{ au_Variables.vimeoVideoId_au }} dynamically, using the countryCode.

I've tried

{% set videoId = countryCode~'_Variables.vimeoVideoId_'~countryCode %}

And then outputting {{ videoId }} but all I get is the string au_Variables.vimeoVideoId_au, not the rendered global.

Any ideas how to do this in Twig?

Not sure if you saw this, but you may also be able to use the Twig attribute function:

{{ attribute(array, item) }}

Pretty straightforward, here's the official docs page...


Sprout Email variables in custom fields aren’t replaced after update I updated Sprout Email from 4.0.8 to 4.4.9, along with Craft now being at 3.6.15.
Since then the variables inside my (redactor) custom field aren’t replaced anymore. The email template ist basically the example template outputting basic html and: {{ email.emailBodyHtml_de }}.
The content of email.emailBodyHtml_de contains things like {firstName} and {{ siteUrl }}, but they are not replaced with the User Model values (the notification is triggered at user save).
When I add {{ object.firstName }} to the html template, it outputs the name correctly, but the variables coming from the custom field aren’t replaced.
Has something changed that I am missing?
Any hint is much appreciated.
Cheers,
Mark

This was a change introduced in v4.2.0 to address a security vulnerability. It was noted in the changelog and upgrade notes.
The Subject and Default Body will still render values dynamically but any personalization needed for custom fields would currently, as you've discovered, need to be handled in the templates.
I do have plans to review this more closely and see if I can find a workaround for custom fields, but for the time being, had to revert to the support above for security considerations.


Plugin custom edit page layout Im making a plugin and have come to the stage where im making an edit form, for the plugin.

I would like the layout to look like this, with 2 columns and tabs above the left column.

My, question is what is the best way to achive this? currently im using extending _layouts/cp in my template, the page look like this.

thanks for your help

It doesn't appear there is an easy way to do this by extending that template. If you take a look at the template templates/entries/_edit.html you will see how the create/edit entry screen creates this view. It is extending _layouts/cp, but it's overriding the main Twig block to do some custom stuff. You can include the tabs in your main block like so:

{% block main %}

        {% include "_includes/tabs" %}

{% endblock %}


date_modify relative time I'd like to reopen this question:

The answer was a plugin called Nice Time

But This plugin is depricated and the creator stats that this functionality is acheivable via the date_modify filter.

Yes okay, but how?

I have a event archive where I want to show "This event happend xy days ago".

There is a time_diff filter in twig. But it seems as if this is not activated in craft.

You could use the diff method to get the number of days between two dates. So for example:

{{ date(entry.dateCreated|date('c')).diff(now).days }} days ago

In my example between today (using now) and the entry.dateCreated.

There is a explanation as to why you need to wrap the first date in the date filter here, which is where I got the answer from!


How to reference a folder inside of a volume, Craft 3 How do I reference a specific folder (by name) inside of a specific volume.  I cannot use the folder ID, I must use the folder name because the name of the folder is a variable related to specific entries.

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

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

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

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

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

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


How to set Commerce 2 confirmation email in .env file? We're just in the process of upgrading from Craft 2 with Commerce 1 to Craft 3 and Commerce 2. One of the issues we had before was that the client was getting confirmation emails for test orders.

Is it possible to set the confirmation email destination in the .env file so our team can set themselves as the target emails for their own local testing?

Thanks!

Could you use the testToEmailAddress config setting in your config.php? As this will send all emails to a single address.

'testToEmailAddress' => getenv('TEST_TO_EMAIL_ADDRESS')

Then in your .env set:

TEST_TO_EMAIL_ADDRESS="email@email.com"


Problem updating to latest version of Sprout SEO I updated Sprout SEO on our development site, but get the following error when trying to view the site:

Craft\TemplatesService and its behaviors do not have a method or closure named "setTemplatesPath".

I can access the Control Panel, but navigating within the Sprout SEO tab gets me the following error:

Unexpected token "punctuation" of value "?".

We are not on the latest version of Craft (Pro 2.5.2754) for a few reasons - not ideal, I know. Can anyone let me know where I should look to resolve this, or if it's a compatibility issue?

We were able to recreate your issue. The error caused by an older version of Twig.

The error should be fixed by upgrading to Craft 2.6.2771


Entries from different category levels brought together I have an issue with categories with different levels:

I have a group of categories which have a structure like this:

First form:
1.0 Group –
1.1 Subgroup –
1.2 Items in subgroup

Second form:
 - 1.0 Group –
   1.1 Items in Group

In some groups are subgroups in others aren't. But I need to list all the items, regardless if they are in a subgroup or not. How can I adress them correctly. Can I do an if statement like: if there is no 1.2 level, take the 1.1 level and treat it like a 1.2 level?

How can I do this?

What you want is the categories that do not have descendants. I would loop over all the categories, and skip the ones with descendants. The test to skip is:

{% if not category.hasDescendants %} ... {% endif %}

Documentation for hasDescendants.


Running Craft CMS 2 on MySQL 8.0+ (Any major considerations?) Yes, that's not a typo. This is for a Craft 2 site (long story). Because MySQL 5.6 is EOL in a few weeks, I am validating how feasible it can be to run under MySQL 8.0, there's not really any option to go 5.7, as our upstream provider provisions MySQL 8 by default now.
I'm asking mainly for anyone else who may have looked at this in addition to validating my own testing and what I have found. I provisioned a NGINX, PHP 7.3 FPM, MySQL 8.0 environment and did initially find several problems with MySQL 8 and Craft 2 that mean you couldn't get past the "cannot connect to DB error" even though the DB credentials were fine. Confirming that it wasn't me being dumb with wrong .env credentials I downgraded my DB container back to MySQL 5.7 and everything immediately worked, so it confirmed that MySQL 8 was the issue.
I eventually wrote a simple PDO MySQL test outside of Craft and found some errors being thrown which we not visible when going to /admin/install (I may have got more clues looking at the logs, but sometimes, you need to sanity check yourself!). Which thankfully did then explain why things were failing and there were several issues in the end.
Default authentication plugin changes
I found Craft 2 couldn't even connect with PDO because of the default authentication plugin change for new MySQL 8 servers. Because this environment was provisioned with docker the default setting was caching_sha2_password. Older databases probably won't hit this.
https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_default_authentication_plugin
This required the following change on the DB user however:
ALTER USER 'db_user' IDENTIFIED WITH mysql_native_password BY 'password';
FLUSH PRIVILEGES;

db_user - MySQL database user
password - MySQL database user password

SQL mode
SQL mode requires the following modification, because it references a removed option in MySQL 8 which will break the DB connection as well. From the original topic on Craft 2 on MySQL 5.7.5+: Getting this SQL Error: GROUP BY incompatible with sql_mode=only_full_group_by
SQL mode needs to be set to:
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

NO_AUTO_CREATE_USER needs to be removed from initSQLs or any .cnf configuration for MySQL 8.0+.
After that, this appears to allow Craft 2 to connect properly.
General issues/problems?
So once I'd figured out why Craft 2 was having a hard time connecting to the DB backend, I pulled a DB export from our currently live environment using MySQL 5.6 and imported it into MySQL, aside from a minor issue with row sizes on the craft_content table (not MySQL 8 specific another issue) the DB seems to be OK and running under MySQL 8 fine. I haven't extensively tested all functionality yet, but for the most part it does seem to be running OK, no server errors when performing some save actions and such.
Are there any major considerations or issues specifically for Craft 2 and MySQL 8 that should be monitored?

Sounds like you've overcome the obvious ones already.
We've done some limited testing with the latest Craft 2 release on MySQL 8+ and no other red flags have been raised from our experience.


Can I limit the available styles from the rich text field? I want my client to have the ability to do things like bold, italicize, and hyperlink text, but I would rather them not be able to use some of the other rich text field abilities.
I see from this question that it may be possible using a 'redactor' plugin? Where is the best place to find information on this?
Is it possible for some Rich Text Fields to have more styling capabilities than others?

Redactor is the name of the Rich Text field itself, as this is a 3rd party component Craft has taken great use of!

With Craft you are able to create custom Redactor configurations whereby you have control over which options you would like useable (bold, italic etc), and these can be set on a per-field basis.

Have a look at the Craft site for details on how to set your own custom Redactor configurations: http://buildwithcraft.com/docs/rich-text-fields#redactor-configs

When you edit a Rich Text field in Craft you will see a 'Config' dropdown. These are the files you have created in craft/config/redactor (see above link for details)


After upgrading Craft CMS, is there a receipt to print out? The in-app process of upgrading a Craft licence is smooth, but leaves no paper trail (not even a confirmation email).
All I've found is a date of registration in the admin panel sidebar, without even stating the Craft licence type (client or pro).

Is there away to obtain a somewhat formal proof of purchase, like a receipt, that I can pass along to a client?

You should receive an email after purchasing a Craft license. Maybe double check your email details and/or your spam folder.

Anyway, if you email the guys at support@buildwithcraft.com they will sort out a receipt for you.


Running into permission issues using Vagrant on Ubuntu I am having issues running CraftCMS in a vagrant environment.

For reference:
    I am using ubuntu 17.04
    Vagrant version 1.9.5
    ubuntu/xenial64 (virtualbox, 20170525.0.0)
    Relevant initial provisioning here

After the vagrant box is booted up I wget the lastest CraftCMS files.
I then run chmod -R 777 /craft/app/ (+/config/ /storage/)

From that point on I would normally be able to complete the installation but instead I am met with a RuntimeException (paste here, screenshot here)

I've tried setting the permissions inside and outside of the environment. I have also tried changing ownership to www-data. And even put the user in the www-data group.

I'm pretty baffled, as I have no problems running my craft install on my production servers. Any help would be appreciated.

The article Local Development with Vagrant / Homestead I wrote is about Homestead (which is great), but much of it applies to Vagrant in general as well.

Included in it are some performance tips, as well as how to solve the filesystem permissions with vagrant-bindfs


Undefined class constant 'Client' Tried to update to new version. Website and admin went down, error message states "Undefined class constant 'Client'". How to solve this message?

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

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

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


Nested categories in URL slug I'm new to Craft and exploring whether it's worth my team moving our existing, deeply-structured content site onto Craft CMS.

We have a heavily nested sitemap at the moment with 6 top-level categories and up to 5 nested levels of subcategory, eg:

- Cat 1
    - Sub Cat 1A
    - Sub Cat 1B
        - Sub Sub Cat 1Ba
        - Sub Sub Cat 1Bb
    - Sub Cat 1C
- Cat 2
    - Sub Cat 2A
    - Sub Cat 2B
- Cat 3
    - Sub Cat 3A
        - Sub Sub Cat 3Aa
    - Sub Cat 3B

I'd like these categories reflected in URL slugs for entries, eg. /cat-1/sub-cat-1-a/ and /cat-3/sub-cat-3-a/sub-sub-cat-3-a-a etc.

I made a Category Group called "Navigation" then made a bunch of categories and nested sub-categories. I added a section and made sure it had a Category field in its Entry Types.

What I can't do, though, is get those URLs to work. I've tried following the instructions from Brandon Kelly here but I only ever get URLs generated with the top-level category slug (eg. /cat-3/{entry.slug}.

Oddly, when I select a category for an entry, no matter how many levels deep I select from, the category shown when I edit the post is always the top-level one, not the one I actually selected. Could this have something to do with it? I've ticked the "Categories in this group have their own URLs" option when editing my navigation Category Group.

The reason why you only see the top level category in your category field and why your URL's only use the top level category is probably because you set the "limit (number of selectable categories)" to 1 in your category field settings.
That way you can only choose one category but it also only selects the top category.

Pretty irritating, I know. I had some issues with it too.

So clear that limit and it should work.
I don't have a solution to limit the amount of categories selected without that option being checked. I guess you can adopt your templates for multiple categories or write a plugin to do some extra checking when selecting categories.


Entries loop that doesn’t take the status into account? How do I create an entries loop that will pull content even if the entry in the loop is not set to Live?

e.g., I have a Matrix so a user can select entries to feature in a slider. They want the slider to feature entries even if the entry itself is currently hidden/unpublished.

{% for caseStudy in entry.featuredCaseStudies %}

            {% if caseStudy.status == 'live' %}{% endif %}

            {% if caseStudy.status == 'live' %}{% endif %}

{% endfor %}

This works only in as much as the anchor is only output if the linked entry is live. But I can't get it to spit out the image; presumably because the entry isn't live.

Short answer

Change this line:

{% for caseStudy in entry.featuredCaseStudies %}

to:

{% for caseStudy in entry.featuredCaseStudies.status(null) %}

Long answer

If “featuredCaseStudies” is an Entries field, then typing entry.featuredCaseStudies will give you an ElementCriteriaModel object, configured to return all of the entries related to entry via that “featuredCaseStudies” field (using the relatedTo param). Just like the ElementCriteriaModel object you get when typing craft.entries, you’re free to chain in additional parameters after entry.featuredCaseStudies.

By default, entry-targetting ElementCriteriaModel objects will only return “live” entries – entries that are enabled, and whose Post Date is in the past, and whose Expiry Date is either not set or set in the future. You can alter that behavior using entries’ status criteria param. Setting it to null tells Craft to not factor entries’ statuses into the query whatsoever, which is what you’re looking for here.


Adding a random entry to an array I have a navi on which one entry consists of a random channel entry from one section among standard singles:

Single 1
Single 2
Random Channel entry
Single 3

I thought about something like this:

{% set randEntry = craft.entries.section('channelX').order('RAND()').first() %}
{% for navi in craft.entries.section(['single1', 'single2', randPortrait]) %}

{{ navi.title }}

{% endfor %}

This does not work. (no error, but the variable is simply ignored).

I found a solution to pass in the variable when looping trough the array

{% set randEntry = craft.entries.section('channelX').order('RAND()').first() %}
{% for navi in craft.entries.section(['single1', 'single2', randPortrait]) %}

{{ navi.title }}

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

{{ randEntry.title }}

  {% endif %}
{% endfor %}

But that's ugly. Is it possible to pass the whole thing into one array without conditional trickery?

You can use slice and merge filters to “insert” that random entry into your array of entries.

In the following example I’m using the id param to query for the selected entries and I’m also setting fixedOrder, as this returns the entries in the same order as the IDs entered into the id param.

{% set selectEntries = craft.entries.id('7, 2, 83, 9, 90').fixedOrder(true) %}
{% set randEntry = craft.entries.section('channelX').order('RAND()').first() %}

{% set navEntries = selectEntries[:2]|merge([randEntry])|merge(selectEntries[2:]) %}


Blitz Cache dynamic button I have a Blitz Cache but the only bit of dynamic data on the page is a "Follow" button which changes depending on if you're following this entry. Looking at their docs, I don't see a way of not caching a certain section or button?
{% if craft.follow.check({ elementId: entry.id }) %}
    favoriteRemove Brand
{% else %}
    favorite_borderSave Brand
{% endif %}

Is it possible to still make this dynamic?

Check out "Dynamic Content" in the "Advanced Usage" section of the Blitz docs:
https://putyourlightson.com/plugins/blitz#dynamic-content
Thus can be done with:
{{ craft.blitz.getTemplate('/template/name', { elementId: entry.id }) }}


Equivalent of "EE Pages" module in Craft? I'm struggling to find a solution for a clients request to be given complete flexibility to create new sections and pages from within Craft. Essentially I would create a series of generic page templates which the admin could then use to build out the site and I can use the Navee plugin to provide a way to create a custom navigation. But this does not change the URL of the entry of course. I suppose what I need is a version of the ExpressionEngine Pages module for Craft. Is there such a thing?

A common approach is to create a Structure for the pages, and use a Content Builder where you can use Matrix blocks of various types to allow the client to build out the pages as they see fit in the Structure.


How to extract static messages from templates into translation files? I use Craft on multilingual site and I'm having some difficulty in getting the static messages on templates added or changed on every translation file I have.

Is there any way to extract those static messages changed or not already translated from templates into all translation files?

I'm looking for a functionality like of "yiic message" which searches for messages to be translated in the specified source files and compiles them into PHP arrays as message source.

Update:

For Craft 3, we use the Yii 2 Inspections plugin for PhpStorm to do this now. https://plugins.jetbrains.com/plugin/9400-yii2-inspections

There is a translation inspection that will let you know which strings are missing translations and which translations are no longer in use.

Old:

We currently have our own command line tool that goes through all of Craft's files and extracts anything in Craft::t() (for PHP), and |t (for Twig) and Craft.t() for JavaScript.

What we would probably do is make that tool into a yiic command and update it to let plugins take advantage of it for their own files as well.

Will add it to the list.


Unexpected token "end of template" of value "" ("end of statement block" expected) Good afternoon,

I'm new in Craft so I installed this step-by-step and I tried to install this theme: https://github.com/duezerouno/0-201

After I did everything, I can see a template error on my site that shows the next: Unexpected token "end of template" of value "" ("end of statement block" expected).

Looks like the error is on the _head.twig file and says that:

<head>
{% block head %}
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>{% if title is defined %}{{ title }} - {% endif %}{{ siteName }}     </title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">

<link rel="apple-touch-icon" href="apple-touch-icon.png">
<link rel="home" href="{{ siteUrl }}">
<link rel="icon" href="images/favicon.png">

<link rel="stylesheet" href="/styles/app.css">

Anyone can help me with this?

Thanks in advance.

It looks like their "_head" template is missing the closing {% endblock %} at the end.


How can I perform a RegEx match in Twig? Is it possible to perform a RegEx match on a string in Twig?

I'm looking for something like this:

{% set string = "This is **string**. **wer**  qewr **234**" %}
{% set match  = string.matches(/([*][*])(.*)([*][*])/g) %}

Currently Twig uses regular expressions only with Comparisons:

{% if string matches '{^[\d\.]+$}' %}
    Do Stuff
{% endif %}

Craft itself currently doesn't have any custom Twig filters or functions either.

But there are third-party plugins which might help you:

Twig PCRE Filters
Low Regex


Craft CMS 3 data structure advice for vehicle make, model, trim, year tagging Hi i really would like some advise on best practices on setting up some data for my Craft APP.

Most of my documents will be linked to vehicle make/model/trim/year. EG Audi A5 Sport 2009-2016 and/Or Audi A5 Sportback 2017+ .

What would be the best way to do this? Would it be to create a new field type or use something like a table?

My First Idea was to do the following:

A Structure

Level 1 : Vehicle Make

Level 2 : Vehicle Model

Level 3 : Vehicle Trim

Then create a field (table) where i select either the trim or model, then select a date range.

But what i want to do is in the front end select documents by everything under Make and/or Model and/or Trim and/or Year

But i am not sure this is the best solution.

Can anyone recommend?

Goal: Filter documents by related vehicle characteristics.

My first idea would be to create it as such:

Create an assets volume where all your documents will be uploaded to.
Create a vehicle category group for your vehicles such as you already defined (the structure you mentioned)
Add 2 fields to the assets volume:

Vehicle (category field)
Year (date field)

This will allow you to add the relevant data to each document. You can than display the documents on your frontend and search/filter them by category and/or date.
How you do that is up to you, either with Twig serverside or with VueJS for example client side.


Craft Commerce View Order PDF, Not Download Is it possible to 'view' an order's PDF rather than download/create it first? I ask because I'm working on PDF templates and I can't figure out how to view the progress/changes I'm making without having to re-download a order PDF everytime.

No, I don't think there's a way of having a "live" pdf open, in the same way as a webpage.

But, what I usually do is just open the pdf template directly in the browser and create the HTML and CSS while using my normal workflow to check how it looks in the browser. This usually get me 95% of the way, and then I can do the final tweaks when I see what dompdf makes of it.

You need a variable order that's an OrderModel to make this work, so I just grab one like this at the top of my template or in my layout:

{% if not order is defined %}
    {% set order = craft.commerce.orders.first() %}
{% endif %}

And if you want to test with different orders you can get one at random, or a specific one by id.


Multiple contact forms different receiver(s) The current site that im building has multiple contact forms. The forms are page specific and should send this to a different user (depends on which page the user sends the form).

My question: is there a way to define per form (page) to which receiver the form should be sent?

Thanks in advance,

No. It's currently not possible, but you could make this a feature request! If you don't have the time, you could fork the plugin and make the changes yourself.


New user registration activation timeout? Does the "Activate your account" link, in emails sent to new users, have an timeframe for expiration?  I've had a few of my users run into a "Invalid verification code" error when clicking on the link, after waiting a couple days. If I resend the email, and they click on it within a few hours there's no issue.

I've looked through the docs and posts here and don't see any reference to one.  If there is a default expiration, is this something I can override?

Thanks!

The verificationCodeDuration config setting is what you're looking for.  Defaults to 24 hours.


Many db requests with relationship fields I have a page with a lot of entries fields. They are awesome but that leads also to a LOT of db requests.

Aside from caching are there some best practices to lower db requests on entries fields?

For example my whole navigation is built with entries fields:

{% for entry in globalsNavi.businessSorter %}
    {{ entry.title }}
{% endfor %}

Would it make any difference if I grabbed only url and title in this example since there are a lot more fields available. And if it would make a difference how would I have to write this?

Something like:

{% for entry in globalsNavi.businessSorter( entry.title, entry.url ) %}

This is how relationships work in Craft at the moment. Each relation equals +1 query. If you don't access your relation on an entry the query isn't executed. So by only fetching title and/or id you don't run any extra relationship queries.

Caching is your best option at the moment to make the query count go down. Make use of caching to cache large chunks of you code.

Brandon has hinted on Slack that Craft3 might incorporate Yii2 lazy loading of relations using the ->with() command. This will solve a lot of the N+1 queries with relationships.

Update

The release of Craft 2.6 included the functions for Eager-Loading of elements. See this link for documentation on the subject: https://craftcms.com/docs/templating/eager-loading-elements


Display X minute / hours / days in entries I am trying to print if statement for x time or x day ago for each published entries. For example the entry is posted x minutes ago should display x minutes ago or x hours ago. Same for days and months.

Here is what I have used but not what I am after.

{{ date(category.dateCreated|date('c')).diff(now).format('%a') }}

But the code I have written does not work.

{% for category in entries %}

{% for time in category %}
{{ date(time.dateCreated|date('c')).diff(now).format('%i') }} minutes ago

{% else %}
{{ date(time.dateCreated|date('c')).diff(now).format('%h') }} hours ago

{% else %}
{{ date(time.dateCreated|date('c')).diff(now).format('%d') }} days  agos
{% endfor %}
{% endfor %}

The above code is too long or is there a better way to check whether the entry is posted min, hours, or days ago.

Check out the DateTimeHelper method timeAgoInWords. It will do what you are after.

https://craftcms.com/classreference/helpers/DateTimeHelper#timeAgoInWords-detail

There is even a handy twig filter available for use in your templates.

{{ entry.dateCreated|timeAgoInWords }}


Is It Possible To Make Titles Optional? I've got a Quick Post widget for notes (tweet-like posts). Is there any way to make the titles optional? I've tried adding the id as an auto-generated title but it doesn't appear to work?

Update:
It actually appears that the auto-generated title is now working (thanks to carlcs) but it only works through the entries menu item rather than the quick post widget despite the widget's type being correct.

If you set the title format to a string like "Note" in the channel's field layout, all your entries will be given this exact name. The entry slug will be saved prefixed: "note-1", "note-2", etc.

If you don't want them all to be named the same, you could add a date to it:

Note {{ 'now'|date('Y-m-d') }}

This approach has one problem, if you make an edit to the "Notes" entry at a later point, the title will get updated to a new 'now' date. To work against that you can add a conditional to the code, checking if a title is already saved for that entry:

{{ object.title ? object.title : 'Note ' ~ 'now'|date('Y-m-d') }}

In the case you add more than one "Note" a day the entries would still be named the same though. To solve that, you could format 'now' to add a time to the title |date('Y-m-d H:i'), or you could use a counter instead. Because entry IDs are saved across all sections you wouldn't want to use them here.

But what you could do is to use the entry title of the previous entry in your "Notes" section (sorted by title) and modify upon that. Just name your first entry in your section "Note 001" and then use this snippet as the title format:

{{ object.title ? object.title : 'Note %03d'|format(craft.entries.type('note').order('title').last().title|slice(5) + 1) }}


Feed Me with Related Entries Fields - One to Many Relationship I'm using Feed Me to populate content for a "Meetings" section in my site. One of the fields in this section is "Meeting Attendees", which is an entries field relating to a Contacts Section.
I have a JSON file that contains a unique Meeting ID, and this Meeting ID could map to several Contacts. In a simplified form, my JSON file format is essentially this:
[
    {
        "Meeting Title" : "Project Kickoff"
        "Meeting Attendee" : "John Doe"
    },
    {
        "Meeting Title" : "Project Kickoff"
        "Meeting Attendee" : "Jane Smith"
    },
    {
        "Meeting Title" : "Project Kickoff"
        "Meeting Attendee" : "Jim Brown"
    }
]

You'll see in this simplified example that three Contacts need to be related to the "Project Kickoff" Meeting entry. I have my "Meeting Attendees" entries field configured with no limit on number of selectable entries, and can add multiple entries without issue when entering data manually.
However when I run Feed Me on a data set like the one above, Feed Me seemingly overwrites/replaces the entries rather than adding each as a separate relation. e.g. When Feed Me has completed processing the above dataset, my "Project Kickoff" entry will only have one attendee related ("Jim Brown" in this case - or whatever the last value in the dataset happens to be). For the example data above, I would expect to see all three "Meeting Attendees" names related to the "Project Kickoff" meeting entry.
Is there a way to configure either Feed Me or my JSON data to produce the intended result?

Why not define the attendees as an array in your JSON? This should allow multiples to be added to your field.
[
    {
        "Meeting Title" : "Project Kickoff"
        "Meeting Attendees" : ["John Doe", "Jane Smith", "Jim Brown"]
    }
]


404 Page for Multi-lingual Page For my multi-lingual-Page (de + en) I've made a 404.html-File in my templates-Folder with a language-changer for html-content-output like
{% if craft.app.language == 'de-CH' %}
Hallo
 {% else %}
Hello
 {% endif %}

When I open the 404-pages local (localhost/404 and localhost/en/404) it works. Also when I open them in live with direct url (www.example.ch/404 and www.example.ch/en/404) everything works fine.
But when I will open a wrong URL like "www.example.ch/tesxt" (correct URL: www.example.ch/test) I get a HTTP 404 – Not Found – yii\web\NotFoundHttpException Template not found: tesxt
Settings:

I only have one index.php
I only have one 404.html
in general.php: 'devMode' => false,
the 404.html is directly in templates-Folder (src>templates>404.html)
installed Plugins: DigitalOcean Spaces Volume, Freeform, Redactor (I think these will not disturb the 404 page)
Craft Version: 3.5.17
PHP-Version: 7.3.17

I don't know exactly why. But I did the Redactor updates in Craft, uploaded the new vendor folder to the hosting provider and now it works.


Translate labels in CP with Craft CMS 3 I was wondering if it was possible to translate the labels, like "Singles","Entries" in the CP

I know it's possible with Craft 2, but I didn't find with Craft 3.

Do you have any ideas?

Thanks!

Yes, it's possible to do. You can do it via Static Translations. Just create translations/en-US/app.php (or whatever your site language is), and do the mapping there as per: https://twitter.com/nystudio107/status/1045963809956012032


Emojis in Rich Text Field Does anyone know of a good way of handling emojis in a rich text field?

I'm aware that is possible to copy and paste them into one, but does anything along the lines of an emoji 'button' (i.e. to sit in the toolbar with a dropdown of categorised emojis) exist? Other suggestions welcome! Just keen to avoid the extra steps of having to find the emoji on an external source, copy, and paste in to the field.

A reference point would be Slack's 'emoji menu'.

It looks like Redactor has a plugin called “Clips” that allows you to:

  Create a dropdown of frequently used "snippets" of code, text, icons,
  emoji, you name it.

Pixel and Tonic made it into a plugin for Craft too.
I haven’t tried either but it looks like it should do the trick. I just tried the Craft plugin and it worked out pretty good. It doesn't have a preview of the emoji like Slack’s emoji menu though.

The plugin has settings where you can define the clips and the following HTML with each clip. Pretty straightforward.

After installing it I edited one of the .json config files in craft/config/redactor/ directory by adding

"plugins": ["clips"]

It then gives you a button on the tool bar called Clips. Make sure your Rich Text field is set to use the config that you added this plugin to.

Clicking that button gives you the following list. Clicking on a clip will insert the corresponding HTML

Not as polished as Slack’s emoji menu. Might be a way to edit the plugin to get it to do that though.


How do I store and retrieve elements for ElementSelectField? Getting error "Call to a member function getUiLabel() on array" I have a field that allows a user to select multiple products and save them to the database for a plugin, but when I try to retrieve these values and have them selected in my form I get the error

  Call to a member function getUiLabel() on array

Here is my field

{{ forms.elementSelectField({
    label: "Products Allowed",
    instructions: "Leave blank if this voucher has no product limits",
    id: 'products',
    name: 'products',
    elementType: productElementType,
    selectionLabel: "Add Products"),
    elements: (products is defined and products ? [products])
}) }}

The first question is, how do I store these values? Do I store it as it comes back? In an array, or do I encode that array to JSON? I've done both and both ways give the same error at retrieval.

Here is my retrieval code

$products = JSON::decode($variables['voucher']->products);

$variables['products'] = [];
foreach($products as $productId)
{
    $product = Commerce::getInstance()->getProducts()->getProductById($productId);
    ArrayHelper::append($variables['products'], $product);
}

As mentioned before, I've also just tried saving the products array without encoding to JSON and applying the saved results directing to $variables['products'] with the same results.

Well, I figured it out to an extent, I'm not sure why this works and I have a feeling it will break eventually, but here is my solution. Please let me know if there is a better one out there or something that is standard practice.

{{ forms.elementSelectField({
        label: "Products Allowed"|t('business-to-business'),
        instructions: "Leave blank if this voucher has no product limits",
        id: 'products',
        name: 'products',
        elementType: productElementType,
        selectionLabel: "Add Products"|t('business-to-business'),
        elements: (products is defined and products ? [products][0])
}) }}


Sprout Forms -- How to link to individual entries on the front-end I'm trying to build a front end to display entries collected through Sprout Forms. I want to create a list of all entry titles that can be clicked through to see the full entry.

I can list a single entry, or all entries:

{% for formEntry in craft.sproutForms.entries.formHandle('entry') %}
  {{ formEntry.title }}
{% endfor %}

But when I try to create a link, {{ formEntry.url }} doesn't work. I'm not entirely sure if this is a Sprout Forms issue or a Craft routing issue, or if I'm just missing something obvious

A note on Elements

Craft allows plugins to create custom Element Types. Elements have the option to support URIs, but it is not required. Out of the box, Craft currently has 7 Element Types and only two of them (Entries, Categories) support URIs.  Here's a good overview of the default Elements.

Sprout Form Element Types and URIs

Sprout Forms adds two new Elements to Craft. The SproutForms_Form Element and the SproutForms_Entry Element both which do not support URIs simply because we didn't feel there was a strong use case for them to be implemented for most form submission scenarios.

While it may not make sense to support URIs for all SproutForm_Entry Elements out of the box, you can still create a way for those Elements to be linked to in your templates, you will just have to do it manually.

How to manually create URIs for Sprout Form Entry Elements

To customize Craft to handle custom URLs for an Element that doesn't support URLs (of even for an Element that supports that that you need to do something fancy with), here is a rough example of the steps needed.

Loop through your Elements and output the URL you wish them to have to link to your Entries:

/submissions/{{ formEntry.id }}

You will then need to setup a route to tell Craft which template it should load when it encounters a URL like that. You can create a route in the CP or in the craft/config/routes.php file. This route tells Craft to load the submission/_entry.html template each time a URL matches submission/ANYTHING:

return array(
    'submissions/(?P<formEntryId>.*)' => 'submissions/_entry'
);

In your submissions/_entry template, you will need to use the ID information in the URL to query for the Form Entry that you wish to display:

{% set entry = craft.sproutForms.getEntryById(formEntryId) %}

In the above example, we're able to use the formEntryId variable because we setup our route to assign the second segment of the URL to the value formEntryId. If you setup your route in the control panel, you may need to grab the ID using getSegment:

{% set formEntryId = craft.request.getSegment(2) %}
{% set entry = craft.sproutForms.getEntryById(formEntryId) %}


Order a paginated entry by postDate I'm stumped trying to order paginated entries for a channel. The end goal is to have listings with the most recent postDate at the top. The code below has the most recent item third instead of first. The first item should be third.

The same happens as you paginate to the next page. The third item listed should be the first item listed.

{% paginate craft.entries.section('podcastEpisodes').order('postDate desc').limit('3') as pageInfo, pageEntries %}
{% for entry in pageEntries  %}

{% set category = entry.topic.first() %}

{{ entry.postDate|date('M j, Y') }}

        {% set myEntry = entry.podcaster.first() %}
        {% if myEntry %}

{{ myEntry.title }}

        {% endif %}

{{ entry.title }}

{% endfor %}

Any idea why this is happening?

The code above is correct and working properly. There was a conflict with a masonry js file making the Craft ordering not work. Big thanks to @Anubarak for testing the code on their side.


Importing Commerce Variants from google sheet How I should set up google sheet data to import Commerce Variants from it?
It is necessary that the Variants are imported in the same way as this example.

Thanks.

Check the tip in this page

  TIP

  When using Google Sheet as your feed type, consult the Google Sheets API docs. Your URL should include a key value for your API key. For example:

  https://sheets.googleapis.com/v4/spreadsheets/SHEET_NUMBER/values/SheetName?key=API_KEY


How can I mitigate caching performance issues with Craft? I ran into problems with the performance of one of our Craft sites. This showed up as:

MySQL running out of memory and crashing, because Apache was using up all the memory in backgrounds tasks,
Sometimes getting blank, white pages back from the cache instead of real results, and
background tasks hanging and failing to clear out stale cached pages.

The website we've built uses caching on nearly every page.

First off:

Craft stores cached content in the templatecaches table.
Craft stores criteria mapping to the cached versions in templatecachecriteria.

1. Make sure Craft isn't caching too much.

Originally, we were using

{% cache using key craft.request.path if not craft.config.devMode %}

We discovered it's critical to use the globally keyword:

{% cache globally using key craft.request.path if not craft.config.devMode %}

Without the 'globally' keyword, Craft continues to collect query string variables and will make a record in templatecaches for each unique set of query string variables. That means that things like CRM mailers which may include a unique query string in every email will create tons of entries in templatecaches. I'm not sure why you would ever want to use {% cache using key %} without the globally keyword, as it seems like without the globally keyword, the key isn't being used.

2. Reduce 'criteria'.

When caching a {% cache %} tag, it looks like Craft tracks all of the 'criteria' to determine when this chunk of content should be invalidated. Examples of criteria are:

Building entries from craft.entries,
Building related entries from an entry, or
Getting all the assets for a particular field on an entry.

So, for example, if you Are showing a list of the five most recent blog articles, you might have

1 Criteria for building the list of recent entries,
1 Criteria for each entry getting a cover photo,
1 Criteria for each entry getting the author, and
1 Criteria for each entry getting the author's photo.

So, that's 16 criteria for this example. Some of the pages on our site did had as many as 247 associated criteria.

Criteria are stored as JSON within MySQL. For each one, Craft has to decode the JSON and compare it to determine whether it should be cleaned up or not, so if you end up with a really high number of criteria, the background tasks will take longer and longer, and in our experience, eventually get stuck.

3. Linking to transformed images might prevent for your page from caching.

If you link to a transformed asset but don't include it on the page (say, as the target for <a> but not the src for an <img> tag.) then you may interfere with the caching of your page.

Craft doesn't generate transformed assets until they are requested, which is fine for <img> tags but not for <a> tags. Instead, it returns a special URL that, when requested, will generate the transformed asset on demand. After the asset is generated, Craft will simply return a link to the generated asset.

However, Craft will not cache any page which has these special URLs in it. For example, if you're caching a page with an image gallery with thumbnails that need to be clicked through to the larger (but still transformed) version, Craft will not cache that page until after all of the large versions have been generated.

I'm interested to know if anyone else has run into these issues, whether there's any other tips worth knowing for controlling performance of Craft's caching.


Download database in gzip With using the CraftCMS builtin database export feature, is it possible to specify the export config to have the file in .gzip instead of just .zip? If, yes, then how can I do it?

Nope, the UtilitiesController is hard-coded to use .zip:

        $zip = new ZipArchive();

        if ($zip->open($zipPath, ZipArchive::CREATE) !== true) {
            throw new Exception('Cannot create zip at ' . $zipPath);
        }

        $filename = pathinfo($backupPath, PATHINFO_BASENAME);
        $zip->addFile($backupPath, $filename);
        $zip->close();

        return Craft::$app->getResponse()->sendFile($zipPath, null, [
            'mimeType' => 'application/zip',
        ]);


Can't get Frontend Search to work Well, to be honest i am completely new, not only to Craft but to most PHP stuff as well.
I am currently trying to setup a search for my page but i seem to miss a crucial step and can not find any tutorials on what to do.

On my front/ index page i included

<form action="{{ url('search/results') }}">
<input type="search" name="q" placeholder="Search">
<input type="submit" value="Go">
</form>

as stated in the Craft Documentation.

I have also set up a single page for my search results with the code from the Documentation as well:

Search Results

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

{{ entries|length }} results:

    {% for entry in entries %}

{{ entry.title }}

    {% endfor %}

{% else %}

Your search for “{{ query }}” didn’t return any results.

{% endif %}

So, now if i try to search at the index page and hit enter, it just reloads the index page with the search term

site.url/index.php?q=test

So for sure i am missing a step here and am not loading the right page. I guess it should be stated in {{ url('search/results') }}, but i have no idea what to put there.

Would be great if anybody could help me or at least point me to a tutorial that focuses on setting up a site search in Craft CMS.

Inside of the <form action="{{ url('search/results') }}"> You define which page should be redirected to when the search form is submitted.

"search/results" would go to the search folder looking for the results.(html / twig).

If you want to redirect to another page you should name the folder (which is "search" now) then the template name. This can be static without creating a "Single" for that page.

If you did create a single that uses that template and you want to go through your single you can just put the slug of the created Single inside your form action.

Example:

You made a folder in craft/templates/ named: search, inside that folder you make a file named: results.

So the file structure would be craft/templates/search/results.twig and the form action would be: <form action="{{ url('search/results') }}">

This way you can just use the preset search template the craft docs offer you. You could also change "results.twig/html" to index.html and then your form action wouldn't need the /results so your action would look like:
<form action="{{ url('search') }}">

But I see you get redirect to /index.php/ aswell so I should try rmeoving that by changing your .htaccess file and maybe your general.php.

You can find instructions on how to do that here:
https://craftcms.com/support/remove-index.php


Error when updating 2 to 3: Bad Request Unable to verify your data submission Followed all steps on Upgrading from Craft 2 I have my .env, db.php, general.php and index.php in place... can't find any reference of this issue.

This happens after "To complete the update, some changes must be made to your database." and clicking on "Finish Up"

I was able to fix it replacing the content of config/license.key by the word temp


HTML and Scripts in Entries? I am building a section in which a client will list their various social network connections. There are fields for each social network's name and icon, as well as a field with the URL to the client's page on the specified network.

I also need a field that contains the code needed for each network's "Share" button. The code for "Share" buttons varies, but typically includes some HTML as well as <script> tags. When I output this field in a template, its contents are HTML encoded and displayed literally.

How can I keep this from being encoded so the HTML and Javascript can be parsed by the browser?

Giving the enduser the ability to include scripts is risky way to present social media links. Any errors could protentialy break the entire html page / site If you really want to do it this way you can use twig's raw filter


How to add to arrays in models? I have a model that contains a bunch of storage arrays where I collect results from various services I have written.

class Shipper_ResultsModel extends BaseModel
{

shipping categories for debugging

    protected function defineAttributes()
    {
        return array(
            'service'               => array('type'=>AttributeType::Enum, 'values'=>['post','courier','free','cantShip','needsQuote']),
            'options'               => array('type'=>AttributeType::Mixed,'default'=>[]),
            'boxes'                 => array('type'=>AttributeType::Mixed,'default'=>[]),
            'postShippingItems'     => array('type'=>AttributeType::Mixed,'default'=>[]),
            'courierShippingItems'  => array('type'=>AttributeType::Mixed,'default'=>[]),
            'freeShippingItems'     => array('type'=>AttributeType::Mixed,'default'=>[]),
            'cantShippingItems'     => array('type'=>AttributeType::Mixed,'default'=>[]),
            'quoteShippingItems'    => array('type'=>AttributeType::Mixed,'default'=>[]),
        );
    }

Each of this ShippingItems arrays is intended to hold an array of Shipper_ShippingItem models.

My issue is in building these arrays, I create new items and add them like this:

            $shippingItem = Shipper_ShippingItemModel::populateModel($data);

            //build our arrays of items
            if($shippingClass=="Courier Only"){
                $results->courierShippingItems[] = $shippingItem;
            }

But this results in the following error:

PHP Notice: Indirect modification of overloaded property Craft\Shipper_ResultsModel::$courierShippingItems has no effect

I think this is because I am not using array objects as such but I have to say I've  got a little confused here and various syntax experiments have resulted in ignoble failures.

Some guidance as to the right way would be much appreciated (and am I right in using AttributeType::Mixed for these?)

(This is all for a mega shipping calculator for Craft Commerce, should that matter)

I'm pretty sure 'default'=>[] isn't doing anything so it's probably not necessary.

If you wanted to force a single attribute to be of a specific model, you could use:

'courierShippingItems'  => array('type' => AttributeType::Mixed, 'model' => 'Shipper_ShippingItemModel');

Regardless, you'll want to use BaseModel's setAttribute to do what you're trying to do and build your entire array up first before assigning it to the attribute.  Something like this:

$shippingItems[] = Shipper_ShippingItemModel::populateModel($data);

$results->setAttribute('courierShippingItems', $shippingItems);


Getting invalid verification code for email confirmation I am using Craft CMS as a backend for react Next app. On our live site we are sometimes getting complaints from the user about error when user try to verify code sent in the email.

This case doesn't happen with every user but very for random users. For this reason I am not able to find the reason for the issue and fix it.
Everytime I see following information in the log file.

  2020-05-27 10:17:35 [-][-][-][warning][craft\services\Users::isVerificationCodeValidForUser] The verification code (gqkZpvgTZDMNSXRyNuXE4ksxpNOlBOl) given for userId: 99965 does not match the hash in the database.
  2020-05-27 10:17:35 [-][-][-][info][application] $_GET = [
      'p' => 'ACT/craft-rest-api/user/verify-email'
      'code' => 'gqkZpvgTZDMNSXRyNuXE4ksxpNOlBOl'
      'id' => 'ef2156d6-306b-4a88-80bb-25ca26562702'
  ]

Here is the information about the system.

PHP version 7.4.5

OS version  Linux 3.10.0-1127.el7.x86_64

Database driver & version   MySQL 8.0.20

Image driver & version  GD 7.4.5

Craft edition & version Craft Pro 3.4.21

Yii version 2.0.35

Twig version    2.12.5

Guzzle version  6.5.4

Imagine version 1.2.3-dev

Plugins:-

Amazon S3   1.2.8

Architect   2.3.3

CKEditor    1.0.0-beta.3

Comments    1.5.6

Contact Form    2.2.7

Craft-Rest-Api  1.1.0

Enforce password    1.0.0

Image Resizer   2.0.9

Klaviyo Connect 3.1.3.2

Redactor    2.6.1

SendGrid    1.2.0

Those codes are valid for as long as whatever verificationCodeDuration is set to (24 hours by default).

Guessing the users that are getting that are hitting expired verification codes.


Template for Site Group rather than site handle We are building a multi-site set up in Craft. We will have a lot of "microsites" for different locations.

I have a site group called "Microsites" and I would like the home page for each of these sites to load a template inside /templates/microsites/index.twig

I don't want to create individual folders in the template folder for each site.

Is this possible?

Edit: I'll provide overview of the site setup

So I will have over 100 different sites on here representing a location. We have a Locations channel on the main site that will hold the data we will query in the Microsite template.

Each microsite will have its own base URL like so:

@web/san-francisco

so whenever that page is loaded, I want it to go into /templates/microsite/_index.twig

Every single microsite home page will use that same template and have the data be loaded dynamically.

The reason we can't just use Channel entries is because we will need localized blogs for them.

Maybe I'm going about this all wrong?

It's not ideal, but you can use one template folder for each group and then create symbolic links for all the language sites.


How to search by title OR tag using Craft CMS? I want to do a search query so the product title or product tag name matches the keyword. below is my code. if I remove the tag related query, this code works as it looks into the product title only and returns the result. But how to make it work so it looks for the keyword in both product title and tag name? and if it exists in any one, it results specific records?
 {% set productValues = {
        keywords: craft.app.request.getParam('keywords'),
        orderBy: craft.app.request.getParam('order') ? craft.app.request.getParam('order') : 'score'
    } %}

    {% set tag = craft.tags.search(craft.app.request.getParam('keywords')).first() %}

    {% set productParameters = {
        search: 'title:' ~ productValues.keywords,
        relatedTo: [
            'OR',
            tag
        ],
        orderBy: productValues.order
 }%}

I think you need to make two separate queries, get two arrays, combine them using the merge method and leave them unique, since these are different searches, textual and by related elements. It's like a quick fix, if I find something I will answer.


How to query using variables I'm having issues with getting results from a query. I have 2 search parameters which i have set to variables. I would like to match both of these to get results.

At the moment the query is returning zero results. I think this is because it is turning the variables into strings. Replacing the variables with hardcoded values does return results.

{% set queryKeyword = craft.request.getParam('q') %}
{% set queryLocation = craft.request.getParam('l') %}

{%
    set entries = craft.entries.section('schools').find({
       search: 'body:queryKeyword categories:queryLocation'
    })
%}

I have tried:

{%
    set entries = craft.entries.section('schools').find({
       search: 'body:' + queryKeyword + 'categories:' + queryLocation,
    })
%}

This doesn't work.

I'm very new to Craft CMS and am not very experienced in PHP/MySQL so any help would be greatly appreciated. Thanks!

I think you are using the wrong string concatination operator. ~ is the twig string concatination operator (vs . for php and + for javascript).

Try this:

{%
  set entries = craft.entries.section('schools').find({
   search: 'body:' ~ queryKeyword ~ ' categories:' ~ queryLocation,
  })
%}


How do I make use of the order fields In Commerce? Building on top of the Commerce Example Templates. I've made an order field called 'Customer Reference'. I'm submitting data like this:

<form class="shopForm" method="POST">
<input type="hidden" name="action" value="commerce/cart/updateCart">

    Your Reference: {{cart.customerReference}}
    <input type="text" name="fields[customerReference]" value="">

<input class="btn btn-outline" type="submit" value="Update Reference">

This code seems to work ok. But after updating the cart the data doesn't seem to be saved, it doesn't show up in the Commerce back end. I'm also not able to be display the data later on in the ordering process, on the receipt for example.

I'm using this to display the data from the field:

{{cart.customerReference}} or {{order.customerReference}}

Can somebody tell me, possibly with some examples, how to properly submit and retrieve the content for custom order fields?

This is related to: How can I update custom order fields in the frontend

Working with: mamp

The text that is submitted using your <input> field will display as expected with Your Reference: {{ cart.customerReference }}.

However, I have a feeling that because the page is re-rendered with the inputs value as empty, when the /updateCart action is submitted again the blank value will override and erase the old value.

To solve this use the customerReference stored on the cart in the value attribute of your text <input>.

<input ... value="{{ cart.customerReference|length ?? cart.customerReference }}">


How to get all Element Types? From within a plugin/module using PHP; is there a way to query all element types being used, including custom elements?
I know in the elements database table there is a type column that I could potentially query. But I wasn't sure if there is a native Craft method I could take advantage of instead?
In an ideal world I just need an array of all the element types:
Example:
['asset', 'category', 'entry', 'globalset', 'matrixblock', 'tag', 'user', 'single', 'event', 'product']```

Ok, I found this:
https://docs.craftcms.com/api/v3/craft-services-elements.html#method-getallelementtypes
Craft::$app->getElements()->getAllElementTypes()


Get the handle of a Matrix block I am performing the following query, which returns me an array of matrix blocks:

$criteria = craft()->elements->getCriteria(ElementType::MatrixBlock);
$criteria->relatedTo = array(someCoolId, anotherCoolId);
$relatedStories = $criteria->find();

When looping through this array, I was wondering if it was possible to access the handle of the matrix block that I am currently in. Reason being is I would like to retrieve this as a string, and perform some type of work on it.

You can grab the handle of an element that has different types (entries, matrix) with getType()->handle for example:

$handle = $entry->getType()->handle

In your case

$criteria = craft()->elements->getCriteria(ElementType::MatrixBlock);
$criteria->relatedTo = array(someCoolId, anotherCoolId);
$relatedStories = $criteria->find();
foreach ($relatedStories as $block){
    $handle = $block->getType()->handle;
    switch ($handle){
        case 'foo':
            break;
    }
}

Edit:

Not sure what you mean exactly so I'll just insert some random code parts until something is correct.

// get the parent element -> the owner of that block.
$parent = $block->getOwner()

// get the field that relates both elements
$field = craft()->fields->getFieldById($block->fieldId);
$fieldHandle = $field->handle;


Using AND with craft.entries() I'm trying to return entries based on some criteria. I exclude entries with a given value like this:

{% set someEntries = craft.entries({
    level: 1,
    id: '1,2,3,4,5',
    myOtherField: 'not blue'
}) %}

But it doesn't work if I try to exclude by multiple values:

{% set someEntries = craft.entries({
    level: 1,
    id: '1,2,3,4,5',
    myOtherField: 'not blue and not green'
}) %}

It's not in the docs and I've tried a few different syntax but had no luck.

This should do what you're looking for:

{% set someEntries = craft.entries({
    level: 1,
    id: '1,2,3,4,5',
    myOtherField: 'and, not blue, not green'
}) %}


Craft 2: Locale throwing 404 in frontend I have my two locales set up as described in the official documentation.

I am able to translate my pages and fields in the CP as supposed to and have two versions ready in the backend, both with a green dot behind them.

However, when I try to access any page apart from the homepage in my 2nd locale in the frontend I get a 404 error.

DE is my first locale, placed within the /public/ folder.
EN is my second locale, placed within the /public/en/ folder with the index.php referring to ../../craft as shown in the official docs and the same .htaccess copied from the parent /public/ folder.

Furthermore, this is my general.php setup for the local development server, where I can not see any obvious mistakes yet:

'.develop' => array(
  'rootUrl' => 'http://deque.develop:8888/',
'siteUrl' => array(
    'de' => 'http://deque.develop:8888/',
    'en' => 'http://deque.develop:8888/en/',
  ),
  'environmentVariables' => array(
  'baseUrl'  => 'http://deque.develop:8888',
  'basePath' => 'http://deque.develop:8888',
  'devMode' => true,
)

I did not write the /en/ in any of the CP settings, only have the correct translations for the URL string there, so that should be no issue. The URLs are rendered fine and as supposed in the Frontend anyway. It’s just that a 404 is displayed for any English pages instead of the actual content.

In Craft’s log file I could only find this hinting at something:

2018/04/13 12:52:20 [error] [exception.Craft\HttpException.404] Craft\HttpException in /Users/Tobias/Development/deque_2018/craft/app/controllers/TemplatesController.php:72

Any hints where I might be making a mistake?

However, when I try to access any page apart from the homepage in my
  2nd locale in the frontend I get a 404 error.

Could it be, that as a result of your settings, URL's for /en do not get rewritten correctly? I don't know how you redirect SEO-friendly urls, but most of the times (at least in my life) if accessing all pages but the homepage fails, it has something to do with URL rewriting.


Loop through structure entry types and matrix blocks Single page website. Navigation based on a Structure section (anchor links). Entries depend on entryTypes.

{# set each section ID with for anchor navigation #}
{% for page in craft.entries.section('pages') %}
<section id ="{{ page.slug }}">

    {# check the slug to get the Matrix entries related to the (html) section ID #}
    {% if page.slug == 'home' %}
        {# get the entries for the entry.type #}
        {% set entries = craft.entries.type('pagesHome') %}
            {# loop through the block types and entries #}
            {% for block in page.matrixFieldHandle.type('matrixBlockHandle') %}
                {{ block.title }}
            {% endfor %}
    {% endif %}

    {# and so on.... #}
    {% if page.slug == 'about' %}
        ......
    {% endif %}

</section>
{% endfor %}

Questions: am I setting up this single page website in a too complicated way with too many DB queries?
Thanks for suggestions!

If I was building a single page website I might create a matrix field with different blocks for each "page".

{# Navigation #}
{% for block in entry.contentBlock %}

{{ block.title }}

{% endfor %}

{# Content #}
{% for block in entry.contentBlock %}

     {{ block.body }}

{% endfor %}

This will allow someone to re-order "pages" easily under one entry. You can also create several different block types with different fields in if these "pages" needed to be different.


How can I pull every entry (large number) in a section? I have an extended profile that users can purchase. When purchased, an entry is created, and tied back to the user.

The user can then log in and access the entry with the extended profile fields.

I would like to have a page that pulls every extended profile entry. This could be in the hundreds. I know Craft will limit the number it returns by default. I also know that I can pass null into the limit. limit(null)

That seems pretty risky and expensive to run. Is there a better solution? I only need the page title of each entry, so I don't need the entire entry model.

Is this a place to use elementAPI and make ajax call(s) to get all of the entries so I'm only returning the page titles?

Thank you for any suggestions!

You could use the {% paginate %} tag with ajax to limit the number of entries that are pulled at a time.


API endpoint to show/add/modify/delete content I would like to access and modify certain entries using asynchronous calls from a custom made webapp using React which is complementary to the main website. Is there any way to achieve this in Craft CMS?

I've got 0 experience with React, but you can write a Craft plugin (generate boilerplate code at https://pluginfactory.io), that has a controller action(s) your webapp can post to.

From there you can use EntriesService->saveEntry (craft()->entries->saveEntry()) to update/create entries just like Craft/any other plugin does.


Best way to deal with Impossible to access an attribute ("isEditable") on a NULL variable ("") I've had this issue a few times & wanted to know if there is maybe a better way to deal with the following issue:

Say I have this if on a page:

{% if entry.isEditable %}
    Edit this entry
{% endif %}

On an editable entry, the button appears if logged in. If logged out the button does not appear.

If I visit a page that is not an entry (just a template group) when logged in or not, I get this error:

Impossible to access an attribute ("isEditable") on a NULL variable ("")

The only successful way I've seen to so far to make this behave is as follows:

{% if entry is defined %}
    {% if entry.isEditable is defined %}
        {% if entry.isEditable %}
            Edit this entry
        {% endif %}
    {% endif %}
{% endif %}

You could combine the first three:

{% if entry is defined and entry and entry.isEditable %}

If the first or second part of this logic fails, it will not check the third part so no error will be thrown. The second part is for the rare cases that a variable with the name entry exists but is null.

If entry is defined, it's always an entry (or at least it should be), so you don't have to check if isEditable is defined.


How to add a facebook and twitter share button on a page I would like to add a facebook and a twitter share button to some pages of our sites. Our site already has a facebook and twitter button at some pages. Those buttons redirect to our corresponding pages.

Facebook/Twitter look for Open Graph(OG) metadata when a page is shared. To specify what this data is, you have to include the meta tags in the head of your page.

Step 1:

Have meta tags for the page

e.g.

  <title>My Website Title</title>
  <meta property="og:url"           content="https://www.myWbsite.com/my-page.html" />
  <meta property="og:type"          content="website" />
  <meta property="og:title"         content="My Website Title" />
  <meta property="og:description"   content="Page description" />
  <meta property="og:image"         content="https://www.myWebsite.com/asset/image.jpg" />

You can also create custom fields and call them dynamically on each page.

//Facebook
<meta property="og:url" content="{{ craft.app.request.absoluteUrl }}"/>
<meta property="og:type" content="website"/>
<meta property="og:title" content="{{ entry.title }}"/>
<meta property="og:image" content="{{ entry.socialImage }}"/>
<meta property="og:description" content="{{ entry.description }}"/>
<meta property="og:site_name" content="{{ site.name }}"/>

//twitter
<meta name="twitter:url" content="{{ craft.app.request.absoluteUrl }}"/>
<meta name="twitter:title" content="{{ entry.title }}"/>
<meta name="twitter:description" content="{{ entry.description }}"/>
<meta name="twitter:image" content="{{ entry.socialImage }}"/>

I use SEOmatic plugin to make the above procedure easy. There are also other plugins available for things like this as well.

Step 2:

Static URL:

Share on Facebook

Share on Twitter

or Dynamic URL:

then add these below in JS

function shareWindow(url) {
    var left = (screen.width - 570) / 2;
    var top = (screen.height - 570) / 2;
    var params = "menubar=no,toolbar=no,status=no,width=570,height=570,top=" + top + ",left=" + left;
    window.open(url,"NewWindow",params);
}

function setShareLinks() {
    var pageUrl = encodeURIComponent(document.URL);
    var tweet = encodeURIComponent(jQuery("meta[property='og:description']").attr("content"));

    jQuery(".share.facebook").on("click", function() {
        url = "https://www.facebook.com/sharer.php?u=" + pageUrl;
        shareWindow(url);
    });

    jQuery(".share.twitter").on("click", function() {
        url = "https://twitter.com/intent/tweet?url=" + pageUrl + "&text=" + tweet;
        shareWindow(url);
    })

}

References:

https://css-tricks.com/simple-social-sharing-links/
https://developer.twitter.com/en/docs/twitter-for-websites/tweet-button/overview
https://developers.facebook.com/docs/plugins/share-button


Display message on logout (flash?) I have looked through previous questions and answers, but don't see the following clearly explained.
When my users visit /logout, they are successfully logged out and redirected to the website's homepage.
What is not clear to me is how I can detect that action, and display some HTML saying they have been successfully logged out.

You can set postLogoutRedirect in your config/general.php (docs) to redirect your users to a specific page, something like 'postLogoutRedirect' => 'your-page'
If you want to use an existing page, say your homepage, and display an alert you could set 'postLogoutRedirect' => '/?loggedout' and check for it in your template using:
{% if craft.app.request.getParam('loggedout') is not null %}

You have been logged out

{% endif %}


Can I use GraphicsMagick with Craft CMS? Short question: Can I use GraphicsMagick with Craft CMS? If yes, how can it be configured? thanks

No, Craft only supports GD and Imagick, not Gmagick (which would be the PHP extension that interfaces with GraphicsMagick). The underlying PHP library, Imagine, actually does, so I guess it would be feasible to add support for it, but I suspect that there's not that huge a demand in the community. You could try submitting a feature request for it.


Best Approach to all unique groups of users to edit unique groups of entries in 1 channel I've got a request to let front end users edit entries in 1 section, but only if the entries are related to their user group - so different users will have ability edit a different subset of entries in the same section.

group A could edit entries 1,3,10,12
group B could edit entries 2,5,7,14
group C could edit entries 9,11,21

Site admins need to be able to add new groups regularly
Thinking about using a category assigned to both user and entry and on the front end limiting which entries they have access to edit by checking for relationship to that category.
Is this a feasible approach? Is there a better approach.

Also looked at the User Group plugin, but that relies on actual user groups which site admins won't be able to add on the live sites since allowAdminChanges is set to false to prevent issues with project.config being updated out of git.
Thoughts

If you're not using Craft's user groups for permissions, the solution you suggest is more or less exactly what sprung to my mind. You could create a Category Group called Permissions (just to keep it distinct from Craft's internal user groups), add the initial permission categories that are needed, then create a new field named Permissions that can be added to the User field layout and the field layout for the sections that are being managed.
Each entry can have one or more Permissions categories selected in the Permissions field, and every User can have one or more Permissions categories assigned to them in their profile.
To work out whether the user can edit a particular entry, just check that their permissions match the permissions that are set for that entry. This is probably easiest with IDs:
{% set entryPermissionIds = entry.permissions.ids() %}
{% set userPermissionIds = currentUser.permissions.ids() %}
{% set canEdit = false %}

{#
    If the result of intersecting the user's permission IDs array with the
    entry's permission IDs array is equal to the length of the entry's
    permission IDs array, the user has all the correct permissions to edit
    this entry
#}
{% if userPermissionIds|intersect(entryPermissionIds)|length == entryPermissionIds|length %}
    {% set canEdit = true %}
{% endif %}

{% if canEdit %}
    {# Show edit form #}
{% endif %}

Note: I've not tested this code, but I think the principle is sound!


Order Sprout Forms by field handle returns an error For some reason Sprout Forms entries will not accept the usual order by field handle setup. When I want to order the contact entries by address for instance:

{% for formEntry in craft.sproutForms.entries.formHandle('contact').order('address') %}
    {{formEntry.address}}
{% endfor %}

I get the error:

  Column not found: 1054 Unknown column 'address' in 'order clause'

This field does exist. If I remove 'order', it parses the field

It seams, that the columns for the form values are not part of the sql, that's why it never will work like this. Maybe it works in upcomming versions of the Sprout Forms plugin.

As a workaround you can use the SuperSort Plugin. With this plugin it's possible to sort your form entries like you need it.

Step 1 -> Download and Install SuperSort Plugin -> https://topshelfcraft.com/lagniappe/supersort
Step 2 -> Filter your form entries like this:

{% set formEntries = craft.sproutForms.entries.formHandle('contact')%}
{% set formEntriesSort = formEntries | supersort('sortAs', '{address | lower}') %}

{% for formEntry in formEntriesSort %}
   {{ formEntry.address }}<br>
{% endfor %}

Like this it should work!


How to order matrix blocks in reverse I've using a matrix field from the same entry in two different templates. In one template I want them in the order they're displaying in the CMS, while in the other I want them displayed in reverse.

It doesn't like this:

{% for cta in entry.ctas.order('desc') %}

Can this be done any other way?

I went and looked at the MatrixBlockModel; there's an attribute named sortOrder (If you output {{sortOrder}} inside the for loop, it will display the index of that block).

You can use that attribute to sort by, in reverse:

{% for cta in entry.ctas.order('sortOrder desc') %}


Add, remove, and append entries to an entries field via frontend form I'm making a one-button form, to add an entry to an entries field.
Adding seems pretty straightforward, but it overwrites any previous entry that occupied the entries field. How would I append an entry to the entries field, or remove an entry?

<form method="post" accept-charset="UTF-8">
  {{ getCsrfInput() }}
  <input type="hidden" name="action" value="entries/saveEntry">
  <input type="hidden" name="entryId" value="{{ entry.id }}">
  <input type="hidden" name="redirect" value="{{currentUrl}}">
  <input type="hidden" name="fields[tournamentTeams][]" value="{{team.id}}">

  <input type="submit" value="Add {{team.title}} to this Tournament">
</form>

My guess is, I will have to populate the entries field input value with the already-added entries to append the entry, and do the same kinda deal upon removing the entry- no idea how I would detect and remove the entry though!

You guessed right, you have to set all already added entries again. To do this,
just have some Twig logic when outputting the fields:

{% for currentTeam in entry.tournamentTeams %}
    <input type="hidden" name="fields[tournamentTeams][]" value="{{ currentTeam.id }}">
{% endfor %}
<input type="hidden" name="fields[tournamentTeams][]" value="{{ team.id }}">

To remove the entry:

{% for currentTeam in entry.tournamentTeams if currentTeam.id != team.id %}
    <input type="hidden" name="fields[tournamentTeams][]" value="{{ currentTeam.id }}">
{% endfor %}

Update: What I'm not sure about is if the above code works when trying to remove the last remaining entry. If it doesn't work I'd try and add something like this:

{% if (entry.tournamentTeams|length == 1) and (entry.tournamentTeams.first().id == team.id) %}
    <input type="hidden" name="fields[tournamentTeams]" value="">
{% endif %}


no entries or files visible I got given a db dump using Craft 3.5.16. After installing all the dependencies using composer and npm  I can login to the admin section.
However, I do not see any entries or any files in the admin section. In the frontend, I can only see the basic skeleton of the website including the footer and the correct CSS but no content. All links in the footer redirect to the live website though they should go to local pages.
The DEFAULT_SITE_URL is set in .env, pointing to the right local URL. There are no errors in the logs either.
Any clue what could be going on would be much appreciated! :)

I might be wrong on this but...
After running composer, did you have to go through an install process? If so, the DB/site you were given might have been configured to use a database table prefix.
If you look in your database, do you see some tables call assets then a second one called xxx_assets (xxx_ could be anything)?
If so, in your .env file, make sure have DB_TABLE_PREFIX= set to whatever prefix (the xxx_ part) you are seeing on your tables.


Is it possible to limit the number of times a user can be added to the same field across different entries? I want to make it so that each user can only be assigned once to a specific field across all entries. For instance, let's say we have a bunch of teams. A user can only be on one team at a time. Once assigned to a team roster, they should not be available to assign to another team. Is this possible?

Could you not come at it from a different angle and instead choose your team by editing the user? That way you can assign a team field to the user and restrict that field so that you can only pick the one team.

Then in your templates you can use relations to link them all up.


Upload and crop profile photo in frontend When you are in the backend and go to a user > profile tab. You'll see a very nice photo upload. I want to build this for the frontend users as well. I have a basic form and I'm loading in the following js files

{% includeJsFile "/build/libs/jquery-ui.min.js" %}
{% includeJsFile "/build/libs/jquery.iframe-transport.js" %}
{% includeJsFile "/build/libs/jquery.fileupload.js" %}

My HTML frontend form looks like this:

<form method="POST" accept-charset="UTF-8" data-saveshortcut="" data-saveshortcut-redirect="gebruiker/profielfoto">
    {{ getCsrfInput() }}
    <input type="hidden" name="action" value="users/saveUser">
    <input type="hidden" name="redirect" value="gebruiker/profielfoto">
    <input type="hidden" name="userId" value="{{ currentUser.id }}">

    <input id="image-upload" type="file" name="image-upload" style="display: none;">

upload

</form>

Here comes my JS:

$(function () {
    $('#image-upload').fileupload({
        dataType: 'json',
        type: 'POST',
        url: 'actions/users/saveUser',

        progressall: function (e, data) {
            console.log('progressall');
            console.log(e, data);

            var progress = parseInt(data.loaded / data.total * 100, 10);
            $('#progress .bar').css(
                'width',
                progress + '%'
            );
        },

        add: function (e, data) {
            console.log('add');
            console.log(e, data);

            data.context = $('
').text('Uploading...').appendTo(document.body);
            data.submit();
        },

        done: function (e, data) {
            console.log('done');
            console.log(e, data);

            data.context.text('Upload finished.');
            $('
').text(file.name).appendTo(document.body);
        },

        fail: function(e, data) {
            console.log('fail');
            console.log(e, data);
        }
  });

  $('.upload-photo').on('click', function() {
      console.log('upload-photo trigger');
      $('#image-upload').trigger('click');
  });
});

The fileupload jquery keeps triggering its fail function. When I log the data I see that it throws and unexepected error on the response.

Can someone lead me in the right direction and try to mimic the same profile photo upload WITH cropping tool?

This is a very old question, but thanks to this example I was able to build quickly a profile picture form using Craft 3 and jQuery File Upload plugin (thank you!).

The action value and file input name have changed. You should write it like this now:

<input type="hidden" name="action" value="users/save-user">
<input id="image-upload" type="file" name="photo" style="display: none;">


Move entry from one structure to another with parenting Seeing as moving entries between sections isn't supported (yet) through the Craft interface, I followed Brandon's answer for a workaround through the database.

I am moving entries from one structure to another; updating the sectionId in the database works fine and the entries are moving over without a problem.

However the issues start when I try and make some of the entries children to others that have also been moved.

I have tried both dragging the entry through the Structure view and setting the parent in the dropdown while editing the entry, but both are coming up with the same error:

  An unknown error occurred.

And I am getting a 500 Internal Server error on this file

/index.php?p=admincp/api/structures/moveElement 500 (Internal Server Error)

Is this a bug within Craft, or have I missed out on some other information that needs to be updated in the database?

That’s a little more complicated, and at that point you’re going to be best off writing your own PHP code to do it.

Craft has a bootstrap file that makes it very easy to write custom PHP code without going to the trouble of writing a plugin, which is great for one-off tasks like this.

Just create a new file alongside your index.php file, called move_entry.php. Here’s what it should look like:

Craft 3

<?php

// ...
// copy contents of index.php here, except for the last `$app->run();` line
// ...

// Start a transaction in case anything goes south
$transaction = $app->db->beginTransaction();
try {
    // Fetch the entry you need to move
    $entry = \craft\elements\Entry::findOne(184);

    // Remove it from its old structure
    $oldSection = $entry->getSection();

    $record = \craft\records\StructureElement::findOne([
        'structureId' => $oldSection->structureId,
        'elementId' => $entry->id
    ]);

    if (!$record->deleteWithChildren()) {
        throw new \Exception('Could not delete the old structure node');
    }

    // Set the new sectionId and typeId on the entry
    $entry->sectionId = 2;
    $entry->typeId = 2;

    // Append it to the end of the new structure
    $newSection = $entry->getSection();

    if (!$app->structures->appendToRoot($newSection->structureId, $entry, 'insert')) {
        throw new \Exception('Could not insert the new structure node');
    }

    // Save the entry
    if (!$app->elements->saveElement($entry)) {
        throw new \Exception('Could not save the entry');
    }

    // Commit the transaction
    $transaction->commit();
} catch (\Exception $e) {
    // Undo whatever changes we already made
    $transaction->rollBack();
    throw $e;
}

echo 'success!';

Craft 2

<?php
namespace Craft;

// Initialize Craft without letting it take over the whole request
$app = require '../craft/app/bootstrap.php';

// Set Craft to Craft Personal so we don't get any errors about Client/Pro-only components not being available
$app->getInfo()->edition = 0;

// Start a transaction in case anything goes south
$transaction = $app->db->beginTransaction();
try
{
    // Fetch the entry you need to move
    $entry = $app->entries->getEntryById(184);

    // Remove it from its old structure
    $oldSection = $entry->getSection();

    $record = StructureElementRecord::model()->findByAttributes(array(
        'structureId' => $oldSection->structureId,
        'elementId'   => $entry->id
    ));

    if (!$record->deleteNode())
    {
        throw new Exception('Could not delete the old structure node');
    }

    // Set the new sectionId and typeId on the entry
    $entry->sectionId = 2;
    $entry->typeId = 2;

    // Append it to the end of the new structure
    $newSection = $entry->getSection();

    if (!$app->structures->appendToRoot($newSection->structureId, $entry, 'insert'))
    {
        throw new Exception('Could not insert the new structure node');
    }

    // Save the entry
    if (!$app->entries->saveEntry($entry))
    {
        throw new Exception('Could not save the entry');
    }

    // Commit the transaction
    $transaction->commit();

    echo 'success!';
}
catch (\Exception $e)
{
    // Undo whatever changes we already made
    $transaction->rollback();

    throw $e;
}

Plug the right entry/section/type IDs in there, point your browser to http://example.com/move_entry.php and you should be all set!

Warning: Make sure you never run this code for an entry that has any children in the structure, as its children will end up getting removed from the hierarchy.


Loop through categories and get bottom-most category for each tree I need to get the last item that don't have a child. So in this case I need

Mobiltelefoner
Ipad
Køleskab
Vaskemaskine

How to I get the last item that don't have a child without knowing the amount of levels?

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

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

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

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

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

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

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