Language Switcher with Users I have the following setup for a language switcher. I have Member Directory pages which are using Users (rather than Entires or Categories). How can I update this to get it working on these pages?

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

 {% for lang in langSwitcher %}
 {# Set homepage as default #}
 {% set url = alias(lang.baseUrl) %}

 {# Entry is defined #}
 {% if entry is defined %}
  {# Check if that entry exists in other locale #}
  {% set otherLocaleEntry = craft.entries.siteId(lang.id).id(entry.id).one() %}
  {% if otherLocaleEntry %}
    {% set url = otherLocaleEntry.url %}
  {% endif %}

{# Category is defined #}
{% elseif category is defined %}
  {# Check if that entry exists in other locale #}
  {% set otherLocaleCat = craft.categories.siteId(lang.id).id(category.id).one() %}
  {% if otherLocaleCat %}
    {% set url = otherLocaleCat.url %}
  {% endif %}
{% endif %}

{{lang.name|upper}}

{% endfor %}

This isn't perfect by any means and might need tweaking but to get you on your way:

Assuming that on a user page, you are doing {% set user = ... %} somewhere (as you would do {% set entry = ... %} on an entry page), You just add another clause to your if statement, after checking for category, you check for user:

{# User is defined #}
{% elseif user is defined %}
  {% set url = lang.baseUrl ~ 'membership/directory/' ~ craft.app.request.segments|last %}
{% endif %}

Or if you have set the user:

{# User is defined #}
{% elseif user is defined %}
  {% set url = lang.baseUrl ~ 'membership/directory/' ~ user.id %}
{% endif %}


field from category not available via craft.categories my categories have a custom field called titleTag for SEO as well as a number of other fields. When I render them at their URI (/categories/cat1) I can output those fields easily with {{category.titleTag}} etc. However on the main category page I also have a filter button that loads another URI via jQuery.load() to filter the items based on category. So in the filter template I have this to start.

{% set filter = craft.request.getParam('filter') %}
{% set category = craft.categories.slug(filter) %}

I then want to output (amongst other things) the custom field values of the found category like so {{category.titleTag}} but it comes out null (the category found I am testing with has the field filled out.

Where am I going wrong?

Because your category variable is no object of type craft\elements\Category but an ElementQuery in order to fetch the category you need to use the one() function

{% set category = craft.categories.slug(filter).one() %}
{% if category != null %}
    {{ category.titleTag }}
{% endif %}

Your {{category.titleTag}} printed the search criteria. Imagine you would like to set other conditions in your query: how is Craft supposed to know when your query ends?


Prevent invalid activation page failure I created a custom page for account activation failure and I'm telling Craft to route to my custom page by setting the general config setting activateAccountFailurePath. This works as expected.

What I'd like to do is prevent users from being able to directly navigate to the custom account activation failure page. I'd prefer this page only be displayed when Craft routes the user to it. Any suggestions?

Thanks

In your config, you can set activateAccountFailurePath to something like:

'activationAccountFailurePath' => 'members/failed?access=1'

In your template, you can check for the URL parameter 'access' and 404 if it is not set.

Template:

{% if craft.request.getParam('access') != '1' %}
   {% exit 404 %}
{% endif %}

{# rest of your template if parameter is available #}

Of course, someone could still access the page if they had the full URL with the parameter, but it should help limit access.


Plugin routing casing: camel, lower, Pascal Recently got tripped up with plugin routing due to casing.

It seems when you're in the control panel, your "plugin handle" is lower-cased in routes, though both seem to work: /cp/settings/plugins/myplugin (/cp/settings/plugins/myPlugin` also works)

However, when using an controller action, it seems like it must be camel cased (/actions/myPlugin/foo).

Seems inconsistent, unless I'm missing some reasoning.

The docs say [PluginHandle]/[ControllerName]/[ActionName], but it seems like it's actually [pluginHandle]/[controllerName]/[actionName] as the example shows (cocktailRecipes/ingredients/saveIngredient).

This is the general rule of thumb...

Lower (myplugin) - When creating links for the browser to follow ("href" & "src")
Camel (myPlugin) - When creating a path for PHP to interpret (like calling an action)
Pascal (MyPlugin) - Almost never. Only for naming plugin components. (ie: MyPluginService)

Here's the logic behind lower vs. camel... If it's an "href" or "src" for your browser to follow, you're basically referring to the folder name which contains your plugin. If it's a reference for PHP to interpret, that information is used to trigger a part of your plugin by class name.

In the case of a controller action (/actions/myPlugin/foo), that path starts as a normal browser path, until actions gets interpreted by your root index.php file. Once the index file parses out the actionTrigger, the rest of the path is handled via PHP.


Craft install stuck on "Oops" screen I've uploaded the files, verified permissions and set up the database. When I run the install, I see the monkey, and I enter in my details. It appears to go well, until a screen showing only: "Oops"
Using Ben Croker's Craft Requirements Checker, I get:

Success
Minimum requirements met. Craft can run on this server!!

The server is running MySQL 5.1.56 with InnoDB, so I believe it's capable of running Craft.
Any advice?

The cause of this is most likely an overloaded (very common if this is a shared hosting account) or misconfigured MySQL server.

The installer itself should only take 10-20 seconds on 99% of hosts.  However on this one, it sits for about 120 seconds, before Apache redirects the AJAX request to:

'p' => 'internal_error.html',

As seen from your log files.  The underlying error is probably being logged in your Apache error logs, but it is most likely something related to a timeout from the long request.

If I try to manually execute the SQL from a database dump that is working, removing Craft from the equation entirely, it does finish in time, but still takes about 45 seconds when it should be done in less than 10.

I'd contact your host and ask them to check on the performance/configuration of your MySQL box.


Any reason why {% requirePermission 'editEntries:1' %} would stop working within the past week or so? This worked fine last week when the site was in development:

{% requirePermission 'editEntries:1' %}

We made the site live a few days ago. I dont know if its related, but when I now go to pages with this on, I am getting

HTTP 403 – Forbidden – yii\web\ForbiddenHttpException
User is not permitted to perform this action

I have doubled checked all settings, they are still the same. The logged in user getting this message is in a group that is allowed to editEntries for section 1.

Thanks

Assuming you've recently updated to Craft 3.1, if you look in your userpermissions table you'll see that they're now lowercase and using UIDs rather than integer IDs, like this:

editentries:3bb69b06-3e65-4ae5-8d70-6c47c1a88fbe

The only place I can find anything like this documented is in the "Updating Plugins for Craft 3.1" guide

https://craftcms.com/guides/updating-plugins-for-craft-3-1#update-element-source-key-references


Craft Query by Category and Tag I am trying to find the last four Channel entries (Named: Post) with a Category relatedTo "Support" (id: 458) AND Tag relatedTo: "Widget1" (id: 469)
I've had success using Category or Tag but not both:
This Craft Query works for Category

for entry in craft.entries.section('Post').relatedTo('458').orderBy('postDate desc').limit(4).all()

How can I add the dynamic Tag to the Craft query? The dynamic Tag matches the slug of the current page "widget1" or slug of another page "widget2".

Thank you.

You'll probably want to read up a bit on relations in the Craft docs, but I think something like this should work

{# First get the category elements #}
{% set supportCategory = craft.categories().id(458).one() %}
{% set widgetCategory = craft.categories().id(459).one() %}

{# Now we use those elements in our query #}
{% set entries = craft.entries().section('Post').relatedTo(['and',
  { element: supportCategory },
  { element: widgetCategory }
]).all() %}

{% for entry in entries %}
  {# ... your code #}
{% endfor %}

I believe the relation needs an element, but you might be able to do something like .relatedTo(['and', 458, 459]).


Is it possible to create fields in a Matrix block from frontend? My clients wants its restaurant owners to create FAQs from frontend where each owner can add its questions from frontend and the users will have to submit its answers. I thought to implement it through creating a matrix field which will be available for each restaurants entry. The name of the field could be the question and the text field could be the answer. Each users could save there answers to a new block. I know how to put data into matrix fields that are already made. But i can't find anything from which i can add fields in a matrix block. Is it even possible? Is there any type of plugin available which would help me in it? Any other ideas for this issue would be appreciated.

There's a lengthy rundown about this in this ticket if you need a detailed explanation.

In short, you'll want to check out P&T's Guest Entries plugin to populate entries on the back-end from front-end input.

I highly suggest paying very close attention to how you should set up your form fields' name attributes from this StraightUpCraft post (scroll to the very bottom for Matrix fields): https://straightupcraft.com/articles/craft-cms-field-guide-twig?view=input


Conditional statement for nav tag when no children On the menu below I need to change the class on the li from dropdown-submenu to dropdown-item for those entries that don't have children.  Any ideas?

Thanks

{% set pages = craft.entries.section('services') %}
                       {% nav page in pages %}

                {{ page.getLink() }}

                {% ifchildren %}

                        {% children %}

                {% endifchildren %}

        {% endnav %}

Have you tried something like:

If that doesn't work, I suspect you could use {% ifchildren %} in concert with a variable to set the style. In this case, we set the variable to a non-null value if there are children. Then we can use the null-coalescing operator to substitute 'dropdown-item' if there are no children. Like:

{% set listclass = null %}
{% ifchildren %}
    {% set listclass = 'dropdown-submenu' %}
{% endifchildren% }


Redactor: Set a min height and preserve line breaks I'm looking to set a min height on the redactor text area.  The vendor site shows how it can be done, but doesn't specify where to add this code snippet.
$R('#content', {
  minHeight: '500px'
});

I added that to the redactor.js file in the vendor/craftcms/redactor/lib/redactor folder, but it didn't work. Can someone point me in the right direction? I'm trying to avoid installing additional plugins like Control Panel CSS just to do that one thing.
Additionally, is there a way to preserve line breaks in the text area? I work only in the code view mode and after every save, line breaks disappear. I did a search and found some pages on Github that talk about the issue, but I couldn't find a resolution.

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

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

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


Getting image url from globals asset field I can retrieve only the image title from the below code, I can't see why the image URL is showing as empty? its a global handle 'brand' and asset field 'logo':

{% set image = brand.logo.one %}

Thanks to Andrew Fairlie for pointing out I need to make sure Assets in this volume have public URLs set


Editing SuperTable inside Matrix block I have a matrix field set up as global (strategies).
Inside each matrix block there is a SuperTable (pairs)
On each row in the SuperTable there is a lightswitch (active)
I need to toggle the lightswitch programatically for each row.
Looking at the SuperTable and Craft docs, I still can't make heads or tails of this. Can anyone help?
Edit
Ended up with a poor man's solution by going directly to the table and editing the column. Would still love to know how to do this "properly, though.
$disable = StcThreePairs::find()
    ->where(['elementId' => $pair->id])
    ->one();

$disable->field_active = 0;
$disable->save();

So you'll want to update the Super Table Block's content and to do that when in a Matrix field is a little tricky, but it can be done.
$matrixBlocks = $entry->matrixField->all();

foreach ($matrixBlocks as $matrixBlock) {
    $superTableBlocks = $matrixBlock->superTableField->all();

    foreach ($superTableBlocks as $superTableBlock) {
        $superTableBlock->setFieldValues(['lightswitchField' => true]);

        Craft::$app->getElements()->saveElement($superTableBlock);
    }
}


500 Internal Server Error when accessing admin I just get a server error when trying to access /admin, or any other URL. This is a completely new installation on a staging server. The 'Welcome' page shows OK.
I'm guessing this is a .htaccess problem, because if I remove it and change 'omitScriptNameInUrls' to false the login page shows - but unstyled. If I login I get 400 bad request.
I've looked in the web.log, but can't see anything to help there.
The hosting company is IONOS (1&1).
Any ideas?

It turned out that RewriteBase / needed to be added to the htaccess


How do you manage your Craft 'starting point'? We build a lot of Craft site's these days, and now we ave a lot of experience we find we are always having to re-do the same few dozen things at the start of every project, such as setting up a Matrix field called 'Mixed Content' with a bunch of entry types in it, and the same for 'SEO' fields. These are always identical, but they take half an hour or so to set up, every time.

The templates aren't an issue, we have those stored somewhere and can just copy them in, but getting the database stuff done is becoming a chore and it's time that's adding up. How do you handle this?

I have a Craft boilerplate installed on my local machine - like a self-contained website with all the stuff I use on every project (I also keep my front-end framework in here).

When I start a new project:

Duplicate the boilerplate site folder
Create an entry in MAMP
Delete the .git folder
Duplicate the local database for the new site (SequalPro, Navicat)
Delete /craft/config/license.key

Bingo, new site is ready to go with all the fields and front end stuff I need for a new project.


Where/how to add a page title to a section (listing) I have a number of pages/sections (listings) in either channels or structures. Each page/section (listing) will have a heading that displays an editable title of each page/section.

Should I be able to set this up so the client can edit the title of each section from within that section page in admin? I'm not seeing where to do that. Or do I have to put that field in another place, not within my section? Like in a global settings section that provides editing of each of my sections/pages?

For example, if the page heading says 'Our Projects', but my client wants to be able to change it to 'About Our Amazing Projects' or whatever, where is the best place to put that? I see a 'Name' field for each section, but I'm not sure if that is the appropriate place for it.

What I think you're asking is how to manage content for listing/index page that would pull in entries in a channel. Like the main index page for a blog that shows a list of recent blog entries. Or an "Our Projects" page that's the parent for project detail child pages.

The way I like to do this is create a Single section called "Blog Index" or "Our Projects." You can then use that Blog Index entry to manage the page title or any other content like a hero image or SEO metadata.

Then make sure you check the "Show the Title field" option under it's entry types (where you setup the sections fields).

If you are on the Blog index page, you can use {{ entry.title }} in template.

Or if you are on another page, like a blog entry, and you want to pull the Blog Index title, you can do something like this:

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

{{ blogIndex.title }}

I prefer this to using globals because it also handles my settings for the URI route and template instead of relying on file-based template routes.

I think it's possible to pull information about a section/channel/structure like it's name. But the real downside to this approach is it requires the client to change settings in parts of the control panel you don't need or want them poking around in. Those are settings, not content.


Is Craft's search diacritic-sensitive? Is Craft's .search() diacritic-insensitive?

(If not, is there a way to make it so?)

In pure MySQL land, this will depend on the underlying character set and collation of the underlying database and tables that Craft is searching against.  You can read more on the MySQL 5.1 rules regarding that here and see an example of how to utilize it here.

In Craft, however, we will do some normalization and additionally swap any known diacritics with their ASCII counterparts (ü => u) among other things before saving to the craft_searchindex table in the database.


Add elements to ElementSelect via Javascript I'm developing a plugin that works with Spotify's API. I'm wondering if can I add elements to a ElementSelect field. I do have the IDs of the elements I want to add.

Thanks!

Do you need something like this (using jQuery):

$('#yourID').append( '<option value="value">text</option>' );


Option for removing 'transfer content to' when deleting a user? Is there an easy way of disabling the 'transfer content to' option when deleting a user from the admin portal? In my use case, I want users content to always be completely deleted when they are removed from the site.

I can't think of a clean way without hacking core Craft files (which is generally not advisable).

Sounds like a reasonable feature request, though!


Get the ID of a new entry when it's saved Is there a way to save a new entry with a template form, then pass the ID of that new entry along to the redirect location?

The use case is, I'm interacting with a scheduling service and want to pass along the new craft entry ID in a query string to their API. The service has a webhook that fires on successful scheduling (and provides an appointment ID).

Currently, I'm getting the user's email address returned from the API, then assuming that user's most recent section/entry in craft is the one I'm looking for. After that, I can unambiguously handle reschedules and cancellations by referencing the appointment ID.

The form has the following inputs

<input type="hidden" name="action" value="entries/saveEntry">
<input type="hidden" name="redirect" value="/schedule">

and I'd like the /schedule page to get a entryId passed into it

If you wanted to do this without having to write your own plugin, you can achieve this with a simple custom route and an extra parameter in your template.

Your hidden fields could look like:

<input type="hidden" name="action" value="entries/saveEntry">
<input type="hidden" name="redirect" value="schedule/{id}">

And then in config/routes.php put

'schedule/(?P<id>\d+)' => 'scheduleTemplate',

When craft saves the entry, it will redirect you to schedule with the ID of the entry that was just saved as the last segment. The custom route will pick up any digit on the end of the url and assign it to a variable called id which you can then use in your templates.

Some behind the scenes clearance, based on your comment

No they aren't twig variables as the replacement is doing through php (although apparently you can use Twig tags).

When you save an entry the new entry object gets passed in redirectToPostedUrl which, if there is an object passed will call the function renderObjectTemplate in the templates service, this will swap out any {single} or {{twig}} tags with the appropriate attribute and you will get the finished URL returned.

Here are two links to the class reference so you can see what I mean.

The redirectToPostedUrl function

The renderObjectTemplate function


Can I use Craft CMS as a PIM system? Does it make sense to use Craft CMS as a Product Information Management system?

I have already used Craft 3 for a couple of sites, and I understand part of its capabilities. I was a bit puzzled though when I started to look at defining objects or entities with inheritance.

For example, how would you use Sections in Craft CMS to model this entity structure?

Thing

Name
Primary Image
Description (multilingual)

English
Norwegian

Type

Product

Category
Features

Name
Image
Description
etc...

etc...

The "Thing" section could be set as a structure if you're planning of having hierarchy, if not, a channel would suffice. You would then create common fields that pertain to all "Things" and add them to all your entry types.

"Types" would be your entry types that would have different fields that are unique to the "Type" of "Thing".

Thing (Section - Structure/Channel)

Name (Title)
Primary Image (Asset)
Description (Rich Text)
Types (Entry Types)

Product (Entry Type)

Category (Categories)
Features (Matrix Field)

Name (Plain Text)
Image (Asset)
Description (Rich Text)

With this content model you'd be able to extrapolate quite a robust PIM system.


Correct syntax for an OR conditional within a Matrix block I have a dropdown Matrix block and need to check whether a selected value is either one or another.  If either value is selected I want to display some text on the front end.  At the moment I have {% if block.wellFormattedContent =='toBeActioned' OR block.wellFormattedContent =='partiallyActioned' %} but it errors.  Hopefully you can see what i'm trying to do.

Thanks

Martin

As already noted by @Benjammin' in the comments, the or operator has to be lowercase. See Logic Expressions in the Twig docs:

  Operators are case sensitive.

You also have to get the dropdown value explicitly by accessing its value property.

{% if block.wellFormattedContent.value == 'toBeActioned' or block.wellFormattedContent.value == 'partiallyActioned' %}

The short syntax {{ block.wellFormattedContent }} (which internally uses the field's toString() magic method) causes problems within Twig conditionals. You can probably also get around this issue by wrapping it in curly braces.

{% if (block.wellFormattedContent) == 'toBeActioned' or (block.wellFormattedContent) == 'partiallyActioned' %}


Is it possible to detach event listeners? I've got an event listener hooked up like this:

craft()->on('elements.populateElement', array($this, 'onPopulateElements'));

Is it possible to detach/deregister the listener? E.g. something like this (this doesn't work, but to illustrate):

craft()->off('elements.populateElement', array($this, 'onPopulateElements'));

Not possible currently, but there's a feature request.


Get Craft UserGroup by ID in Plugin I'm trying to get a record from my database for a UserGroup (although I'm guessing this applies to a few scenarios really - anything that isn't a Craft Element.

I'm still new to plugin development so I could be approaching this entirely wrong but I'm pretty sure I don't want to be using craft()->db->createCommand() because it might break in a future version of craft when the schema changes and I also can't do it by using craft()->elements->getCriteria(ElementType::UserGroup); because it's not an element.

Is there a best practice for this?

You'll want to go through Craft's service layer to get things like that.

There is a UserGroupsService, which has all sorts of handy methods for retrieving UserGroups like getGroupById() and getGroupByHandle().

You can invoke these from your plugin like:

$userGroup = craft()->usergroups->getGroupById(3);
$groupName = $userGroup->name;

Note that these will return a UserGroupModel populated with your UserGroup information.


Why isn't relatedTo not working (anymore)? I’m using a structure for creating new pages and navigation. In this structure there are multiple entry types where one is used for creating category pages. Here a user can add some content and select a category that will be used to load projects that are related to it.

In my template I'm using this code to do this:

{% set category = entry.projectCategory.first().slug %}
{% set params = {
        section: 'projects',
        relatedTo: category
} %}
{% set projectEntries = craft.entries(params) %}

{{ category }}

{% for projectEntry in projectEntries %}

                    {% set image = projectEntry.featuredImage.first() %}{% if image %}{% endif %}

{{ projectEntry.title }}

{% endfor %}

First I'm getting the category slug that was selected for this category page. After that I'm setting up my parameters for getting projects (this is another section) that are related to that category.

Before it worked perfectly fine when I had put in a "static" category (so not using the category variable) but when I tried to push the selected category the whole thing stopped working. Even going back to my original code that worked doesn't load any projects.

If I remove the "relatedTo" argument it loads all projects just fine.

Also the slug is perfectly shown in the H1 tag.

Any ideas?

You are so close! All you need to do is to remove the ’.slug’, because that is what the param is expecting.


Relation fallback if no category has been selected I have a filter with a few different parameters that get pulled in and I was wondering if there was a relatedTo wildcard that I could use.

Here's the relevant code:

{% set function = craft.app.request.getParam("function") %}

{% set functionSection = 'craft.categories.group('businessFunction')'  %}

{% if function | length %}
    {% set functionSection = craft.categories.group('businessFunction').slug( function|split(',') ) %}
{% endif %}

{% set posts = craft.entries({
          section: category,
          relatedTo: [
              'and',
              { element: functionSection }
          ]
}) %}

The problem is if an entry doesn't have any Business Function selected then it's not related. I could have a conditional that ignores the relationship but there's multiple relations in the real code - it'd be easier if I could set functionSelect equal "all" or something similar.

I had to use a bunch of conditionals to accomplish this - it's not ideal but here's what I came up with

{% set category = craft.app.request.getParam("category") %}
{% set function = craft.app.request.getParam("function") %}
{% set industry = craft.app.request.getParam("industries") %}

{% if not category | length %}
        {% set category = "blog,caseStudies,videos,webinar,whitePapers" %}
{% endif %}

{% set category = category | split(',') %}

{% set posts = craft.entries({
    section: category,
    orderBy: "postDate desc"
}) %}

  {% if function | length %}
    {% set functionSection = craft.categories.group('businessFunction').slug( function|split(',') ) %}
    {% set posts = posts.relatedTo(functionSection) %}
  {% endif %}

  {% if industry | length %}
    {% set industrySection = craft.categories.group('industry').slug( industry|split(',') ) %}
    {% set posts = posts.relatedTo(industrySection) %}
  {% endif %}


URL drops :8888 from localhost I'm running Craft CMS with MAMP at localhost:8888.

When I pass in a URL with {{ entry.title }}, I get http://localhost/news/2016/we-just-installed-craft which gives me a 404 until I manually put in the :8888 after localhost.

Am I missing something in the set up here?

I would try and put the port in your siteUrl config param:

'siteUrl' => 'http://localhost:8888',

Alternatively you might be able to use this though haven't tested it (I believe the php server variable uses the server name & port number):

'localhost' => array(
    'siteUrl' => 'http://'.$_SERVER['HTTP_HOST'],
    'devMode' => true,
    'cacheMethod' => 'file'
)


How to fetch the data from Event I am trying to fetch the content from an event onEntrySave but I don't know how to access the entry's properties from the event. So far I have got the event handler working I would just like to fetch the data, any ideas?

From the docs: http://buildwithcraft.com/docs/plugins/hooks-and-events#listening-for-events

The entry will be in the params property of the $event.  You can access it like so:

$event->params['entry']


In Craft 3, (how) can I disable a category on a per site basis? In the CP, is it possible to disable Category X for site A, and not for Site B? And if so, how?

I guess it is either a bug or the developers don't want us to do it via cp request. In my plugin (phpCode) I can activate and deactivate categories per site easily but the cp template is missing the required input. When you compare the route of a category and an entry you'll notice it easily

Take a look at entries/_edit.html

        {% set parentIdParam = craft.app.request.getParam('parentId.0') ?: craft.app.request.getParam('parentId') %}
        {% for siteId in siteIds %}
            {% set site = craft.app.sites.getSiteById(siteId) %}

                {%- if siteId == entry.siteId -%}
                    {{ site.name|t('site') }}
                    {{ forms.lightswitch({
                        name: 'enabledForSite',
                        on:   entry.enabledForSite,
                        small: true,
                        disabled: isVersion
                    }) }}
                {%- else -%}
                    {% set siteEntryUrl = url(
                        'entries/'~sectionHandle~'/'~craft.app.request.getSegment(3)~'/'~site.handle,
                        (parentIdParam ? { parentId: parentIdParam })
                    ) -%}
                    {{ site.name|t('site') }}

                {%- endif -%}

        {% endfor %}

and the categories/_edit.html

        {% set parentIdParam = craft.app.request.getParam('parentId.0') ?: craft.app.request.getParam('parentId') %}
        {% for siteId in siteIds %}
            {% set site = craft.app.sites.getSiteById(siteId) %}

                {%- if siteId == category.siteId -%}
                    {{ site.name|t('site') }}
                {%- else -%}
                    {% set siteCategoryUrl = url(
                        'categories/'~groupHandle~'/'~craft.app.request.getSegment(3)~'/'~site.handle,
                        (parentIdParam ? { parentId: parentIdParam })
                    ) -%}
                    {{ site.name|t('site') }}
                {%- endif -%}

        {% endfor %}

It's missing the

{{ forms.lightswitch({
     name: 'enabledForSite',
     on:   entry.enabledForSite,
     small: true,
     disabled: isVersion
 }) }}

even though when I include the input to the template it does not work since it's not populated correctly. The _populateCategoryModel method does not recognize the field.

To compare it: EntriesController:

private function _populateEntryModel(Entry $entry)
{
    // Set the entry attributes, defaulting to the existing values for whatever is missing from the post data
    $entry->typeId = Craft::$app->getRequest()->getBodyParam('typeId', $entry->typeId);
    $entry->slug = Craft::$app->getRequest()->getBodyParam('slug', $entry->slug);
    $entry->postDate = (($postDate = Craft::$app->getRequest()->getBodyParam('postDate')) !== false ? (DateTimeHelper::toDateTime($postDate) ?: null) : $entry->postDate);
    $entry->expiryDate = (($expiryDate = Craft::$app->getRequest()->getBodyParam('expiryDate')) !== false ? (DateTimeHelper::toDateTime($expiryDate) ?: null) : null);
    $entry->enabled = (bool)Craft::$app->getRequest()->getBodyParam('enabled', $entry->enabled);
    $entry->enabledForSite = (bool)Craft::$app->getRequest()->getBodyParam('enabledForSite', $entry->enabledForSite);
    $entry->title = Craft::$app->getRequest()->getBodyParam('title', $entry->title);

has the $entry->enabledForSite but the CategoryController

 private function _populateCategoryModel(Category $category)
{
    // Set the category attributes, defaulting to the existing values for whatever is missing from the post data
    $category->slug = Craft::$app->getRequest()->getBodyParam('slug', $category->slug);
    $category->enabled = (bool)Craft::$app->getRequest()->getBodyParam('enabled', $category->enabled);

    $category->title = Craft::$app->getRequest()->getBodyParam('title', $category->title);

does not have it

If you want you could create a plugin to fix this issue, it's actually not that complicated since you can change everything in craft now, so you could overwrite the function. But It would be easier to create a ticket with a feature request or something. Maybe Brad could make it clearer

To Resume
If you want to enable categories per site, you have to include the field to the template and to the controller in _populateCategoryModel then it works


Migrating Joomla K2 nested categories I have a large-ish site built with Joomla and K2, with articles stored in a hierarchy of categories..

What is the proposed way to recreate the Category hierarchy functionality?

What I am interested in is that when a user opens a parent category, he sees all items stored in this category, plus all items stored in children categories.
If he opens a child category, he sees items stored only in this category.

I have tried a demo installation, and experimented a bit with section types and categories, but what I need is some kind of parent-child relation in Categories or Sections.

Could you please help me clarify how these things are distinct and what would be best practice to achieve what I want?

Thanks in advance for your time.

Craft supports hierarchical, nested categories out of the box.

It also supports hierarchical entries, assuming you used the Structure section type (and not a channel or single).

Where Craft and Joomla differ is the output on the front end is completely up to you. There's no default "widget" or anything in Craft that is going to do exactly what you want.

Craft's {% nav %} tag would help you output categories and sub categories. This example uses a structure section but it's also applicable to nested categories as well.

There's a few recipes in the Craft Cookbook that you might find helpful in this instance as well.


Can you prevent upscaling when using Craft's image transforms? With Craft's image transforms used to resize images or generate thumbnails, can you prevent images from being upscaled? There's often cases where it makes no sense to increase the dimensions of an image.

It would be great if there was a setting for this, but I can't find one documented.

Otherwise, is the solution to fetch the image size in Twig and then conditionally apply the image transform?

As found here, this actually seems to be a requested feature that is not yet implemented. However, in the link given, Brandon also supplied a workaround for the time being:

{% set transform = {
width: min(150, image.width),
height: min(100, image.height)
} %}

<img src="{{ image.getUrl(transform) }}">


Creating an .txt file for every entry dynamically I'm looking to create a .txt file with table field data taken from an entry on the fly. All entries would have their own designated files. It's for video chapters with JW Player. They ask for a .vtt file but with testing a .txt seems to work.

I've had a good search but can't seem to find much. I guess the worst case scenario is uploading them via FTP, but preferably not! Thanks.

You can write a plugin that listens to the onSaveEntry event.

When that event fires, you can grab any of the data you need for the text file from any of the custom fields and your plugin can write it out to the filesystem at whatever place it needs for JW Player to consume.


Admin resources are accessible without being logged in Should the /admin/resources/assetthumbs/{assetid}/200 be accessible without being logged in?

I’ve just noticed I can access thumbnails that way, and with some fiddling even let it generate huge images for me

This is on v2.6.3002.

In Craft 2, this is expected behavior.

In Craft 3, we "fixed" it by using an Asset's UID instead of its ID, which makes it harder to guess.


How to use my site's 404 page? I am using Craft only for the blog section of my site. The rest is HTML.

How do I make my site's 404 page come up for errors in the Craft-blog section?

Do I use the errorTemplatePrefix?

Where does that go?

What to I put in there if Craft is above root and my page is mydomain.com/404.html

Can't think of a native way to do this — a few options come to mind, none of which are ideal.

recreate your sites 404 page in your 404 template (should be able to just copy/paste for the most part).
redirect to your site's 404 page from your 404 template (i.e. redirect 'craft/templates/404.html' to 'mydomain.com/404.html'). So in your 404 template you would have:

{%  redirect '/404.html'  %}

Reaching here, but you could also possibly include your 404 page in an iframe in your 404 template.


How to reorder structure entries in the Admin panel? I converted a channel into a structure and now my entries are listed in reverse order.

I have a very large number of entries. Is there a way or a plugin to permanently sort them and store the order?

I don't know if there's a quick/easy way to do this within the admin area, but if you go to Entries, then click on your Structure, there's a little 4-dot symbol to the left of the Entry's title (make sure you have Structure selected in the drop-down to the right of the Search bar). You can click that 4-dot icon and move them around manually. Doing this will reorder the way entries appear on your site.

If you're just looking to reorder the entries within the admin area (and not reorder them on the front-end site), then click the drop-down to the right of the Search bar. You'll see options like Title and Post Date. Once you click one of those, you'll see headers for Title, Post Date, etc., that you can click on to sort entries. Again, this method won't affect how entries are displayed on your site; this only affects the admin area.


Locked out of the admin interface I'm having an issue with the login-page and since this is my first Craft website, I'm a little unsure of where to begin to look.

When attempting to log in to the admin interface, my username/password is rejected only with the message "An unknown error occured". The same goes for trying the "Forgot your password?" function.

As far as I can tell, the only change recently made was running the auto-update to the latest version (2.X) last week. Have not logged back in since, so this could very well be the culprit. The front end loads just fine. I do have a couple of plugins installed, but not sure how I can deactivate them without using the admin interface.

Are there some log files in the /craft folder where I can start to look?

Any help much appreciated.

I don't have enough rep to comment, but I can answer a few of your questions.

Craft logs are located in /craft/storage/runtime/logs.

Make sure you have a backup of the database before you uninstall the plugins. Depending on the plugin you could experience data loss.
To remove the plugins you can go to the /craft/plugins directory and delete the folders.

Keep in mind if you do this it will not allow the plugin to clean up after itself.

I also found this which may help avoid the clean up issue. https://github.com/khalwat/uninstall. It is a tool that allows you to uninstall plugins via the cli.


Craft CMS Shows 404 Error on Admin Pages I'm trying to take a live / currently well functioning production site and create a local version. I downloaded all the files and the database and the site itself now works on my local device but whenever I try to access any of the admin pages to edit the site, I get a 404 page from Craft.

I replaced my entire craft/app folder to help ensure no corrupt file issues and that didn't fix the problem. I also completely deleted the contents of my craft/storage/runtime folder to account for the potential download of temp files that could be confusing the local site and that didn't fix it either.

The local site is running in dev mode and there is no error that shows on any of the admin pages, just a 404.

Any idea what's going on here and possible fixes?

Thanks!

Goodness, I figured out what was going on here. The cpTrigger had been changed from admin to a different name in the craft/config/general file. [Facepalm]


PHP mbstring extension isn't enabled? (WampServer) I'm using WampServer Version 3.0.4 64bit on Windows 10 to run a local dev site. It's been working fine for a few weeks, and I last opened the site about 5 days ago. Today when I go to my site, I'm getting this error:

  Craft CMS requires the PHP multibyte string extension in order to run.
  Please talk to your host/IT department about enabling it on your
  server.

I checked my PHP extensions menu in Wamp, and there is a check mark next to php_mbstring, so it seems to be enabled.

When I go to localhost in my browser to view my Wamp home page, I see the following error:

  * ERROR * The PHP configuration loaded file is: - should be: c:/wamp64/bin/apache/apache2.4.18/bin/php.ini or
  c:/wamp64/bin/php/php5.6.19/phpforapache.ini

I don't know if this is new, but I haven't changed anything in my wamp configuration files since the site was working.

Full Wamp configuration, in case it's helpful:

I'm fairly new to both Wamp and Craft, so not sure where the problem lies. Thanks in advance for any help!

As these things go, after I posted my question, I clicked "Refresh" in the Wamp menu and now my site works. I'm not sure what changed, especially since I already restarted the entire program several times, but all's well that ends well.

Configuration after refreshing:


Custom Field Type with Multiple Values I'd like to create a field type for my plugin called "location" with two text boxes: one that holds a coordinate for latitude, and one for longitude. I haven't figured out yet how to map those two values from HTML input elements in a template to a JSON array in the database.  Is there an elegant way to achieve this with the Craft API?

You can do this simply by setting your field type’s defineContentAttribute() method to return AttributeType::Mixed, which will tell Craft to JSON-encode its value before storing it in the database.

public function defineContentAttribute()
{
    return AttributeType::Mixed;
}

Then, whatever you submit in the field’s post data will be saved as-is.

For example, if your getInputHtml() method had this:

public function getInputHtml($name, $value)
{
    $lat = (isset($value['lat']) ? $value['lat'] : '');
    $lng = (isset($value['lng']) ? $value['lng'] : '');

    return '<input type="text" name="'.$name.'[lat]" value="'.$lat.'">' .
           '<input type="text" name="'.$name.'[lng]" value="'.$lng.'">';
}

Then it would be expected that the resulting post data for your field would look something like:

array(
    'lat' => '12345',
    'lng' => '67890'
)

And with AttributeType::Mixed, that’s exactly how it would get stored. Behind the scenes it will get JSON-encoded when getting saved to the DB, and JSON-decoded when getting fetched from the DB, but your field type will never need to know about that.


How to set cookie to only show intro animation once per session I'm a Craft beginner, so forgive me if this is an easy question.

I have an intro animation, that I'd only like to show on the first visit to the site, so that it doesn't load again when the user navigates back to the homepage after visiting other pages. Then I'd like it to expire when a user closes their browser.

I'd like to use secure cookies via the Cookies Plugin

The id of the intro animation is id="preloader"

I've put {{ setSecureCookie('intro-animation') }} above the html tag and {{ getSecureCookie('intro-animation') }} with the preloader section.

So how I do I set it up to only show the intro animation on first visit?

You could try something like

  {% set vidAlreadyPlayed = getSecureCookie('intro-animation') %}
        {% if not vidAlreadyPlayed %}
            {{ setSecureCookie('intro-animation', 'hey', now | date_modify("+60 seconds").timestamp ) }}

No cookie set

        {% else %}

Cookie set already

        {% endif %}


Lowering memory usage on task batches I build a plugin for Craft 2 which imports data from an excel file into craft commerce products.

The problem is that it needs to import excels with like 10.0000 rows and 30 columns.

I made a simple page in the CP where they can upload the file and then view the progress inside of the tasks.

Running just 1 task was not good because if it crashes on the first row it just stops. I wanted to make some kind of batching with tasks so this s what I came up with:

public function startExcelImportTasks($fileName){
    $return = false;
    $dataObject = craft()->myplugin_productsInfo->getDataByExcelName($fileName);
    $grandTotal = count((array)$dataObject);
    $batchSize = 500;
    if ($grandTotal > 0) {
        for ($i=0; $i < $grandTotal; $i+=$batchSize) {
            $numberOfTasks = $batchSize;
            //if last loop set numberoftasks to total left
            if (($i + $batchSize) > $grandTotal){
                $numberOfTasks = $grandTotal - $i;
            }
            unset($dataObjectSlice, $dataObjectSliceString, $task);
            $dataObjectSlice = array_slice( $dataObject , $i , $numberOfTasks );
            $dataObjectSliceString = json_encode($dataObjectSlice);
            //create a task per batch
            $task = craft()->tasks->createTask('Myplugin_ImportExcel', 'Import excel - ('. $i . '-' . ($numberOfTasks + $i) .')', ['totalSteps' => $numberOfTasks, 'offset' => $i, 'grandTotal' => $grandTotal, 'dataObject' => $dataObjectSliceString]);
        }
        $return = true;
    }
    unset($dataObject,$grandTotal,$batchSize,$numberOfTasks,$dataObjectSlice,$dataObjectSliceString, $task);
    return $return;
}

So this is all running very well, I get tasks split up by 500 rows. My problem is memory usage, I thought when a new task would start it would free up the memory of the previous task but when I log my memory usage with memory_get_usage(true) it does not reset after the first loop and just continues to build up loop after loop until it finally crashes. It then goes to the next step starting with all free memory.

Is there any way to reset the memory for each loop? Loop 2 does not need to know ANYTHING that loop 1 needs since I slice the data and pass it to the right task.

I tried using some unsets in the code but that doesn't seem to do very much.

I also came across some subtask posts but I do not think that will change anything? I also like that the batching is shown in different tasks in the CP.

Any help is welcome,

Thanks

Ok, update..

The problem of my high memory usage was caused by (I think the logging of) devmode.. When I set devmode to false the moment that hit 10+gig memory before now has 100mb of memory usage...

Resetting memory on the different tasks that get initiated in the same function or as subtasks is not possible I guess?


Trying to launch Craft CMS site on 1&1.co.uk and told I don't have permission. Any help why? Does anyone know how to launch a Craft CMS site on 1&1.co.uk web hosting. I've uploaded my database, changed the siteUrl and uploaded the site with FTP but it's not working. I receive an error message (see image).

It's likely a problem with permissions on your folders. You can find the right permissions here: https://craftcms.com/docs/installing#step-2-set-the-permissions


How can I parse environment variables in a string? I have a string in my plugin that contains environment variables. How can I parse them the same way Craft does?


Search Plus: Target different indices from different environments When testing the indexing configuration, it would be nice to specifically target a testing index. I obviously don't want to disrupt the live data while I make some configuration adjustments. In Algolia, I can clone an index, and rename it something like mydata_test.

Is there a way to target different indices from different environments?

You could check your config for an environment variable and change the name of the index that's searched depending on what environment you're in.

On my SearchPlus integration the index name is set as a data attribute on the search component, so it's possible to vary the index based on the environment:

{% set indexName = 'myindex_test' %}

{% if craft.config.craftEnv == 'production' %}
    {% set indexName = 'myindex_live' %}
{% endif %}

<div class="searchplus" data-index-name="{{ indexName }}">
...
</div>

The search JavaScript reads in the data attributes on initialisation and sets up the Algolia index based on the value of data-index-name.

Note: I'm using this with Craft 2. I understand that you can access config values in Craft 3 via craft.app.config.general.<value>.


How can I handle exceptions on the front end So I have some exceptions being caught in a plugin, and have to assume that in some cases a 500 error is going to occur at some point.

How can we set up Craft so that a server error displays a template rather than the default message display (assuming devMode is OFF)?

This would be something we'd want working across the whole site, not just on one plugin.

If you put a 500.html template in your craft/templates folder, then that will get displayed on the front end when a exception bubbles all the way to the top.  The same will work for other HTTP status codes as well (404.html, 503.html, etc.).


Bumping into max row size of 65k craft_content table in MySQL 5.5 We are building out web applications for one client and have been using Craft to do so. However, I think we may have just hit a limit in the number of fields that Craft will support. More specifically this looks to be more of a MySQL limit. I had recently encountered a similar issue with a single entry that exceeded the row size with too much rich text. This was resolved with an update to the innodb file format, setting it to barracuda.

Unfortunately this is not helping me in this instance as the limitation is now the total byte count for the number of columns, not the actual content.

I've tried changing any columns in the table to 'text' and looked at any other tweaks based on the described limitations, but to no avail.

I'm at a loss for what to do at this point as I am unable to even add one more field without an error being thrown and the DB becoming corrupt.

As soon as I save that one more variable, I get this error:

Internal Server Error

CDbCommand failed to execute the SQL statement:
SQLSTATE[42000]: Syntax error or access violation:
1118 Row size too large (> 8126). Changing some columns to TEXT or BLOB may help.
In current row format, BLOB prefix of 0 bytes is stored inline.

Then when I try to access the admin or any template on the site, I get this error:

Internal Server Error

CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]:
Column not found: 1054 Unknown column 'content.field_heroCtaTitle' in 'field list'

The bummer with this error is I can only recover with a database restore. Didn't want to try and hack out the bad field.

In the short term, I may try to replace some standard fields with matrix fields which should reduce the number of columns in the craft_content table, but this is not really an ideal approach.

Any other thoughts, ideas, hacks would be greatly appreciated!

I came into a similar problem with rich text areas and front end form submissions maxing out memory very easily. It may not solve your issue at the root but as you asked for any thoughts ideas or hacks and for the issue you state. In the rich text field options at the bottom you can change "column type" to "medium editor" which bumps storage from 64K to 4GB.

Hope that helps in any slight way, sorry if it's off point.


Should I use tags for cities? I would like to have some advise on the following:

I'll be running a site with events. These events (channel entries) will take place in a certain city. I don't want to setup every city as a category, but use tags instead. My questions are:

Is it logical to use tags for cities?
Can I list all events based on a city (tag) on my template?

Thanks.

Probably and yes.

Using tags for cities:

If you want to allow users to add any city they want, tags are perfect. If not, you should predefine them, and use categories, dropdowns or multi-selects.

Since you don't know if the user has actually entered a city, you should consider validating it with a custom plugin:

Wait for the entries.onBeforeSaveEntry event
Check if the entered tag is a city. (You could use the Google Geocoding API)

.

List entries which have a specific tag:

You can use relations to find all entries which have a specific tag:

{% set tag = craft.tags.name('miami') %}
{% set relatedEntries = craft.entries.section('events').relatedTo(tag) %}

{# Gets all entries which have the 'miami' tag #}


PHP error when rendering a template from __toString() I have a model with the following functions:

public function render()
{
    $render = craft()->templates->render('myplugin/templates/mymodeltemplate');
    return $render;
}

public function __toString()
{
    return $this->render();
}

Calling __toString() gives me the following error:

Fatal error: Method Craft\MyModel::__toString() must not throw an exception in /projectpath/craft/app/vendor/twig/twig/lib/Twig/Extension/Core.php on line 0

I've found this explanation:

http://php.net/manual/en/migration52.incompatible.php

But I'm not sure how to work around it and accomplish what I'm trying to do...

In PHP, nothing can throw an exception inside of a __toString() method, or else you'll get the error you're seeing.

Not only is that a questionable design decision, it also hides the underlying exception message and stack trace from you.

If you do this, at least you'll be able to log the underlying error and fix that:

public function __toString()
{
    try
    {
        return $this->render();
    }
    catch (\Exception $e)
    {
        Craft::log('ERROR: '.$e->getMessage(), LogLevel::Error);
    }
}

Then you can look in your craft/storage/runtime/logs files for [error] to see the exception message.


Getting previous order history in a Commerce 2 adjuster I am trying to write a Commerce 2 adjuster that will apply a discount on all items from a specific type if a customer bought a specific item with another product type in the last year as well as a minimum price.

It's my first attempt and I'm already stuck trying to retrieve the order history from a specific user.  I can't find anything in the Commerce 2 docs. That's what I have so far. Please be gentle :-)

<?php
namespace craft\commerce\adjusters;

use Craft;
use craft\commerce\base\AdjusterInterface;
use craft\commerce\elements\Order;
use craft\commerce\models\OrderAdjustment;

class FriendDiscount implements AdjusterInterface
{

    // get the current user and check if the discount condition is true
    public function checkIfDonated()
    {
        $user = Craft::$app->getUser();
        if ($user) {
            // check if user bought line item with product type 'typeA' in the last 365 days and spent at least 100$ on it, then return true
            return true;
        }
        return [];
    }

    public function adjust(Order $order): array
    {

        $friendAdjuster = new OrderAdjustment();

        // apply discount if checkIfDonated() returned true
        if ($this->checkIfDonated() == true) {
            // apply discount only on items with the product type 'typeB'
            $friendAdjuster->type = "Discount";
            $friendAdjuster->name = "-14$ Off";
            $friendAdjuster->description = "-14$";
            $friendAdjuster->amount = -14;
            $friendAdjuster->orderId = $order->id;
            return [$friendAdjuster];
        }
        return [];

    }

}

The method to check the previous orders would look something like this:

public function checkIfDonated($order)
{

    $email = $order->getEmail();

    if (!$email) {
        return false;
    }

    $orders = Plugin::getInstance()->getOrders()->getOrdersByEmail($email);

    $didDonate = false;
    foreach ($orders as $previousOrder) {
        foreach ($previousOrder->getLineItems() as $lineItem) {
            $purchable = $lineItem->getPurchasable();
            if ($purchable && $purchable instanceof \craft\commerce\elements\Variant && $purchasable->getProduct()->getType()->handle == 'typeA') {
                $didDonate = true;
            }
        }
    }

    return $didDonate;
}

That above assumes you want to look at all orders made by anyone with that email address. You could add additional guards after the email check to see if they are logged in as a user etc. Hope that helps.

Also, don't forget to pass the order to the method: if ($this->checkIfDonated($order) == true)

And to add the Plugin import: use craft\commerce\Plugin; to the top of the adjuster class.


SiteName in a plugin? I'm sure it's obvious, but how do I get the current site name from within a plugin?

I tried a few things, including

craft()->systemSettings->getSettings('general')

Any ideas?

From searching the files (i.e. 'craft/app/Craft.php' line 124) it looks like you can get it using:

craft()->getSiteName()


Use of localeEnabled(): bug or misunderstanding? localeEnabled(false) does not seem to do anything or I'm misunderstanding its use.

I'm on Craft 2.6 and have this code:

{% for region in Craft.entries.section('handle').level(1).localeEnabled(false) %}

This section is a structure with 3 top level categories which are enabled or disabled for certain languages.
If I'm viewing the site in the Spanish locale for example, I'm only seeing the entries that have Spanish enabled, because they're automatically filtered by Craft to my current Locale as is how Craft works.

So I thought, localeEnabled(false) would get all of the entries in all locales.
But unfortunately, it doesn't work...

Is this a bug or do I misunderstand the function of that command? The explanation in the docs really read as if my understanding of the function is correct.

It's a bit awkward, but you're understanding is correct.  My guess is you probably need to add a .status(null) to take into account the elements global status as well.  localeEnabled, by itself, just checks the element's locale status.


Creating partials outside of the templates folder I'm interested in building a highly modular Craft site in which my folder structure might look something like this:

- craft/
- modules/
  - hero-banner/
      index.html
      scripts.js
      styles.css
  - carousel/
      index.html
      scripts.js
      styles.css
- templates/
    404.html
    index.html
    _layout.html
index.php
robots.txt
.htaccess

An example of what hero-banner/index.html would look like:

{{title}}

{{subtitle}}

An example of how you'd use this in a Craft template like templates/index.html:

{{
  craft.componentUI.run('hero-banner/index', {
    title: 'Welcome to my site!',
    subtitle: 'This is an intro paragraph that has a bit more detail about this site.',
    image: 'http://dummyimage.com/800x350/000000/555555'
  })
}}

A couple reasons I'd like to do something like this:

To create a parity between a style guide and the live site. This way a change to hero-banner/index.html would be reflected in the style guide and the live site. I understand a partial can do the same thing, but I'd prefer something like this because...
We can encapsulate a module's HTML, CSS and JavaScript in one place. Doing this will allow us to utilize Git or npm to manage these modules individually if we'd like to use them on other sites. It also makes locating a module's assets much easier since they're centrally located rather than being in 3 different folders.

I've found a way to reference template files outside the standard templates/ directory to make this work. So I know this sort of setup can work.

However, my question is what problems could arise from this type of setup? Do I need to be concerned about performance/security/something else entirely?

Edit: Just for further clarification, I'm not looking to serve my CSS and JS through Craft. I want to keep my CSS and JS as-is, but wondered if I could call the modules from those directories (outside of the normal Craft templates).

So a few potential things to consider:

You do not want to be serving static assets like Javascript, CSS, etc. out of the templates directory.  I realize you're planning to put them "elsewhere", but ensure that elsewhere is in the /public/ folder, so that php, Yii, and Craft do not have to be spun up just to serve a static asset.  Do not use a Craft routine/plugin to load them.
The entire point of modularization is that the payoff is down the road as you're able to reuse components on future projects by just "plugging them in".  I've seen this approach taken on many types of software projects, from desktop apps to mobile apps to websites.  It almost never works out as well as people think it will, unless it is seriously well architected, because we're generally not a factory churning out widgets.  There are things unique to each website beyond the basic functionality that requires customization; writing something that is both that general, and also useful is difficult.  Think of how many hours you have spent fighting even well-implemented frameworks like Bootstrap or Foundation.
Most things of this nature either end up being way, way over engineered and bloated, with a ton of time spent on them, and the promised gains down the road in terms of time savings never being realized due to the aforementioned issues.

Just my two cents.


404 page title SEOmatic 404 page doesn't have a title. It shows "| Sitename" in my case.

I'm using Craft 3 with the SEOmatic plugin and would like to set the title in the 404 template.

{% set seomaticMeta = seomaticMeta | merge({ seoTitle: '404 page not found' }) %}

This gives a internal server error, looks like the seomaticMeta object is not available on the 404 page.

So it looks like you're using the old syntax for SEOmatic 1.x for Craft 2.x; here's how you do the same thing in SEOmatic for Craft 3:

{% do seomatic.meta.seoTitle("Some Title") %}

c.f.: https://github.com/nystudio107/craft-seomatic#twig-templating


"Unknown error" constantly, seems tied to user preferences I have a user group called Content Loaders with limited permissions. After creating a test user in this group I got an "An unknown error occurred" message every time I navigated anywhere in the CP or saved a change (though both were successful). I started adding back permissions and when I re-enabled General > Perform Craft CMS and plugin updates, the errors went away. Not sure if this is a configuration issue on this new staging server, but everything else seems to be working. I can't find any posts about similar issues. Obviously I don't want people doing data entry to be able to perform Craft updates! ;) Anyone have a clue what might be causing this?

Possibly related: even with an admin account checking for updates just shows the spinner image endlessly. I have no problem checking for updates on my local install. This is running on DigitalOcean (with ServerPilot), Ubuntu 14.04.4 x64 with PHP 7.

The only errors I saw in craft.log (which I cleared before doing something that caused the cpanel error to appear) looked like this:

2016/07/31 03:45:43 [error] [php] include([snipped path]craft/plugins/commerce/vendor/composer/../guzzle/guzzle/src/Guzzle/Http/Client.php): failed to open stream: No such file or directory ([snipped path]craft/app/vendor/composer/ClassLoader.php:412)

This was apparently caused by an almost complete but failed deployment of the app folder. Only a few files were missing/corrupted so Craft still worked other than the issue described.

I replaced the entire craft/app folder (deleted it, unzipped Craft on the server and used mv) and updated the permissions. At this point I got the same error. The error continued to show up after disabling all plugins other than Commerce. But when I disabled Commerce I was able to check for updates again (Craft was already up to date), and under the limited user the errors no longer appear. Oddly, re-enabling Commerce changes nothing. I did encounter a PHP error when navigating within Commerce, so I followed similar steps to upload a fresh copy. Everything appears to be working correctly now.


If merging two sections from different locales how do I then sort them by a shared criteria? I've got a site with multiple locales and I want to merge together content from across these locales, eg News.

The two sections share the same fields so should theoretically be able to be sorted by a shared criteria.

Looking at the post at How do I sort a collection of entries from multiple sections by date? I can merge these both into a single array but when I try to post the ids from these into a new query (to sort the results) only one set of results are returned.

Sample code:

{% set ids = craft.entries.section('news' ~ Section).relatedTo(active).ids() %}
{% set mergeIds = craft.entries.section('newsAlumni').status(null).locale('prior_alum').search('shareNewsAlumni:1').localeEnabled(false).ids() %}
{% set ids = ids|merge(mergeIds) %}

{% set news = craft.entries.id(ids).localeEnabled(false).status(null).order(['stickyNews desc','postDate desc']).ids() %}

If I dump the results of ids I get:

295484 | 3747 | 1787 | 1783 | 1781 | 1778 | 638 | 636 | 640 | 295486

295486 being the entry from mergeIds being returned.
However, if I dump the results of news I get:

295484 | 3747 | 1787 | 1783 | 1781 | 1778 | 638 | 636 | 640

Leaving out the result from mergeIds.
Any thoughts on why the entries from mergeIds are not being included in the resulting news object?

Ta

Cole

With that last {% set news = craft.entries.id(ids) %} criteria model you're querying in one locale only
and there's no way to change that, Craft doesn't have a feature to set up a criteria model to query in multiple locales.

You'd have to merge the entry models themselves and use something like the Super Sort plugin to bring them in order.

{% set entriesA = craft.entries.section('news' ~ Section).relatedTo(active).ids() %}
{% set entriesB = craft.entries.section('newsAlumni').status(null).locale('prior_alum').search('shareNewsAlumni:1').localeEnabled(false).ids() %}
{% set entries = entriesA|merge(entriesB) %}

{% set entries = entries|supersort('sortAs', '{postDate}')|reverse %}
{% set entries = entries|supersort('sortAs', '{stickyNews}') %}


Import Entries with Categories I posted this on github already but I thought I would ask her as well to see if anyone has any ideas

Im trying ot do a simple import of some organizations with categories and parent organization

Here is the CSV

https://www.dropbox.com/s/irh8cno9eh536su/testImport.csv?dl=0

Everything goes in (including the parent which is an entry field and works great) but the categories always end up blank.

Any ideas what might be wrong?  The importer isnt showing any errors.

Anyone curious about this answer, can checkout the GitHub thread referred to above:
https://github.com/boboldehampsink/import/issues/14

The most relevant comment for this answer is by boboldehampsink:

the documentation on category importing isn't complete yet. You have to fill in the complete path with titles, so: Category Title/Subcategory Title/Subsubcategory Title (for example)


Shipping for other category than what's set as default is not applied to total Somehow, shipping rates are not applied to the total when checking out and paying. It does show when selecting the shipping method, but not on the final order review and is not submitted as part of the payment.

The way it's set up is essentially a single shipping method, with geographical rules/zones. There's a "General" category, which is the default, and then an "Accessories" category which applies to smaller items related to that category. In the shipping method's various rules there's a different price set for the two shipping categories, and the non-default "Accessories" category is not being applied.

I'm assuming/hoping it's a user-error on my part, and curious if anyone has run into this, and know of a fix?

Upon further investigation, it seems that no shipping is being applied after updating to the latest Commerce 2. Will report back here.


Separated DB for each locale in subdomain with no shared Craft installation The goal is to have single site (subdomain.domain.dev) with single locale(en_gb) in it and with one craft installation shared with this site only.

I'm not sure if I configured general.php and db.php correctly to get subdomain.domain.dev loaded.

Production steps of What I did:

Set up host to point to subdomain - subdomain.craft.dev

Folders structure:

craft

craft.dev

subdomain.craft.dev
Created database - subdomain_dev
Uploaded necessary files to subdomain folder and edited one line of code

// Tell Craft to serve the subdomain content
define('CRAFT_LOCALE', 'subdomain');
Uploaded en_gb templates to ../craft/templates/en_gb.

I'm not sure, If I also should edit $craftPath to point to templates files for en_gb locale.
Edited general.php

// All environments
'*' => array(),
// Development environment - Locale
'craft.dev' => array(
    'devMode' => true,
    'siteUrl' => array(
        'en' => 'http://craft.dev',
        'en_gb' => 'http://subdomain.craft.dev'
    )
)
);
Edited db.php

// All environments
'*' => array(
    'tablePrefix' => 'craft',
),

// Development environment - Locale
'craft.dev' => array(
    'server' => 'localhost',
    'user' => 'root',
    'password' => '********',
    'database' => 'craft_dev',
    ),
// Development environment - Locale
'subdomain.craft.dev' => array(
    'server' => 'localhost',
    'user' => 'root',
    'password' => '********',
    'database' => 'subdomain_dev',
    )

Locale en_gb was also created from back-end.
When I load the http://subdomain.craft.dev, I get Twig_Error_Runtime saying, that variable doesn't exist.It's like templates in ../craft/templates/en_gb wasn't found?

Generally speaking, locales are designed to share the same templates, so craft is not necessarily looking for a /template/[locale]/ folder to find the correct templates to load. You may have to specify the different locale template paths as part of your section settings in that locales database. As far as I know the only automatic locale routing happens in your public folder, if craft is trying to resolve a route for a static page.

I'm curious as to why you would want to point the different locales to different databases? Keep in mind that structure and data are both stored in the craft database, so if you point 'locale1' at 'db1', and 'locale2' at 'db2', you are essentially loading two entirely separate sites (with their own CP, users, sections, fields, etc). This might make sense if you want to share templates and resources between the two sites. However, if you are also not sharing templates, then it might make more sense to just create two separate installations of craft.

Update

Regarding licensing and subdomains. My understanding is that you can use the same craft license on more than one craft install as long as they share the same primary domain (subdomains are ok). In your case you would set up your local dev environment to be something like: 'project.craft.dev' and 'localeA.project.craft.dev'; and the production environment to be 'domain.com' and 'localeA.domain.com'. You can then purchase the license on 'domain.com' and copy the license file (craft/config/license.key) over to 'localeA.domain.com'.

This is presuming of course that they share the same primary domain. What you can NOT do is create 'domain-localeA.com' and 'domain-localeB.com' using the same license.


Craft unable to determine if an update is available? I just cloned a production site to run in a local environment to test and make sure the site was compatible with PHP7 in preparation for a production server upgrade. For the most part, it seems to have migrated without any issue, except for when I try to check for updates, I get the error: Craft is unable to determine if an update is available at this time. Similarly, the edition button at the bottom of the dashboard gives the error: Craft is unable to fetch edition info at this time.

I tried deleting my license key and clearing caches to no avail, but then I checked logs and noticed this error had been showing up:

2018/02/26 23:50:58 [error] [application] Error in Craft\Et::phoneHome. Message: [curl] 35: Unknown SSL protocol error in connection to elliott.craftcms.com:443  [url] https://elliott.craftcms.com/actions/elliott/app/checkForUpdates

I can’t seem to find any other mention of this issue on StackExchange or elsewhere - any ideas? Thanks so much in advance.

There's a 99% chance you're running old version of MAMP that needs to be upgraded.

The host that https://elliott.craftcms.com lives on recently dropped support for TLS 1.0, which what your stack is trying to connect with.


Advanced Element Queries - example uses In Craft docs element queries article, there is section "advanced element queries", with methods like where, groupBy etc.
What are example use cases of these methods in Twig templates or PHP modules?

These are simply low level operations you can do to more specifically filter the elements that should be returned. It is generally more common to use them in plugins/modules than in Twig templates, but the use-cases are numerous. A few trivial examples are below.
{{ set entries = craft.entries.where(['authorId', 1]).all() }}

{{ set entries = craft.entries.where(['in', 'authorId', [1, 2, 3]]).all() }}

{{ set entries = craft.entries.where(['>=', 'dateCreated', '2021-01-01']).all() }}

{{ set entries = craft.entries.where(['like', 'title', 'prefix%']).all() }}

Detailed docs for where and other DB query parameters can be found here:
https://www.yiiframework.com/doc/guide/2.0/en/db-query-builder#where


Controller action throws a 500 error in some environments We have a plugin. Locally, it's working as expected.

When we push to dev, one of the actions begins to throw a 500 error.

The action is taking place via an ajax call, and the error in the console is:

POST http://website.com/admin/pluginName/controller/method 500 (Internal Server Error)

If I expand that error in the console, I see the following:

k.cors.a.crossDomain.send jquery-2.1.1.min.js?d=1421398025:4
n.extend.ajax             jquery-2.1.1.min.js?d=1421398025:4
n.(anonymous function)    controller:474
(anonymous function)      jquery-2.1.1.min.js?d=1421398025:3
n.event.dispatch          jquery-2.1.1.min.js?d=1421398025:3
r.handle                  jquery-2.1.1.min.js?x=Q4rOzOLw2:3

Checking the Craft Error Logs I see:

Level: error
Category: exception.Guzzle\Http\Exception\ClientErrorResponseException
Message exception: 'Guzzle\Http\Exception\ClientErrorResponseException' with message 'Client error response

Any ideas on what is different about our dev environment vs. the local environment?

Any steps I can take to better diagnose how to solve this issue?

Brad's comment above helped us find the solution.  I had been looking at the craft.log file in the control panel at /admin/utils and it doesn't output the stack trace.  Look at the actual log file, we got more info on the issue which was that the ajax call was returning:

[status code] 401
[reason phrase] Unauthorized

The plugin on the site we have was trying to render a front-end template using Guzzle and the dev site is password protected, and the request was not making it through.

Possible solutions include:

Updating the way the template is being processed to not require a front-end request
Only use this functionality in locations that are not password protected
Hurry up and finish the massive overhaul of the plugin you are working on so this issue doesn't exist any longer!

#3 it is!


Rendering a template from a controller - unable to find template Once again going out of my mind trying to figure something out...
I have a custom controller which I want to return a rendered template. The template should, ideally, reside in my front end templates directory.
But I can't for the life of me figure out the path to use.
The template I want is at ./templates/how-to-book/holidays-for-destination-options.twig but my controller is unable to find it seemingly regardless of how I try to write the path.
This is a sketchy version of the controller (I'm not getting any data yet, just want to render the correct template)
public function actionLoadHolidays()
    {
        $request = Craft::$app->request;
        $destination = $request->post('destination');

        $holidays = [];

        $oldMode = Craft::$app->view->getTemplateMode();
        Craft::$app->getView()->setTemplateMode(View::TEMPLATE_MODE_SITE);

        $this->renderTemplate('how-to-book/holidays-for-destination-options.twig', array(
            'destination' => $destination,
            'holidays' => $holidays
        ));
        Craft::$app->view->setTemplateMode($oldMode);

    }

Using the path as shown, I get the response Not Found: Template not found: actions/my-module/holidays/load-holidays
I'm hitting this controller via an Ajax request if that has any bearing.
Can someone please help me figure this out - I'm feeling dumb!

Yes I was being dumb....
I wasn't returning the rendered template. Controller should be
public function actionLoadHolidays()
    {
        $request = Craft::$app->request;
        $destination = $request->post('destination');

        $holidays = [];

        $oldMode = Craft::$app->view->getTemplateMode();
        Craft::$app->getView()->setTemplateMode(View::TEMPLATE_MODE_SITE);

        return $this->renderTemplate('how-to-book/holidays-for-destination-options.twig', array(
            'destination' => $destination,
            'holidays' => $holidays
        ));

    }


Asset file permissions issue hyperlane I am having trouble setting up image volumes correctly in Hyperlane.
My best guess is that is has something to do with permissions but I have not been able to find a solution.
This is how I have set up the image volume like instructed in Hyperlane's documentation

However when I am uploading images it doesn't show in the templates, and when opening the url path I get a 404.
You can see a page where I have uploaded an image here https://dev-craft3-f59ef5d673d0.hyperlane.co/work/nausea and when I right-click and open the image in a new tab I get a 404 https://dev-craft3-f59ef5d673d0.hyperlane.co/uploads/images/work/nausea.jpg
The template to get the image looks like this
  {% set image = entry.featuredImage.one() %}
  {% if image %}
  <div class="image-box">
    <figure>
      <img
      src="{{ image.getUrl() }}"
      alt="{{ entry.title }}">
    </figure>
  </div>
  {% endif %}

…and the field is set up like this

In Craft, assets are always "absolute" paths to the webroot, not relative to the URL (although you can make it like that).
So in your example, @AssetPublicPath/images is going to be replaced with https://dev-craft3-f59ef5d673d0.hyperlane.co/uploads/images.
If you want something to go into a subfolder, in this case work, you'd need to either specify that as another Craft Volume or specify that in the featuredImage asset field.
Looks like have "restrict uploads to a single folder" checked but there's nothing set in that field so Craft is getting confused as to where to put things.


Get an image from a random entry I have a section with an text field and an image field. the asset field may sometimes be left blank. in this case, in my template, i want to grab the image from another random entry.

This is the code I'm trying to use, but when the image field is blank in my initial entry, I'm getting an error that Variable "image" doesn't exist.
Am I calling the random image incorrectly?

{% for stat in craft.entries.section('statistics').limit(1).order('RAND()') %}
{% if stat.image|length %}
    {% set image = stat.image.first() %}
{% else %}
    {% for random in craft.entries.section('statistics').limit(1).image(':notempty:').order('RAND()') %}
        {% set image = random.image.first() %}
    {% endfor %}
{% endif %}

{{ image.url('medium') }}')

{% endfor %}

I think something like this should work

{# First get all the stats #}
{% set stats = craft.entries.section('statistics') %}

{# iterate over those stat in a random order %}
{% for stat in stats.order('RAND()') %}

    {% if stat.image | length %}

        {% set image = stat.image.first %}

    {% else %}

        {# If there's no image, query for a random stat, excluding those without images #}
        {% set randomStat = stats.image(':notempty:').limit(1).order('RAND()') %}
        {% set image = randomStat.first.image.first %}

    {% endif %}

{% endfor %}


filter entries by id retrieved from matrix block entry I've searched around and other solutions don't seem to be working I must be missing something obvious

Here's what i'm doing

{% set myVar = '' %}
{% for block in entry.matrixComponent %}
     {% if block.type == "matixBlockType" %}
          {% set myVar = block.matrixBlockField.ids() %}
     {% endif %}
{% endfor %}

This seems to work when I dump myVar I get

array(1) {
  [0]=>
  string(5) "10032"

which is indeed the id I'm looking for. I then

{% if entry.id not in myVar %}
    <div> {{ entry.id }} {{ Title }} not in myVar </div>
{% else %}
    <div> {{ entry.id }} {{ Title }} is in myVar {{ myVar }} </div>
{% endif %}

It lists out my posts in the matrix component, and where the entry.id matches myVar it still says not in myVar even though it would seem to me that it should have excluded it.

I'm not sure why it is listing the entry that matches myVar's Id

If I do a similar test:

{% set myVar = ['10032'] %}

{{ dump(myVar) }}

That gives:

array (size=1)
  0 => string '10032' (length=5)

Just like yours.

{% set entryId = 10032 %}

{% if entryId not in myVar %}
    {{ entryId }} not in myVar
{% else %}
    {{ entryId }} is in myVar
{% endif %}

Outputs:

10032 is in myVar

As expected.  Changing entryId to something other than 10032 gives the expected "is not in myVar".

It should be noted that this line:

is in myVar {{ myVar }}

Will cause an array to string conversion error because you're telling Twig to output an array to the browser and it doesn't know how.


Where are all the references to the URL stored? I have my first craft website all working great on my local dev server and want to move it to the production server. I think I went about this the wrong way but I installed a fresh install of craft on the pro server then purchased a pro license.key. This all installed OK. This is the same root level structure as the local dev version.

I made sure both sites were upto date then copied over my database dump from dev and uploaded my templates. However this has broken the URLs (the home page loads). Have I missed something?

The production server doesn't have the domain pointing at it but can be view via the IP like so.

http://79.170.40.48/mydomain.co.uk/    <-- though it does require the trailing lash

The odd bit is if I visit the link

http://79.170.40.48/mydomain.co.uk/products

the browser address bar says

http://79.170.40.48/mydomain.co.uk/products

the apache error says the requested URL is
/home/sites/mydomain.co.uk/public_html/index.php was not found on this server.

And curiously the /home/sites/ address is what my my local dev path is. So where is the remote product install getting this from?

Craft makes it easy to handle multiple environments, but you need to make it aware about the differences. Usually it's smart enough to enough to know the base folder path that you have it hosted in.

It's also smart enough to usually which url's you want. Sometimes it doesn't properly remove index.php from the URL, and that you can manually override with the setting omitScriptNameInUrls.

Since your public folder is named public_html, it's not clear from your question if you are running with the standard folder structure (index.php located in public folder, $craftPath inside index.php pointing to craft/ folder one level above public folder).

In general, you should have a look at the documentation regarding multi-environment configuration.

The one other area where it's usually necessary to set environment specific settings is Asset sources: Check out the chapter on that in the docs as well.


Manual update fails on server I tried up update to the latest Craft, but assets are not loading and the process stops here.

I deleted the storage/runtime folder but I got no luck.

Log says:

2016/11/08 20:17:23 [error] [application] Tried to read the folder contents of /var/www/dev/craft/craft/storage/runtime/compiled_templates/, but could not.

It doesn't matter if I set it to 777 or correct user.

Even stranger is that dispite the error log, I get content created in the compiled_templates folder.

I figured it out. It was super unexpected, after turning on errors finally, I got

 Fatal error: Class 'Craft\AppPathCacheDependency' not found in

Then I realized that GIT didn't include that file, still not sure why, but now I know the cause.


FeedMe: How to import data into the Matrix field of a section? I have a section called "Musicians" which is already set up and populated.
It has an unpopulated "Albums" Matrix field which will hold each artist's albums.

I have exported the albums as a separate JSON file. Now I like to import them into the existing "Musicians" section's Matrix field.

But my three test album entries fail to get added to the corresponding artist.

I've assigned the correct JSON fields to the matrix, but I'm not sure how to connect each album with the existing artist – adding the artist Title field or title slug in FeedMe doesn't do the job.

What am I missing?

Here is a sample JSON structure:

{
  "title":"Milyakburra",
  "url_title":"milyakburra",
  "album_artist_relate":[
     {
        "entry_id":"2590",
        "title":"Emily Wurramara",
        "url_title":"emily-wurramara"
     }
  ],
  "album_release_date":"2018-06-01",
  "album_description":"",
  "album_tracks_1":"Lady Blue\nMilyakburra\nNgarrikwujeyinama\nCarry Me Home\nBlack Smoke\nLullaby\nHey Love\nTap Sticks\nYimenda-Papaguneray (Turtle Song)\nBlue Moon, Black Sea\nBlack Boy",
  "album_tracks_2":"",
  "album_cover":"/images/uploads/resources/music/emily-wurramura_milyakburra.jpg",
  "album_fishpond_link_id":"",
  "album_amazon_link_id":"",
  "album_itunes_link_album_name":"milyakburra/1388866633"
},

Edit:
It looks like FeedMe has difficulties finding a match between a musician entry's title field and the album_artist_relate title field. If I manually add a new title field at the top of the structure (and rename the existing one to "title2") FeedMe correctly inserts the data into the matrix.

It seems that FeedMe cannot process such JSON objects as it needs them to be cleaner.

I ended up doing a lot of PHP processing of my exported data until it had the below format. With that FeedMe was happy.

{
  "title":"Emily Wurramara",
  "album":[
     {
        "album_release_date":"2017-02-08",
        "album_description":"",
        "album_tracks_1":"Hey Love",
        "album_tracks_2":"",
        "album_cover":"emily-wurramura_hey-love.jpg",
        "album_amazon_link_id":"",
        "album_itunes_link_album_name":"hey-love-single/1203932967",
        "album_title":"Hey Love (Single)"
     },
     {
        "album_release_date":"2017-02-22",
        "album_description":"",
        "album_tracks_1":"Hey Love Me Too",
        "album_tracks_2":"",
        "album_cover":"emily-wurramura_hey-love.jpg",
        "album_amazon_link_id":"",
        "album_itunes_link_album_name":"hey-love-single/1203932967",
        "album_title":"Hey Love (Me Too)"
     }
  ]
},


Contact Form not sending I'm using the Pixel & Tonic Contact Form plugin.
I have created a template and I'm using the example code from the README file.

No email is being sent. Upon submit it redirects to the form page.  I have successfully sent myself an email test using Php Mail.

Do I need a template at:
<input type="hidden" name="action" value="contactForm/sendMessage">

This is my code:

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

                {% for error in errors %}

{{ error }}

                {% endfor %}

        {% endif %}
    {% endmacro %}

    {% from _self import errorList %}

    <form method="post" action="" accept-charset="UTF-8">
        {{ getCsrfInput() }}
        <input type="hidden" name="action" value="contactForm/sendMessage">
        <input type="hidden" name="redirect" value="/thank-you-for-contacting-us">

Your Name

        <input id="fromName" type="text" name="fromName" value="{% if message is defined %}{{ message.fromName }}{% endif %}">
        {{ message is defined and message ? errorList(message.getErrors('fromName')) }}

Your Email

        <input id="fromEmail" type="text" name="fromEmail" value="{% if message is defined %}{{ message.fromEmail }}{% endif %}">
        {{ message is defined and message ? errorList(message.getErrors('fromEmail')) }}

Subject

        <input id="subject" type="text" name="subject" value="{% if message is defined %}{{ message.subject }}{% endif %}">
        {{ message is defined and message ? errorList(message.getErrors('subject')) }}

Message

        <textarea rows="10" cols="40" id="message" name="message">{% if message is defined %}{{ message.message }}{% endif %}</textarea>
        {{ message is defined and message ? errorList(message.getErrors('message')) }}

        <input id="kneesbees" class="kneesbees" name="kneesbees" type="text">

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

I figured out what was happening. There was a conflict with a previously installed plugin, Sprout Invisible Captcha.


Finding corresponding category in different subtrees of a category group I'm building a language switcher for a clients website. The website consists of multiple regions which can have multiple locales. As regions aren't supported yet in Craft 2, I've worked my way around that in a variety of ways.

For my products section, I have a category group of product categories. The top level of each tree within that group is the region a product belongs to. So you can have something like this:

US

Category US A

Category US A 1

Europe

Category Europe A

Category Europe A 1

So when selecting category 'US A 1' I know the region this product needs to be shown in is US and I have the correct category too.

Now when switching languages, I check if the region also changes. If so, I have the ID of the new region (which is the first level category of a tree within that group). So, I check if this entry exists related to that category ID.
If so I need to find the exact same subcategory in the Europe tree as was selected in the US tree (so find 'Europe A 1') and check if the entry is also related to that category. If so, send the user to that URL. Problem is I don't know how to do that last step as all I'm getting is an array of categories without any hierachy.

Important: I need this in a plugin in PhP so no Twig.

UPDATE

The only link between for example: 'US A 1' and 'Europe A 1' will be the slug. I'll have to enforce the client to make sure similar categories share the same slug. (Thanks to carlcs to ask this important info I forgot to mention :)

I would just split that category group, if possible, and offer one group for the region and one for the “A1” type of categories.

If this is out of question, you need to find a way to link your categories. Give them the same slug or use another field to make the connection (e.g. a Categories field) and use the corresponding criteria param to filter for the entry in the new locale.

$currentLocaleCategory = $entry->myCategoriesField->last();

if ($currentLocaleCategory) {
    $criteria = craft()->elements->getCriteria(ElementType::Category);
    $criteria->locale = $locale;
    $criteria->descendantOf = $descendantOfParam;
    $criteria->slug = $currentLocaleCategory->slug;

    $newLocaleCategory = $criteria->first();
}


Unable to create the cache directory Unable to create the cache directory
  (/path/craft/storage/runtime/compiled_templates//36).

I receive this on one live installation of Craft CMS.
This is 99% a server issue with permissions. I can't even login to the CP anymore.

My question tough: I don't cache anything on the site.
Does Craft still cache things even with 'cache' => false, or are these two different cache levels?

Yes, Craft still has its runtime caches for compiling Twig templates (as seen in your example) and such. Craft's template and partial cache is separate from Twig's own template compilation, if I'm not mistaken.

If storing in local folders won't work, you can change the cacheMethod setting to use a store other than a local directory ('memcache', 'apc', etc.).


What is the easiest way to include bootstrap in Craft? How is the easiest way to include bootstrap to Craft? I've seen there's already a bootstrap.php in the "app" folder... what can I do with this guy?

There are other ways, but since you've asked for the easiest, that's how I'd do it...
Just add it to /templates/_layout.twig and extend it to other templates: like /templates/index.twig starts with {% extends "_layout" %}
<!doctype html>

    ...
    <link rel="stylesheet" href="/css/bootstrap.css">
    ...

            {% block content %}{% endblock %}

// don't forget jquery/popper here

PS. Make sure `bootstrap.css` and `bootstrap.js` are placed in `/web/css` and `/web/js`


EntryModel attributeConfigs method throwing undefined index I am attempting to read out the entry field attributes by using the attributeConfigs array of the EntryModel.

When I review the EntryModel object, using id and title as an example. I request the attribute configs like this:

    $entry->attributeConfigs['id'] // Works
    $entry->attributeConfigs['title'] // Undefined index error

All though the index exists in the array

    [_attributeConfigs:Craft\ContentModel:private] => Array
    (
        [id] => Array
            (
                [maxLength] => 11
                [min] => -2147483648
                [max] => 2147483647
                [decimals] => 0
                [type] => number
                [unsigned] =>
                [length] => 10
                [column] => integer
            )

        [title] => Array
            (
                [required] =>
                [maxLength] => 255
                [label] => Title
                [type] => string
            )

Is there any way I can access these configurations?

An entry's title is stored on the ContentModel, so you'd need to do:

$content = $entry->getContent();
$content->attributeConfigs['title'];


Edit multiple entries at once through the front-end I am making/trying to make a reservation system with Craft. Logged-in members should be able to make a reservation for a hotel room on the front-end, and change it later.

I am keeping a stock for the available hotel rooms in entries. I have channel section called "rooms". In that section are 2 entries (= 2 different hotels). Every entry has information about the hotel (name, location,...) and has a matrix field with avaialble dates and stock for that date.

What I want to do: a logged-in user can choose a date and choose a number of rooms on that date. He should also fill in all his personal details. I was thinking about making entries of that info in a new channel (e.g. "reservations"). The hard part is: when a user selects a number of rooms, I want the stock of that night edited in the rooms entry. So if we heve 20 rooms available, and a member makes a reservation for 2, the stock should be set to 18.

I guess the first answer to this will be "write a plugin", but I have never written a plugin before, and I have no idea what's the best practice or where to start. Any ideas?

Couldn't you have multiple forms on the page, and submit them via AJAX in sequence when the user clicks on the Submit button?


shell script question on homestead I added a nginx config rewrite rule to remove static asset numbers from file names. It works great on the server config file.

    # enable static file caching
    location ~* (.+)\.(?:\d+)\.(js|css|png|jpg|jpeg|gif|webp)$ {
     try_files $uri $1.$2;
    }

However I'm now trying to use a custome serve-craft.sh on my homestead local to replace the default serve.laravel.sh. (to prevent losing my nginx config every time I do a reload --provision).

I'm not familiar with sh syntax and the following doesn't seem to work when I load the sh by adding a "type:craft" to my homestead.yaml
I suspect the try_files line has syntax error

How could I rewrite this in shell script?

Any idea anyone?

The best way to accomplish what you're trying to accomplish would be to utilize the after.sh shell script that Homestead provides. Check out Extending Homestead and Local Development with Vagrant / Homestead