Filtering Search Results by Category I'm currently trying to filter my search results by category, I've been following this tutorial but cannot get it to work. It keeps not adding on the category parameter, but instead just replaces the search parameter like so:

On search:
"/search/?q=dress"

On Clicking a Filter:
"/search/?category=wedges"

Below is the code running my search box:

  <form action="search/" class="form">
    <input type="text" class="text-field w-input" maxlength="256" type="search" autofocus="true" name="q" data-name="Name" placeholder="e.g. Black Dress" id="name">
    <input type="submit" data-wait="Please wait..." class="search-field-go w-button" value="">
  </form>

and the code running the results page:

{% set query = craft.request.getParam('q') %}
{% if craft.request.getParam('category') is not null %}
    {% set category = craft.categories.slug(craft.request.getParam('category')) %}
    {% set entries = craft.entries.search(query).order('score').relatedTo(category).find() %}
{% else %}
    {% set entries = craft.entries.search(query).order('score') %}
{% endif %}

{% include 'search/_filters' %}

{% if entries|length %}

{{ entries|length }} results:

        {% for entry in entries %}

{{ entry.title }}

        {% endfor %}

{% else %}

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

{% endif %}

   {% for category in craft.categories.group('womens').find() %}

            {{ category.title}}

  {% endfor %}

In this line here (reformatted for legibilty):

  {{ category.title}}

You are generating the url by from craft.request.url and appending the category. But the original query is not part of the url at this point. I think this will work and be clearer:

  {{ category.title}}

This uses the url function, passing it the query string parameters.


How to reset matrix field to have NO blocks in plugin? I want to reset a matrix field to have no blocks in it. In a plugin, I would normally set a matrix field by doing something like this:

$blocks = [];
$i = 1;
foreach ($itemsArray as $item) {
    $blocks['new' . $i] = [
        'type' => 'myBlockTypeHandle',
        'fields' => [
            'someBlockFieldHandle1' => $item['value1'],
            'someBlockFieldHandle2' => $item['value2'],
            'someBlockFieldHandle3' => $item['value3'],
        ],
    ];
    ++$i;
}

$entry->setFieldValues([
    'myMatrixField' => $blocks,
]);
Craft::$app->elements->saveElement($entry);

But I want to do the opposite and set the matrix field to have no blocks. I have tried setting the field to an empty array but it doesn't work:

$entry->setFieldValues([
    'myMatrixField' => [],
]);
Craft::$app->elements->saveElement($entry);

There are no errors on save but the empty array gets ignored and my matrix field still has its data in it. I've tried setting it to empty nested arrays and to null but they all get ignored.

How do I reset a matrix field?

Ok I'm a dummy. A matrix block is an element like an Entry, Asset, etc. So I need to delete it like an element instead of treat it like an array:

$blocks = $entry->myMatrixField->all();

if (! empty($blocks)) {

    $elementsService = Craft::$app->getElements();

    foreach ($blocks as $block) {
        /* @var \craft\elements\MatrixBlock $block */

        $elementsService->deleteElement($block);
    }
}


Calling a method from a service in another plugin from an event I'm having a problem calling a service method from another plugin when hooking into the beforeSend event in the ContactForm plugin. I have the code below in a super simple plugin called ContactFormExtra to catch if someone wants to also subscribe to our newsletter when they fill in the contact form. I have another subscribe plugin setup with it's service class having the methods to do the subscribing - which also handles a simpler subscribe form without the contact form fields. Any ideas on how this could work - or do I need to put all the subscribe stuff again into the ContactFormExtra plugin?

This follows the example on GitHub for pixelandtonic/ContactForm

When trying to subscribe on the contact form, I get this error:

Craft\ContactFormExtraPlugin and its behaviors do not have a method or closure named "_getSettings".

Looks like it's trying to call the Subscribe plugin's functions from the ContactFormExtra plugin?

If I don't choose to subscribe and submit the form, then the Subscribe plugin service call is skipped, moving on to the calls on the ContactFormExtra plugin's service. Then I get this error:

Property "Craft\WebApp.contactformextra" is not defined.

Simple ContactFormExtra plugin code:
(plugins/contactformextra/ContactFormExtraPlugin.php)

class ContactFormExtraPlugin extends BasePlugin
{
  public function init()
  {
    craft()->on('contactForm.beforeSend', function(ContactFormEvent $event) {
      $message = $event->params['message'];
      $subscribe = craft()->request->getPost('subscribe');
      $attribs = $message->getAttributes();
      if ($subscribe == 1) {
        $result = SubscribeService::subscribe($attribs['fromEmail']);
      }
      // save the record
      $attribs = $message->getAttributes();
      $attribs['subscribe'] = $subscribe;
      $enquiryModel = craft()->contactformextra->newEnquiry($attribs);
      craft()->contactformextra->saveEnquiry($enquiryModel);
    });
  }
  ...
}

ContactFormExtra plugin service code:
(plugins/contactformextra/services/ContactFormExtraService.php)

class ContactFormExtraService extends BaseApplicationComponent
{

    public function newEnquiry($attributes) {
      // do stuff here
    }

    public function saveEnquiry(ContactFormExtra_EnquiryModel &$model) {
      // do stuff here
    }

}

Subscriber plugin:
(plugins/subscribe/services/SubscribeService.php)

class SubscribeService extends BaseApplicationComponent
{
  protected $settings;

  private function _getSettings()
  {
    $plugin_settings = craft()->plugins->getPlugin('subscribe')->getSettings();
    $this->settings = $plugin_settings;
  }

  public function subscribe($email)
  {
    $this->_getSettings();
    // do the subscribing here...
  }

}

Capitalization matters when you're calling services. Try updating this line:

$enquiryModel = craft()->contactformextra->newEnquiry($attribs);

to this:

$enquiryModel = craft()->contactFormExtra->newEnquiry($attribs);

and make sure you update that across all the places where you're calling that service. Try that, and post the results. I'll take another look if you're still seeing the issue, which may still be there; just grabbing at low-hanging fruit right now. :)


Order merged query by shared field I’m trying to merge two query sources (some entries and some categories) but have them ordered by a shared field that is a date field. Here’s what I have so far:

set classesLocations = craft.entries.section('classes')|merge(craft.categories.group('locations'))`

I can group by the field of course, but not sure that helps me with ordering.

When I try to use .order('startTime') on the merged object I of course get an error, as they have already been automatically converted to an array to perform the merge rather than remaining as objects. And of course doing the order on both set of objects first doesn’t help, because the merge just tacks the merge on to the end.

Duplicate? How do I combine search for categories and entries into one set of search results?

You will have to use something like supersort to sort your array.

{% set classesLocations = craft.entries.section('classes')|merge(craft.categories.group('locations'))|supersort('sortAs', '{ startTime }') %}


Can you call a controller method from within a plugin/module in Craft 3? I initially asked a question here about how to use Solspace Freeform to build a custom front-end login form. I gave up too easily and accepted the "it's possible but probably not a good idea" answer. Full disclosure: I'm still trying to see if I can use Freeform as a replacement for all of the stock Craft front-end forms (login, user profile, entry, etc). There is so much available out of the box with Freeform in terms of form validation rules and styling, I really want to leverage that for all my forms.

I have a Freeform login form with the appropriate fields
In my custom module, I'm hooking into Freeform's EVENT_FORM_VALIDATE
At this point the Craft::$app->request object has everything that the craft\controllers\UsersController's actionLogin() method would need to attempt to log the user in
Is there some way to "hand off" the current request to the UsersController?
If the login is successful, will the UsersController go about its business and redirect the user properly?
If the login fails, I can add errors the Freeform's response as needed
Is this a terrible idea? Is there a better way to accomplish this?

Based on your goal, I don't recommend taking this approach for the technical debt reasons in my comment, however your actual question is still a valid one. You can call any controller's method from a plugin/module like this:
Craft::$app->runAction('users/save-user');


Is there a thumbnail generator plugin for video assets? I need a thumbnail image of a video which i upload as an asset. Instead of uploading an image manually I'd prefer craft to generate a thumbnail for me.

Is there a plugin I didn't find or did someone find another workaround?

There is a plugin called 'Transcoder' But it's not free:
https://github.com/nystudio107/craft-transcoder/blob/v1/README.md


Get Entries That Match ALL of the tags specified I have a search page where a user can check about 20 different checkboxes, where these checkboxes all relate to tags I have set up inside of Craft. I would like to perform the following search query:

For all of the tags selected, I would like to return a list of entries that have ALL of these tags. For example:

The user clicks the checkboxes, "SCC" and "HVT"

A query should be performed that returns only the entries that have the tags, "SCC" AND "HVT". I have been reading Craft docs for the past 3 hours, and am not grasping this concept at all.

I know this is hardcoded, but I was just experimenting, and it does not work at all:

{% set entries = craft.entries.section('journalArticles').relatedTo('and', { targetElement: 'SCC' }, { targetElement: 'HPV' }) %}

I do not want to use a plugin if I don't have to.

Short version
change the title into an id and it will work
{% set entries = craft.entries.section('journalArticles').relatedTo(
    'and',
    { targetElement: >>idOfYourElement<< },
    { targetElement: >>idOfYourElement<< })
%}

Long version
It looks a little bit nasty (I never do these kind of things in twig because I don't like the syntax and prefer PHP for many reasons) but here you can see a working example for a twig search form
first your html: it could be like this
<form>
    {# loop all your tags and display a checkbox for each one #}
    {# Important: insert the id of your tag as value not the title #}
    {% for tag in craft.tags.group('default') %}
        <input type="checkbox" name="selectedTags[]" value="{{ tag.id }}">{{ tag.title }}

    {% endfor %}

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

And your twig
{% set isSubmitted = craft.request.getParam('submit') %}
{% if isSubmitted %}
    {# get all selected input ids #}
    {% set allRelatedTags = craft.request.getParam('selectedTags') %}

    {# proceed only if the user selected at least one tag #}
    {% if allRelatedTags %}
        {# build your related to array #}
        {% set relations = ['and'] %}

        {# inlcude an additional 'targetElement' for each selected tag #}
        {% for tag in allRelatedTags %}
            {% set relations =  relations|merge([{targetElement: tag}])%}
        {% endfor %}

        {# search for entries with the related parameters #}
        {% for entry in craft.entries.relatedTo(relations).find() %}
            {{ entry.title }}

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

The reason why your code did not work is quite simple as you can see in the relatedTo documentation

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

you inserted the not unique title which could be everything. So all you have to do is to insert the id of your element instead of the title... that's it


Can Craft's Rich Text fields be configured to use Redactor's autosave? The question really says it all. Here's the autosave docs page: http://imperavi.com/redactor/docs/settings/autosave/

I'm just thinking about what would need to happen in order for this to work.

Craft would have to expose Redactor's autosave configuration somehow - either via UI or a Redactor config file.
You'd have to write a plugin and point the autosave configuration to an action on a controller in your plugin.
That action would be responsible for persisting the RTE content as well as the entry and field it came from (since you can have multiple RTEs on a page) - likely the database.

All-in-all, not a very robust solution. It'd be much more likely that we implemented our own autosave solution that worked for all fields at the entry level, instead of just the RTE.


How do you get entry's data from Ajax form submission with Guest plugin? I'm trying to get some info from entry like entry ID that the Guest plugin sent it via Ajax. There are the keys that the plugin responds back with. How can I work out to those keys respectively call them? (response.id) for example?

According to the README, the Guest Entries plugin accepts an AJAX request, and returns an object containing the entry ID, title, and so forth.

As such, if you're using jQuery, you should be able to do something like this (not tested):

$.ajax({
    data: $('#theform').serialize(),
    method: 'POST',
    done: function (data) {
        // The entry title.
        console.log(data.title);
    }
});

I'm not sure how Guest Entries handles errors, so you'll probably want to check the data.success property, before proceeding.


Check which locales of an Entry are active I have a section called News with 2 locales: 'en' and 'nl'. For some News items I have both languages switched on and for some only 1 language. The screenshot shows an example of an entry with only 1 language switched on.

Is there a php method to check the Entry object which languages are switch on?

After doing a quick search through the Craft app folder I found this method:

craft()->elements->getEnabledLocalesForElement($variables['entry']->id)

You can probably use this and send the EntryModel's id as the parameter


Is there a way to divide an entry's data into multiple subviews with unique URLs? I have a one-level structure where I am storing a client's projects, with the ability to reorder them by dragging the entries in the structure.

Each project has been designed to have multiple subpages of information available, accessible by clicking on tabs, where each tabbed view shows a subset of the project data.

Ideally, each tab would have its own URL so I can deep-link to the subpages, each served by a different template, but load in the views via ajax when a tab is clicked on. Is it possible to derive multiple child views with distinct templates from a single entry, without having to manually add child tab entries for every project, which I definitely don't want to make the client do?

The alternative would be to load in all the tabs on initial page load, and show and hide them as they're clicked on, and use pushstate to deep link to those tabs, but I'd rather have them as proper server side URLs, I think.

Does anyone know if this is possible?

Disclaimer: I haven't ever used structure, but hopefully the method described below also works for that section type.

You can do this quite easily with URL-segments

Consider a URL like so:

http://www.domain.com/section/entry/

http://www.domain.com/section/entry/subview-1

And so on.

The section/entry route will hit your entry template, but you can create a new route

section/{slug}/*

And point it to your subview template.

There, you ask craft for whatever is in URL segment 3 like so:

craft.request.getSegment(3)

And display content based on that.

To get the entry you are on currently, just filter on segment 2 like so:

{% for entry in craft.entries.section('section').slug(craft.request.getSegment(2)) %}
    {{ entry }}

{% endfor %}


Error running any Composer command I am working on a project with multiple developers and another member of the team is getting on with a Plugin to assist with some CraftCommerce integrations.

As it's not a publicly available plugin, it's being stored locally in our repo.

However, whenever I run any Composer command on my local machine I get the following error:

[RuntimeException]
  Package <agency>/<plugin> cannot install to
  "/Users/jaycollett/Development/project/build/custom/<plugin>"
  inside its source at "/Users/jaycollett/Development/project/build/
  custom/<plugin>"

We have found this response from Andrew Welch, but it can't be this because our Composer.json repositories section is as follows:

  "repositories": [
    {
      "type": "composer",
      "url": "https://asset-packagist.org"
    },
    {
      "type": "path",
      "url": "./custom/<plugin>"
    }
  ]

After discussing it with the team we worked out that deleting the plugin directory from the /vendors folder and rerunning composer install resolved it. Not sure why though...


How to exclude certain fields from .search() I have an event section in my website with a couple of fields on the entries and one of them is a "related events" field where I can select a other event entries to be shown at the end of the page.

I also use the .search() function to search within events and it happens that events are listed in the results of searches for a certain keyword, where the only appearance is within the related events, which is unwanted behavior.

What I need is to exclude this one field where I can select the related events from the search index.

How can this be solved?

Starting with Craft 3.1 the solution is easy. In the field definition there is a new checkbox: "Use this field's value as search keywords". Uncheck and you're done!

Please note that there was a bug until Craft 3.1.9.1 which prevented this from working. Thanks to Romain poirier and Brandon Kelly (https://github.com/craftcms/cms/issues/3837).


Image Transforms adding white to edges of image I have my image transforms set to crop centre-centre with quality 100, but for some reason the images that are rendered have a high change of having 1 or 2 pixels of white added to at least one set of parallel sides.

See below for an example of what is being output (black background added after the fact for emphasis):

The original image was a JPG with no white border. As far as I can tell, the issue is most prevalent when trying to crop in only one direction. For example, the the image above should only be being cropped on the top and bottom, as the width of the original is the same as the width of the outputted image.

Has anyone else come across this issue? If so, is there a fix?

Running locally on MAMP with PHP 5.6.10, using GD. Craft Pro 2.4.2679

As @BradBell says, using Imagick fixed this for me.
Following https://stackoverflow.com/a/16154605/662826 I uncommented the Imagick extension, reuploaded and the compression was much better and white line gone.


Migrate Craft CMS installation from PgSQL to MySQL - any hints? We need to migrate a Craft installation with a pgsql dump to MySQL.

Any hints on the procedure?

Thanks,
Matthias

For others finding this post: we never made it. We invested > 2 days and then decided to stay with postgresql for this project.


How to view a draft page in live view without publishing it I am creating a news item page for a future release but I can't figure out how to preview it in Live View without Enabling it.  Is there a way to view a page in progress without publishing it live?

This should be possible right out of the box. Make sure that you:

Have the correct entry template set in the Section's settings
Are using Craft's native {{ entry }} variables in the template.

It might be helpful if you posted your template code.


How can I show the child category and not it's parent - but other times show it's parent? I have a categories field on an entry that can have one or many children. I am able to output everything - but would like to restrict the field a bit more.

If a child has been selected, I do not want to show the parent. In my example, I only want to show "child".

It is possible, that I might only choose "parent" and I only want that to show. Or, is there a different way I should go about doing this? Thank you for any suggestions!

I've tried something like this:

{% for service in entry.servies %}
   {% set subCategories = craft.categories.descendantOf(service) %}

   {% if subCategories|length %}
       ...
   {% endif %}
{% endfor %}

But that will show the child category if it's selected or not. I would only like to show the "Child" category if it was actually selected. Otherwise, show the "parent" category.

UPDATE/SOLUTION

First, I want to thank Robin for your help. I tried different variations and was unsuccessful. I ended up taking my existing category and making it a structure. This gave me the flexibility that I needed.

You can change the sort order in your CategoryQuery

{% set child = entry.getFieldValue('servies').orderBy('level DESC').one() %}

returns the category of the deepest level -> the child. If no child is selected you'll receive the parent


Problem with manual upgrade I tried to upgrade a website that I have to the latest version 2.6.2930 from an older 2.6.2804 and for an unknown reason the upgrade failed. I couldn't log in the administration area but the front end was working.

Now I tried to roll back to an old backup that I had 20 days ago. So I restored mysql database askitis.gr_160813_184933_v2.6.2804.sql and I uploaded only the folder /craft/app from the older version of craft Craft-2.6.2804

Now when I get to the website administration panel I get the button to finish up the installation like I'm updating the website. Any ideas what's going on? According to everything I read in order to roll back you need the db and files to be of the same version. I check the craft_info and this is the case

Delete your craft/storage/runtime/cache and craft/storage/runtime/compiled_templates folder after doing this manual update.

Otherwise Craft still references the (now renamed) Garnish Javascript, and the UI for the AdminCP is not functional.


How to loop through category group and identify those related to entry Looping through a category group to show links to all the categories. This is an entry page and I want to highlight any categories assigned to the entry. How do I do that? I've tried this so far:

{% set cats = craft.categories.group('events').find() %}
{% for cat in cats %}
    {{ cat.title }}
{% endfor %}

Your solution looks like it's almost there, but it would be making a lot of DB queries as Craft will be querying the database for each category. You can give Craft all the help you can with something like this.

{# First, retrieve all of your events categories #}
{% set cats = craft.categories.group('events').find() %}

{# Get the IDs of all categories related to this entry #}
{% set relatedCats = craft.categories.group('events').relatedTo({sourceElement: entry}).ids() %}

{# Test if the current category ID is in the array of related category IDs #}
{% for cat in cats %}
    {{ cat.title }}
{% endfor %}


When developing plugins where should you store values that might not strictly be settings? For instance I'm writing a plugin which is going to be periodically pulling stuff from Twitter, so I'd like to keep a hold of when the plugin was last run and maybe some Ids relevant to Twitter that sort of thing.

I know there is the settings array which you use for user defined values, should I also use it for other stuff that the user can't change, or is there a more sensible place to stick those?

You could create a Record which will give you a custom table to store your twitter related settings and update them as needed but I think that your use case is still simple enough that you could leave them in the settings array and then use the Plugins Service to update those settings.

This is how I would do it if I chose to use defineSettings()

// MyPlugin.php
public function defineSettings()
{
   return array(
        // ...
        'twitterApiKey' => array(AttributeType::String, 'default' => '5omeRand0mstriNg'),
        'twitterUsername' => array(AttributeType::String, 'default' => 'someone'),
    );
}

// MyService.php
public function saveTwitterSettings(array $settings=array())
{
    $plugin = craft()->plugins->getPlugin('myplugin');
    $savedSettings = $plugin->getSettings()->getAttributes();
    $newSettingsRow = array_merge($savedSettings, $settings);

    return craft()->plugins->savePluginSettings($plugin, $newSettingsRow);
}

Feel free to follow up with questions/comments if you have any.

@selvinortiz


How do I format the date and time I got from an entry? I am working on a project where the content manager can add events (entries). These events have a date, starting time and end time. The fields in the cms show the option for adding a date, time and time accordingly.

To print them in HTML I do this.

Date

{{entry.datum}}

Starttime

{{entry.begintijd}}

Endtime

{{entry.eindtijd}}

However, only the date is shown, like this:

2014-11-30

2014-11-30

2014-11-30

How do I format the result so I get the times in a format like 15:00?

Also, how do I format the date to be shown in Dutch time format, like 1 januari 2015?

Thanks in advance

You can use the Twig .format() filter to achieve exactly what you are looking for, the reference page for date and time values is here.

So if you would like the date format to show 15:00, you can use:

{{ entry.lorem.format('H:i') }}

And the date format for 1 Januari 2015 will be as follows:

{{ entry.lorem.format('j F Y') }}

As I say, you can reference the website for which values to use.


Build Query relatedTo multiple categories Trying to build a complex query and I'm sure there is bound to be a better way of doing it that the multiple if statements I currently have.
URL for the page is /products/(category1)/(category2)/(category3)

if any of the categorys in the url is selected it will display that slug other wise it will be all e.g.
/products/inks/glass/all
/products/all/glass/catname

I have been doing this:

{# get categories #}
  {% set catTypeSlug = craft.request.getSegment(2) %}
  {% if catTypeSlug != 'all' %}
  {% set catType = craft.categories.slug(catTypeSlug).first() %}
  {% endif %}

  {% set catSurfaceSlug = craft.request.getSegment(3) %}
  {% if catSurfaceSlug != 'all' %}
  {% set catSurface = craft.categories.slug(catSurfaceSlug).first() %}
  {% endif %}

  {% set catUseSlug = craft.request.getSegment(4) %}
  {% if catUseSlug != 'all' %}
  {% set catUse = craft.categories.slug(catUseSlug).first() %}
  {% endif %}

  {# set parameters #}
  {% if catType is defined and catSurface is defined and catUse is defined %}
    {% set params = { section: 'productsServices', relatedTo: catType, relatedTo: catSurface, relatedTo: catUse } %}

  {% else %}
    {# multiple if statements checking if categories defined #}

  {% endif %}

What's the best way to build my parameters instead of multiple if statements?

Untested, but something like this should work:

{# set base criteria #}
{% set params = {
    section: 'productsServices',
    limit: null
} %}

{# set relationship criteria #}
{% set relationParam = ['and'] %}
{% for segment in craft.request.segments %}
    {% if loop.index != 1 and segment != 'all' %}
        {% set category = craft.categories.slug(segment).first() %}
        {% set relationParam = relationParam|merge([{ targetElement:category }]) %}
    {% endif %}
{% endfor %}

{# check to ensure that at least one relationship is defined and merge criteria #}
{% if relationParam|length > 1 %}
    {% set params = params|merge({relatedTo: relationParam}) %}
{% endif %}

{# retrieve entries #}
{% set entries = craft.entries(params) %}
{% for entry in entries %}
    {{ entry.title }}
    ...
{% endfor %}

Update Added a check to ensure that not all segments are set to 'all'; Fixed 'length' syntax.

Give credit to carlcs and his ElementCriteriaModel Fu in this answer.


How do I make it required to enter password when changing user data? Is it possible to enforce users to enter their password when changing their data?
For example when changing their phone number.

Thanks in advance

Craft has a similar concept in the Control Panel for changing sensitive data like passwords/emails you could model called "elevated sessions".

You could write a custom plugin and your form could post to an action in a controller in your plugin, which could check if the phone number for that user has changed.

If so, you'd prompt the user to enter their current password and either do something similar to Craft's UsersController->actionStartElevatedSession, if you need it to last for period of time, or just validate the password and let it go through once.


How can I output the Field Name in my template? I've created a plain text-field and added this field into a section.
I then created an entry and filled it with content.

I know I can output the content of the field in my template with {{ entry.field_handle }}, but is it also possible to display the field name? If so, how?

You can get any field with craft.fields, which returns a FieldModel:

{% set field = craft.fields.getFieldbyHandle('field_handle') %}
{{ field.name }}
{{ field.instructions }}

.

Note: There is no documentation on the FieldModel yet, but if you want to know more, take a look at craft/app/models/FieldModel.php.

This is a list of all attributes supported by the Model:

groupId
name
handle
context
instructions
required
translatable


How to save Order Status Message in Craft Commerce using frontend form It's easy enough update the order status from the frontend using:

<input type="hidden" name="action" value="commerce/orders/updateStatus">
<input type="hidden" name="orderId" value="{{ order.id }}">
<input type="hidden" name="orderStatusId" value="{{ order.orderStatus.id }}">

But I'm wanting to add a message to go with the status. Any pointers? It looks like the message is part of the Order History model, not the Order Status model.

Updating an order from the front end would not be possible unless the user has update/manage order permissions.

As for the message it is simply a message post param that you send along with the status ID.


Commerce - Ajax returning obj.success even when failed I've got a basic jQuery script that I use to update the cart, either through the actions /actions/commerce/cart/updateCart (if product isn't in cart yet) or /actions/commerce/cart/updateLineItem (if product is already in cart.

It's been working fine, however I'm noticing the ajax return object is returning with property .success as true even if the product that was added was out of stock. This leaves the user thinking the product was added, rather than being able to say it wasn't and was out of stock.

For example (not the direct code, might have some errors, but the gist of what I am doing is:)

HTML

<form method="POST" id="addToCartForm">
{{ getCsrfInput() }}
<input type="hidden" name="action" value="commerce/cart/updateCart">
<input type="hidden" name="redirect" value="/cart">
<input type="hidden" name="purchasableId" value="{{ product.id }}">
<input type="hidden" name="qty" value="1">
</form>

jQuery .. on submit form

$form = ("#addToCartForm");

var form_data = $form.serializeArray()

form_data.push({
    name: window.csrfTokenName,
    value: window.csrfTokenValue
})

$.post('/actions/commerce/cart/updateCart', form_data, function(response) {

    if(response.success) {
    console.log("success");
    }

    else if(response.error) {
    console.log(response.error);
    }

    else {
    console.log("neither a success nor an error returned.. ¯\_(ツ)_/¯");
    }

});

The problem is that if the product has no stock left, response still returns with success. Right now, I figured the best thing I can do is look inside response.cart.lineItems and see if the new purchasableId exists in there. If not, than I can assume it wasn't added and will just have to use that as an indicator that stock was empty - although that'd be an assumption not always true.

Is this a bug or would there be a reason/mistake that could cause commerce to return .success as true even when the product being added is out of stock?

This sounds like a bug and I would raise it with support@craftcommerce.com

The stock part of Craft Commerce is still pretty basic at this point.


Merge related entries from several matrix blocks while maintaining other matrix field data I have a matrix that essentially creates categorized lists of other entries. The fields in my matrix block are "categoryName", a plain text field and "member", a entry relationship field.

I know i can output a list in with all of the blocks in order like this:

{% for block in allMembers %}
  {% for member in block.members %}
    {{ block.categoryName }}:
    {{ member.title|typogrify }}
  {% endfor %}
{% endfor %}

And this give me a list like:

Category 1: Apples
Category 1: Oranges
Category 1: Pears
Category 2: Cats
Category 2: Dogs

What I really want, though is to combine the contents of both blocks into a single array, and also pull in the category names,so i can sort them alphabetically by related entry title, like this:

Category 1: Apples
Category 2: Cats
Category 2: Dogs
Category 1: Oranges
Category 1: Pears

I know I can merge all of the related entries into a single array like this:

{% set allMembers = [] %}
{# loop through all relationship fields for this entry #}
{% for block in entry.featuredMembers %}
  {# loop through related entries #}
  {% for member in block.members %}
    {# add member to members array #}
    {% set allMembers = allMembers|merge([member]) %}
  {% endfor %}
{% endfor %}

{% for block in allMembers%}
  {{ block.title }}
{% endfor %}

But then I lose the Category Name. Is there a way to associate the categoryName field with the individual related entries before I merge them into my allMembers array?

Figured it out:

{% for member in allMembers %}
    {% set cat = entry.featuredMembers.relatedTo(member).first() %}
    {{ member.categoryName }}
{% endfor %}


Unable to Access "Settings" in Backend So I've created a boilerplate for my web development company using Craft. However, I'm encountering so much inconsistency across different machines.

I recently set up a new website at my public domain. I set up the webserver, and did a Git pull from the boilerplate Bitbucket I've got going.

After the pull, I did a composer install and installed Craft.

At this point the website is working, but I can't login. The Craft setup never prompted me to create a new user/password. Not sure why.

Regardless of this issue, I have to import my DB from my local box to the web server. So after doing so, I can now login. Great right? Not quite.

After I login, I can't access any Settings in the backend and get a error about my license key. I've since fiddled around with my License Key settings on Craft's website, but I still can't access the Settings panels.

I'm sure there's a process to deploying a site to production, but so far I can't find any consistency. Any advice is greatly appreciated.

Screenshot below.

In your general.php for a production site you'll probably see "allowAdminChanges" set to false. This is not an inconsistency, this is how it is supposed to work.
Every change you make on your local development will be added to a project config file ( yaml file in your config folder ) and fields / sections / settings you create locally will then automatically be synced into your staging or production environment, the reason admin changes aren't allowed by default in there is simple, if you make changes in many places, the project.yaml file will be inconsistent and you'll run into a lot of issues trying to sync your install across different environments.


Why is Craft CMS attempting to connect with SSL3 When either of two of our admin logins attempt to add a new admin user and select to send an activation email, we get this error message:

  Internal Server Error  stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed

Why is Craft CMS attempting to connect with SSL3 which is intentionally disabled at the server level due to known vulnerabilities?

The error is coming from when Craft tries to send out an activation email for the new user.

In Craft's email settings (Settings->Email), you're telling Craft to connect to your email provider over SSL (TLS), but it looks like your local OpenSSL certificate config is setup improperly on your box.

More info here: https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting#php-56-certificate-verification-failure

I definitely wouldn't recommend their workaround of disabling SSL certificate verification as that opens up a slew of security issues, but would fix the local OpenSSL configuration.


How do you use a for loop to output to JS? I have a map generated in JS.

I need to set the country-id and url for each country.  Both 'country-idandurlare fields in my Craft categories groupcountries`.

{
  "country-id": "FR",
  "url": "http://mysite/country/france"
},

I know (basically) how to output to JS for use in my templates.  Here is a link to an earlier question I asked on how to output to JS. This time my question is not how to include JS, but how do I generate a specific output.

How do I incorporate a for loop that produces the desired output for each member of the category country.

{% set nations = craft.categories.group('country') %}
{for country in nations %}
{
"country-id": "{{country.CountryCode}}",
"url": "{{country.url}}",
},
{% endfor %}

Part of the problem is how to I get the loop to also output the script brackets, quotes, commas and attributes that surround the data for each country?

UPDATE -- MORE INFO --- This is the full JS that the above is taken.

It'd probably be easier to assemble the items the way you need them in Twig, and then JSON encode them. Try something like this:

{% set nations = craft.categories.group('country') %}
{% set countries = [] %}
{% for country in nations %}
    {% set thisCountry = {
        'country-id' : country.countryCode,
        'url' : country.url
    } %}
    {% set countries = countries|merge([thisCountry]) %}
{% endfor %}

{% set countryJs %}
var countries = {{ countries|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}
{% endset %}

{% includeJs countryJs %}


"Craft CMS does not support backtracking to this version. Please upload Craft CMS 0 or later." I have a problem related this and this question. I began updating a long time ago (2017?) and got the error "Craft CMS does not support backtracking to this version. Please upload Craft CMS 0 or later" when I try to access the site or admin. I'm just now trying to fix it. I have tried replacing the app folder with a clean craft 2 version and I'm getting a blank white screen on everything.

I run a local install and a live install from the same DB.

What else can I try?

Turns out I hadn't fully uploaded the app folder when I tried to access it earlier. Tried again, made sure it was finished before renaming and it worked fine.


Caching and Rendering We just have experienced a massive hit (traffic) on our site due to a campaign and have noticed that the craft caching solution is not really working well for the templates/html. We are wondering if there is anything else and how we can set it up to cache to MEMCACHED or any other system instead of the database.

I found some interesting posts on Is there a way to override the template caching system?

Thanks!

PS also the render controller is not performing and is taking over 1s to complete. Any suggestions.

The {% cache %} tag will only write to the database.

You don't provide many details, so all I can do is offer some general advice.

I'd double check how you're using the {% cache %} and make sure that you're not over-caching your data or caching lots of static data that might not need it.

You can always through something like Varnish/Fastly in front of Craft to help with template caching.

You can tell Craft to use things like memcache with the cacheMethod config setting, but that only affects Craft's non-template data caches.


User registration; validate email but don't activate automatically is it possible to have the public registration form validate the users Email, but still require manual activation by a system administrator?

There's User Registration - Keep as inactive until verified by admin which I think will stop a clicked email confirmation link from activating the user...

but from what I can tell Craft's "email confirmation" is really just an "activate user via link"; so it's not really confirming the validity of the email nor storing that confirmation anywhere; it's just activating the user. Is that right or am I mis-understanding it?

Thanks,
Matt

I think the approach Johannes posted as an answer to the question you linked to is a good one.

Let the user activate the account via email. It makes sure the address exists and he has access to it, because he can't guess the activation URL without the mail.
This activation only makes him become a member of a Users Group without any permissions at all (e.g. 'unverifiedUsers'). To restrict front end access do something like this:

{% if currentUser.isInGroup('unverifiedUsers') %}

You don't have access rights. Please wait until an admin verifies you account. Thank you!

{% else %}
    {% include 'partial' %}
{% endif %}

Then let an admin do the manual verification: add the user to a group with the permissions you want.


Javascript events when modal window is opened or closed How can I detect when a modal window has been opened or closed?

I am writing a plugin which wants to detect when a garnish elementeditor modal window has been opened or closed.

This is what I ended up doing:

https://github.com/nystudio107/disclosedassets/blob/master/resources/js/disclosedassets.js

There is a Garnish.Modal.visibleModal that will contain the handle to the Garnish modal object if one is visible. You can use this to see if a modal is visible, and even see which one.

Unfortunately there's no event I'm aware of that triggers when a modal is shown, so you'll still have to poll via window.setTimeout() -- it's a hack, but...


Craft 2.6 slow bootstrapping? For some reason when we're bootstrapping Craft CMS it's VERY slow to bootstrap (500ms) worth of slowness. This is utilizing HTTP2 and PHP7 so we're expecting it to be much faster than this.

I'm assuming this is just some setting we're missing and/or our Craft installation is doing too much for one app.

I changed the _layout.html to this:

<!DOCTYPE html>

    <title>TESTING</title>

    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />

TESTING IN THE BODY

Not much going on there. However, this is still taking 500-600ms to bootstrap. This is my general.php file --

<?php

require __Dir__ . '/../../vendor/autoload.php';
require_once __Dir__ . '/../plugins/global/config/Environment.php';

//error reporting
if (Craft\Environment::isProduction()) {
    //log all errors except for notices, strict php guidelines, etc
    error_reporting(E_ALL & ~E_STRICT & ~E_NOTICE & ~E_DEPRECATED);
    ini_set('display_errors', 0);
} else if (Craft\SayEnvironment::isDemo()) {
    error_reporting(E_ALL & ~E_STRICT & ~E_WARNING);
    ini_set('display_errors', 0); //don't display errors to console in demo
}

return array(

//////////////////////////
///  Default Settings  ///
//////////////////////////
'*' => array(
    'useCompressedJs' => false,
    'appId' => 'myappid',
    'validationKey' => 'asdfasfdasdfasdfasfasd',
    'timezone' => 'America/Chicago',
    'omitScriptNameInUrls' => true,
    'generateTransformsBeforePageLoad' => true,
    'maxUploadFileSize' => 33554432,
    'phpMaxMemoryLimit' => '512M',
    'slugWordSeparator' => '-',
    'enableCsrfProtection' => true,
    'devMode' => false
),

////////////////////////
//  Local Overrides  ///
////////////////////////
'localhost' => array(
    'cacheMethod' => 'file',
    'overridePhpSessionLocation' => false,
    'environmentVariables' => array(
        'siteUrl' => 'https://localhost/'
    )
)

);

Realistically all I'm asking Craft to do right now is bootstrap itself and load this _layout.html file. Any ideas why this implementation might be slow? We have 15-20 large plugins but we're not really doing anything with them in this instance?

It shouldn't be that slow to bootstrap, but even if you're not doing anything with the plugins in your template, they are still loaded and instantiated with every request.

If I were you, I'd do some profiling with Blackfire or NewRelic to see what's really going on.


query orders by date AND time in craft commerce How can I query all completed orders within the last hour? It seems craft is only comparing a date by YYYY-MM-DD.

Following query collects all orders from the same day, as {{dateFrom}} would output 2017-10-13 and not eg. 2017-10-13 11:22:08

{% set dateFrom = now|date_modify('-3600 seconds') %}
{% for order in craft.commerce.orders.dateOrdered( '>= ' ~ dateFrom) %}
  ...
{% endfor %}

adding something like
craft.commerce.orders.dateOrdered( '>= ' ~ dateFrom|date('c')) would find any orders at all.

'>= ' ~ dateFrom|date('c')

is correct to output the DateTime object as a string with the time (and timezone) included. If you don’t use the filter it’s output in the Y-m-d format by default.

So my recommendation would be to double check what dateFrom|date('c') actually outputs and to compare it with the dateOrdered values in the CP or database.


How to add a subTask to an already running Task? I have a plugin which creates a task every time a specify form is submited. Now I want to create a WrapperTask and run each of those tasks as a subTask:

I know that I can create a sub-task within the WrapperTask by using $this->runSubTask, but how can I add a subTask to an already running WrapperTask from outside (the service for example)? Or at least send a new settings-array to an already running Task?

Example:

User submits form
Service creates WrapperTask
Service adds subTask to WrapperTask
Nothing happens for some time
User submits form again
Service checks if WrapperTask is still running, and adds subTask

.

If that's not possible, can I at least show them visually as subtasks of my plugin in the task-list?

Sub-tasks can only be initiated by the parent task, and they will only visually look like a sub-task if they are actually sub-tasks.

It’s also not possible to change the settings of an already-running task, at least without manually checking for new settings in your task.

So, your parent task’s getStep() function would need to do its own checking to see if it should be running a sub-task, somehow, and then conditionally call $this->runSubTask().


Whitespace created when using if statements I am using the following block of code in a template:

{% if entry.features | length %}

Features

        {% for block in entry.features %}

 {{ block.feature }}

        {% endfor %}

{% endif %}

The if statement is adding whitespace to the markup which causes styling issues.

How can I correct this? Do I need to format the code block differently?

You can also the hyphen/dash '-' modifier for shorter syntax and in place of the spaceless tags. Plus you get a bit more granular control where you want it, like trimming only leading or trailing space.

Example 1 taken from Twig Docs: Whitespace Control, this would remove whitespace around the if's and output of value.

{% set value = 'no spaces' %}
{#- No leading/trailing whitespace -#}
{%- if true -%}
    {{- value -}}
{%- endif -%}

{# output 'no spaces' #}

Example 2 is a possible real world scenario for retentive space people:

{%- set metaDescription = 'Page description.' -%}
{%- set metaKeywords = 'word1 word2 word3' -%}
{%- set pageTitle = 'A Title' %}

{% if metaKeywords is defined -%}
    <meta name="keywords" content="{{ metaKeywords }}" />
{%- endif %}

{% if metaDescription is defined -%}
    <meta name="description" content="{{ metaDescription }}" />
{%- endif %}

{% if pageTitle is defined -%}
    <title>{{ pageTitle }}</title>
{%- endif %}

Rendered output:

<meta name="keywords" content="word1 word2 word3" />
<meta name="description" content="Page description." />
<title>A Title</title>


Contact Form plugin - Not receiving emails at separate addresses I have implemented the Craft contact form plugin, and have my form set to send to two email addresses. I am receiving messages at one address, but my client is not receiving any messages at the other. Their email address is the same domain as the website.

Any thoughts?

First, make sure you're on the latest version of the plugin. There was a bug related to sending to multiple addresses that got fixed several months ago.

If that's not it, have them check their SPAM folder to see if it's getting trapped in there.

If it's not in SPAM, then try using a different email protocol under Settings->Email in the control panel, preferably SMTP based.  phpmail is notoriously unreliable at email delivery.


Internal server error with Dukt video My site is working fine with dukt videos on local and staging but I am getting an error on any page with a dukt video field. Error is on the front end and the dashboard.

Internal Server Error
Argument 1 passed to Composer\Autoload\ClassLoader::addClassMap() must be of the type array, integer given, called in /homepages/15/d322782150/htdocs/nailcote-craft/craft/plugins/videos/vendor/composer/autoload_real.php on line 38 and defined

I've emailed support directly but in the meantime if anyone has come across this I would be glad of the help.

Fixed. I downloaded fresh copies of OAuth and Video plug-ins. Re-uploaded to server and it's all working.

I guess something got missed or corrupted in the initial upload.


Using a back reference inside a regex search string within replace filter I’m trying to insert a programmatically generated id attribute into child elements of parsedown processed text. I'm aware that Craft’s twig replace filter incorporates preg_replace, so…

I have a regex search string that finds an HTML tag and its contents. It includes an inner back reference to make sure that the closing tag matches the opening tag (as opposed to some nested closing tag)…

(<([a-z][a-z0-9]*)\b[^>]*>(.*?)</\2>)\s+

I can use $1 inside |replace to refer to the entire tag found by the outer parentheses…

elems|replace('/(<([a-z][a-z0-9]*)\\b[^>]*>(.*?)</\\2>)\s/', '$1>,')

…and then work with the results, but the problem (I think) is the syntax for the back reference inside the search string itself.

I've tried the following without success…

elems|replace('/(<([a-z][a-z0-9]*)\\b[^>]*>(.*?)</$2>)\s/', '$1>,')
elems|replace('/(<([a-z][a-z0-9]*)\\b[^>]*>(.*?)</\\$2>)\s/', '$1>,')

Where am I going wrong? Is this even possible with preg_replace? Or is there a better way to go about injecting attributes into parsedown processed text?

Backreferences within the regex are normally defined as \1, \2, etc. In the |replace filter you need to escape all backslashes, so it’ll be \\1, \\2, etc.


How to export Sprout Form submissions with a JSON API endpoint? The goal is to have an endpoint that takes starting id and limit parameters and returns a filtered list of Sprout Form submissions as JSON without the JSON Feed v1 metadata bits.

I've tried to set up an endpoint with Element API, but haven't gotten that working yet. I suspect my elementType is off. I know that there are integration options available in Sprout Forms but from the documentation it looks like it's only pushing the submissions as they come in, not as requested. I've got the endpoint set up on a single PHP page with it's own db table now as a proof of concept.

Is the best way forward to:
a) Complete configuring the element API endpoint.
b) Build a native Sprout Forms data integration.
c) Use custom PHP to get the data and return the JSON.
d) Or something else?

Please see the Sprout Forms Element API documentation page. If it doesn't address your answer, please update your question and I can clarify further.

Here's the example from the docs of both a Form and Form Entries being retrieved from the Element API:

<?php

use barrelstrength\sproutforms\elements\Form;
use barrelstrength\sproutforms\elements\Entry;

return [
    'endpoints' => [
        'api/sproutforms/<formId:\d+>.json' => function($formId) {
            return [
                'elementType' => Form::class,
                'criteria' => ['id' => $formId],
                'one' => true,
                'transformer' => function(Form $form) {
                    foreach ($form->getFieldLayout()->getTabs() as $tab) {
                        foreach ($tab->getFields() as $field) {
                            $fields[] = [
                                'field' => $field,
                                'folder' => $field->getFieldInputFolder()
                            ];
                        }

                        $tabs[] = [
                            'title' => $tab->name,
                            'fields' => $fields
                        ];
                    }

                    return [
                        'handle' => $form->handle,
                        'tabs' => $tabs
                    ];
                },
            ];
        },
        'api/sproutforms/<formId:\d+>/entries.json' => function($formId) {
            return [
                'elementType' => Entry::class,
                'criteria' => [
                    'formId' => $formId,
                    'status' => 'unread'
                ],
                'paginate' => true,
                'transformer' => function(Entry $entry) {
                    return [
                        'id' => $entry->id,
                        'dateCreated' => $entry->dateCreated,
                        'title' => $entry->title,
                        'customField' => $entry->customField,
                    ];
                },
            ];
        }
    ]
];


Getting my head round installing plugins from the command line My command line skills are limited but I’m trying to be better. I’ve been using composer successfully for a while to initiate Craft installs, but then subsequently using the Craft web GUI to install plugins.

Today I thought I’d try and use the command line on a fresh local install, which has DB connection details stored in .env as is usual. The host is configured through MAMP Pro on Mac OS Mojave.

I’ve run composer update on my install and it reported there was nothing to update.

I then used the web GUI to install craftcms/contact-form and all went fine, so there is no doubt that my local DB credentials are correct.

Then, in the command line I invoked:

composer require craftcms/contact-form-honeypot

…which ran fine. And then:

./craft install/plugin contact-form-honeypot

…and got:

  "failed to install contact-form-honeypot: Craft CMS can’t connect to the database with the credentials in config/db.php."

What am I doing wrong?

So this is a MAMP/local dev issue -- run via the CLI, Craft can't connect to the db. Probably it's looking for the wrong mysql.

Check out the MAMP with Composer and MySQL on the Command Line article for details.


Formatting Slug {postDate.month} to 2 characters We are migrating our site into Craft, which is by and far easy and pleasant. But I'm trying to match our old CMS's permalink structure, which used 2-character months in the URI.

When defining the structure to contain our old content, I'm unable to format the postDate.month as I'd like. I thought the Twig below would work, but it's giving me the wrong digit for the month (or example it should be '07' but consistently gives me '12'):

{postDate.year}/{postDate.month|date('m') }/{slug}

I'm sure this is pretty simple, but I can't pin down the syntax. Could someone please give me a hand?

I need a URI like this:

2015/07/here-is-my-slug

You should just be able to do:

postDate|date('m')

postDate by itself should give you a DateTime object which you can then apply the filter to.


Search results by closest match to query I currently have a search box which returns results, but only seems to return results if the search term is an exact match. For example, if i search hospital I will get 5 results back with the name hospital in the title, but if i search hospitals i will get no matches found. I would like the search to return results that are close to the search term as well. This is how i have it set up.

This is my search box. It returns to the same page as my index page has an {% include "components/search" %} to display on the homepage.

   <form class="navbar-search" action="{{ url('') }}">

        <input class="form-control" placeholder="Search" name="q" id="srch-term" type="search">

        <button class="btn btn-default" type="submit"></button>

  </form>

Then my search component is this:

{% set query = craft.request.getParam('q') %}

{% paginate craft.entries.section('Organizations').search('title:' ~ query).order('score').limit(10) as entries %}
    {% if entries|length < 1 %}
        {% paginate craft.entries.section('Organizations').search('organizationSummary:' ~ query).order('score').limit(10) as entries %}

If the title returns no search results I wanted it to search through a summary section instead. Currently it works very well except for only returning exact terms. I'm a bit stuck as I'm ordering by score as shown in the Craft documentation so not sure what I am missing here. Any ideas?

Thanks

Lots going on here, but I'll take a stab at it (in the future, it's helpful if you have multiple questions/issues to make separate posts for them).

Your questions of "why isn't this search term matching" probably comes down to the fact that by default, Craft doesn't do fuzzy matching.  You can use wildcards (*) to change that behavior on a per-search basis.  You can see that syntax here along with all of the other search syntax that Craft supports: https://craftcms.com/docs/searching

Also of note from that page is the defaultSearchTerms config setting, where you can change that behavior.

  Then my search component is this:

{% set query = craft.request.getParam('q') %}

{% paginate craft.entries.section('Organizations').search('title:' ~ query).order('score').limit(10) as entries %}
    {% if entries|length < 1 %}
        {% paginate craft.entries.section('Organizations').search('organizationSummary:' ~ query).order('score').limit(10) as entries %}

That's probably not working as expected because not only can you not nest paginate tags, you can technically only have one paginate tag per request.


Simple navigation with active class? What is the best way to create a simple (one level) navigation that also have active class?

My section types are singles only for now.

Thank you

If you just want to set the active class on static nav then you can just create a conditional using any defining attribute (i.e. title, slug, id, uri-segment, etc). Here is an example using the uri-segment:

{% set uriSegment = craft.request.segment(1) %}

About

Projects

News

    {li}etc

For more dynamic nav:

Singles are not particularly good for creating dynamic nav because there is no built in order or relationship between the items or even a way to identify if they are pages vs some other miscellaneous content. So you will generally have to employ some other strategy instead of, or in addition to, your singles.

If you want to create a more dynamic nav, then there are a few ways to go:

Create a separate structure (named 'primary-nav' for example) that links to the corresponding singles via an entries field (set to limit 1). See this question for an example.
Instead of singles, opt to use a structure (named 'pages'  for example) with different Entry Types defined for each of your page layouts. You can then use entry.type or craft.request.segment(1) in your template to set the 'active' class and load the appropriate sub-template.
Use one of the navigation plugins designed specifically to create page navigation, like a&m navigation or craft nav.


How do I set up Craft 3 to web server in WAMP? I'm very new to Craft CMS, and I certainly love this concept! However, I keep trying to run it locally onto my computer following the documentation here https://docs.craftcms.com/v3/installation.html and can never figure out where to go from "Step 5: Set up the web server" for WAMP. Do I need to install Craft into the 'www' folder for WAMP? It's a very bland explanation for this section and cannot for the life of me figure this out! If anyone can assist please let me know as it is most likely something I have missed :( let me know any information that you need to help answer this question.

I only know mamp. You have to point the local domain to the web folder. If you don't change the folder structure the composer libraries will live outside the public folder just fine.

Do you get any errors or something?


How can a user create an entry that is only enabled for 1 locale? How can a user create an entry that is only enabled for 1 locale?

I would like a German user to only be able to publish an entry in the de locale.

I have set the permissions for the user to only publish in the de locale, but, when this user saves a new entry, the locale is then enabled for every locale.

I have tried disabling each locale in the channel settings, but, then the user is required to enable it for their own locale when publishing.

Similar question here, but no answer yet.

I have tried disabling each locale in the channel settings, but, then the user is required to enable it for their own locale when publishing.

That's the only way to pull off what you're looking for in Craft 2.

With the upcoming Craft 3 refactoring, it would be much easier to pull of with a new event that a plugin could listen to and alter the behavior.

Feel free to make a feature request as well.


Is there simpler, less assuming Craft documentation? I'm really struggling with understanding how Craft works at the moment.
I've been started mid-way on a particular project and I just can't get my head around how Craft works.

Their documentation seems to assume some knowledge I just don't have and combined with the intermediate-to-expert level of Craft-use in the project I'm on, I just can't figure it out.

Right now I'm failing at even the simplest things. I see fields as 'variables' of an entry, which are then sectioned?
I'm doing things that work one particular way:

{% set entries = craft.entries.slug('xyz') %}
{{entries.navigationCaptionTitle}}

..but not another:

{% for block in entries %}
  {{ block.navigationCaptionTitle }}
{% endfor %}

..and I think it's down to my basic understanding of how Sections, Entries and Fields work, how Craft manages them and their basic terminology. I'm definitely a visual learner so anything remotely graphical will help.

I don't have any CMS background, largely just working on html, css and js.

Best is to create fresh Craft instalation and experiment, learn basics. I did the same thing when I was assigned to a large drupal project.

Here is a resource list on Craft:

http://craftcookbook.net
http://straightupcraft.com/articles/getting-started-with-craft-cms
http://webdesign.tutsplus.com/courses/building-landing-pages-with-craft-cms
http://craftcms.com/docs/templating/craft.entries
https://craftcms.com/support
http://straightupcraft.com/events/matrix-entry-types-and-advanced-content-layouts

"..and I think it's down to my basic understanding of how Sections, Entries and Fields work"

It's quite simple really :)
You attach fields to section - this defines a "template" for your entry/entries.

Single type section has one entry, Channel & Structure have multiple entries. Also you can create few entry types for Channel & structure (https://straightupcraft.com/articles/how-do-i-output-an-assets-field-inside-a-matrix-field-inside-an-entry-type).

STRUCTURE SECTION EXAMPLE

Create fields

Create section

Create Entry types (Click Edit Entry types)

Drag&Drop fields

Create new Entries

Note: Entry type changes

Create entry template file (see step 2 for file location).
File located under (installation folder)/craft/templates/example/_entry.twig

Result

You can also pull those two entries from any twig file like this (Details):

{% for entry in craft.entries.section('example') %}
    {{entry.title}}

{% endfor %}

OR just first one

{% set firstExample = craft.entries.section('example').first() %}
{{firstExample.title}}

See also this


Can I Relate Afterwards I've imported Wordpress comments into a post type called 'comments' in a section called 'interactions'. I have the slug stored in 'relatedPostSlug'.

How would I relate the 'relatedPostSlug' to the actual posts with that slug?

If you want to leave the data as-is, you could just fetch the “related” interaction entries like this:

{% for interaction in craft.entries.section('interactions').relatedPostSlug(enry.slug) %}
    {{ interaction.comment }}
    ...
{% endfor %}


SQL Error (Feed Me) when matching entries I'm currently getting the following error when matching on an entry field.

Offers Test: SQLSTATE[42883]: Undefined function: 7 ERROR: operator does not exist: integer ~~ unknown LINE 3: WHERE "id" LIKE $1 ^ HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. The SQL being executed was: SELECT "structureId" FROM "sections" WHERE "id" LIKE '%' LIMIT 1 - Schema.php:664

Currently, I have two channels one is called "Brands" and the other "Offers". Offers has an Entry field which I'm trying to match on this field, see the below image:

I believe this has been fixed in the latest version of Feed Me (3.0.2.1 at time of writing). Do feel free to comment if not, or get in touch via the Feed Me support channels


Import large number of entries every day - 1 million I have a shopping product feed that is generated every day with around a million products. This can be in any format needed - CSV, JSON, XML etc, and will live on an S3 bucket.
Each day, I need to import this feed to entries in Craft and assign them categories etc. A large percentage of the products will be duplicates but it may need to update data within the product.
What would be the best way to import this large of a data set?
I have used FeedMe in the past, but I'm not sure whether it could handle this many products.
Thanks in advance.

You could write a service method that reads the import file and divides it into chunks, then it could dispatch a queue job for each chunk which does the actual entry creation/update. This way you could scale the resources and amount of queue workers available to work through the queue and even Play with the chunk size.
In the queue job you might want to implement proper exception handling to keep track of unsuccessful entry operations to handle them somehow.


Just starting to evaluate - some basic questions We are just in the CMS evaluation stage, so, I have some early questions:

We don't want to create another layer of user logins, can Craft authenticate users using oauth or active directory?
As Craft users -> Why is Craft better than Drupal, Wordpress, Joomla?

For 1), check out Dukt's oAuth plugin for Craft.  Not aware of any Active Directory plugins that have been written yet and not seeing any on here, either.

The second question is pretty subjective, so not sure if that's the best type of question for SE, but I'll let someone else take a stab at it if they want.


How do I set up a section for pages with very flexible content? I'm trying to build a page similar to the index page of buildwithcraft.com. There you have a page with (visual) sections ("A new kind of flexible", "Ready where you are" and so on). Each one has different backgrounds and maybe different layouts as well. Therefore you need a different set of input fields for every such section.

What's the best way to set up a (craft) section that allows you to edit pages like that?

I would use a matrix field with multiple types.


Pull info from a Related field within Matrix > within Super Table Ok, my mind is about to implode with this… any help on template syntax very welcome!

I have 2 Sections: ‘artists’ and ‘schedules’

In the ‘schedules’ section I have a Matrix field called ‘stageSchedule’, with a Block type called ‘dayOfEvent’

In that Block type I have a Super Table field called ‘schedule’. - breakdown....

schedules (Section)

stageSchedule (Matrix) > dayOfEvent (Block)

schedule (Block field (Super Table)) - ST

In ‘schedule (ST)’ I have a date field called ‘timeOn’, which is when the artist is due to be on stage. I thought I could get this information from ‘schedule (ST)’ by having an ENTRIES field called 'act' (in the same ST field) which is linked to a specific artist from the ‘artists' section.

What I want to do... On the individual ‘Artist Bio’ pages I want to display what time they’re going to be on stage by pulling that information from ‘schedule > stageSchedule (M) > dayOfEvent (B) > schedule (ST) > ‘timeOn’.

I have tried every which way but I either get an error or nothing at all :/

I hope that makes sense... Thanks to anyone who can work this one out!

EDIT

As a test I created a Super Table field on it's own (not within Matrix)  and got the data correctly using this:

{% set reverseRelatedElements = craft.superTable.getRelatedElements({
    relatedTo: {
      targetElement: entry,
      field: 'testTimes.artist' // Super Table Field
    },
    section: 'schedules’
  }) %}

  {% for relatedEntry in reverseRelatedElements %}
    {{ relatedEntry.testTimes.timeon|datetime('H:i') }}
    {{ relatedEntry.testTimes.timeOff|datetime('H:i') }}
  {% endfor %}

So basically I need to do the same but target a Super Table field nested in a Matrix field?  Here's an image...

I didn't test it yet but it should like this :

{% set entries = craft.entries().section('schedules').all() %}
{% for entry in entries %}
{% for block in entry.stageSchedule : %}
    {% if block.type == 'yourblocktype' : %}
         {% for item in block.schedule %}
            {{ item.timeOn }}
         {% endfor %}
    {% endif %}
{% endfor %}
{% endfor %}

I assume there is only one entry in schedules sections.
Please be remind block type is different with block name.
Hope this help.


Export more than 50 Freeform submissions (without a lot of scrolling) We've got a site with several Freeform forms, and my client has noticed that when they use Freeform's "Export CSV" they only get the first 50. That's because you need to select all the submissions, then export them – and if you've not scrolled down several times to force all of the other entries to load in, you'll only get the 50 that were initially shown.

Does anyone know a way round this? If you've got hundreds of submissions it feels a bit clunky to have to trigger the AJAXing in of entries before you can export them.

We're on Craft 2.6.3011, Freeform 1.8.6.

Thanks!

Sprout Reports is a flexible reporting plugin that allows you to create custom queries and export the results as CSV.

You could write a custom report using the default Twig Template or Custom Query reports building a report using Freeform variables in your Twig templates or a MySQL query that queries the report Freeform content table directly.

If you'd like to give your users settings, such as which Form to export submissions from, you can add settings to a custom Twig Template report or write a custom integration to define settings and handle your query using PHP.


Find Entries with Multiple Matches in a Single Field I have entries in a channel called "shorts".
Each of those entries has a field called "size" that can be a value of small, medium or large.

I have created a form where I want users to be able to filter entries where the field could match small and medium (for example). I am using checkboxes on my front end form and a drop down field on the Craft admin form.

The URL I'm utilizing looks like this: http://domain.com/search/results?size=small&size=medium

But only the mediums are being displayed.

This is my code. I am not sure how to join the two together so smalls and mediums are displayed:

{% set params = {section: 'shorts', limit: null}
{% if craft.request.getParam('size') %}
{% set params = params|merge({'size':size}) %}
{% endif %}

The main problem is your URL isn't formatted correctly. You need brackets after each 'size' parameter to make an array of those values. Otherwise, it only picks up the last value.

http://domain.com/search/results?size[]=small&size[]=medium

Then you can do something like this:

{% set sizeQuery = craft.request.getParam('size') %}

{% set params = {section: 'shorts', limit: null} %}

{% if sizeQuery %}
  {% set params = params|merge({'size':sizeQuery}) %}
{% endif %}

Also, you can use the dump() function to test what craft.request.getParam('size') is finding in your URL.

{{ dump(sizeQuery) }}

This URL: http://domain.com/search/results?size=small&size=medium

... returns string(5) "medium".

But this URL: http://domain.com/search/results?size[]=small&size[]=medium

... returns array(2) { [0]=> string(5) "small" [1]=> string(5) "medium" }.


Only allow signups from people with @___.com emails I want users to be able to signup to my Craft site, but only if they have a specific email domain. So:

*@gmail.com
*@hotmail.com

Would be allowed, but anyone with a yahoo.com email, for example, would not be able to sign up. I can do client-side validation but is there anything I can do in Craft?

Thanks!

One way of doing this is to write a custom plugin that intercepts the users.onBeforeSaveUser event.

You would check that the submitted email address matched your desired pattern and set $event->performAction = false if the criteria wasn't met. This would prevent the user from being saved.

So the init() method of your plugin might look something like this:

    public function init()
    {
        craft()->on('users.beforeSaveUser', function(Event $event) {

            // Retrieve the userModel from the event
            $user = $event->params['user'];
            $isNewUser = $event->params['isNewUser'];

            // Check if this is a front end request and that we are dealing with a new user
            if (craft()->request->isSiteRequest() && $isNewUser) {

                // Check for valid email address
                if (email address doesn't match required pattern) {
                    // Cancel user save
                    $event->preformAction = false;
                }
            }
        });
    }


craft.feeds does not appear to be working I want do display a financial widget on a front-end of a site.

The financial data is actually a feed:

http://test.solutions.vwdservices.com/customers/vastned.com/page-modules/widgetrss

But it's not working on the frontend. No content.

{% set feedUrl = "http://test.solutions.vwdservices.com/customers/vastned.com/page-modules/widgetrss" %}
{% set limit = 1 %}
{% set items = craft.feeds.getFeedItems(feedUrl, limit) %}

{% for item in items %}

{{ item.title }}

        {{ item.summary }}
{{ item.date }}

{% endfor %}

This is my feed data:

<Feed xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/2005/Atom">
<Title>Aandelen Vastned</Title>
<Id>0</Id>
<Updated>2014-08-22T17:29:40</Updated>
<Entry>
<Title>€ 36,81</Title>
<Id>00000000-0000-0000-0000-000000000000</Id>
<Updated>2014-08-22T17:29:40</Updated>
0,00%
<Author>
<Name>Grijs</Name>
</Author>
</Entry>
</Feed>

FeedsService uses SimplePie for feed parsing, but it currently does expose any errors that SimplePie may be returning when connecting to a feed.

  A feed could not be found at http://test.solutions.vwdservices.com/customers/vastned.com/page-modules/widgetrss. This does not appear to be a valid RSS or Atom feed.

Here's the error it's returning when connecting to that feed.

We'll update FeedsService to return any errors that come back from SimplePie, too.


Implementing Read-Replica (slave) database connections I'm thinking about ways to implement this but don't instinctively know the best route in Craft.

Our infrastructure is in AWS and, due to other applications, we have access to a read-replica DB instance alongside the master instance. I'm wondering about how to write an extension/plugin that would direct all SELECT requests to either the master OR the slave, and all INSERT / UPDATE / DELETE requests to the master only.

What are some possible paths for incorporating this?

Craft 3

You can see an example of how to do read/write splitting in Craft 3 here: https://docs.craftcms.com/v3/config/app.html#database-component

Craft 2

Definitely not current possibly natively in Craft since Yii's CDbConnection (which is what Craft uses for database connections) has no concept of master/slave connections.

In theory, something like the Yii DB splitting extension that @RitterKnight mentioned is a start in the right direction, but even then, you'd have to do some pretty significant core hacking to utilize it in Craft 2.

Should be much more feasible in Craft 3 since the ability to swap out core components like that is planned.


How to create a basic plugin front-end controller? I'm trying to create a very simple controller from a "foo plugin", but it seems there is something i did not understand because i can't make it work. (404 error)
I looked at contactForm plugin as an example; except i'm trying to respond to a "GET" http request.

My plugin is enable and OK.
My plugin is "foo". Here is my controller, in plugins/foo/controllers :

<?php
namespace Craft;

/**
 * Contact Form controller
 */
class fooController extends BaseController {

  function actionHello() {
     $this->renderTemplate('foo/test');
  }

}
?>

This is not supposed to be called with this uri ?

http://craft.local/index.php?p=actions/foo/Hello

Must i register a route to make this work ?

Also tried renaming my controller and class to "foo_testController", and then calling :

http://craft.local/index.php?p=actions/foo/test/Hello

without success.

What am i missing ?

I solved the problem using Pascal Case for naming all my files and classes. I was using camel Case...

So all works fine with those filenames for my "foo" plugin :

FooPlugin.php
controllers/FooController.php

I used Pascal Case for the classes name too, mainly for consistency reason; but i noticed that :

using camelCase for controller class name if the filename is in PascalCase does not break anything
using camelCase for plugin classname breaks the controller.

Anyway, if you don't want issues, juste use Pascal Case (file names and class names) everywhere and you should be Ok.

Please note that with apache, this path is calling my controller correctly (all in lower case)

actions/foo/hello


Commerce template question I have just completed a fresh install of Craft CMS Pro and the Commerce plugin on my local host.  To view the website I go to localhost:8888 and I see the generic home page that says "Welcome to Localhost. Recent News - We just installed Craft" etc...   My question is, how do I view the page that my sample Commerce template is on that I dropped into the templates folder?  In my templates folder it is /templates/shop.  I also still have /templates/news/ in there that came with the Craft Pro in the templates folder as well. Maybe I'm confused but I thought my homepage would be overwritten with some sort of shopping website template, or do I need to go to localhost:8888/xxxxx?

Yes, the example templates are designed to be used inside a subdirectory like /shop. This does not stop you from putting the example templates anywhere else (like the root template directory), but links inside the example template referencing /shop would need to be updated.


How to remove index.php?p= permanently? I discovered search engines found duplicate content on my domain due to URLs being output with index.php?p= and index.php in ADDITION to the clean URLs.

For example, I have:

domain.com/index.php?p=about
domain.com/index.php/about
domain.com/about

And the first two requests with index.php?p= and index.php shouldn't exist. Only the last request with domain.com/about should exist.

While I found help removing index.php, some URLs continue to include ?p=.

So, now I still have:

domain.com/?p=about
domain.com/about

While all I want is:

domain.com/about

Note: This is happening to several pages and blog entries throughout the site. Not only URLs directed to about.

How may I remove ?p= permanently from the remaining URLs?

Within .htaccess, I have:

<IfModule mod_rewrite.c>
    RewriteEngine On

    # Remove index.php
    RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
    RewriteCond %{REQUEST_URI} !^/index\.php/admin\b [NC] # Don't mess with admin requests
    RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]

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

Within craft/config/general.php, I have:

return array(
    '*' => array(

        'omitScriptNameInUrls' => true,
    ),
);

Taken from this answer on Stack Overflow:
.htaccess mod_rewrite: rewriting querystring to path

<IfModule mod_rewrite.c>
    RewriteEngine On

    # Remove index.php
    RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
    RewriteCond %{REQUEST_URI} !^/index\.php/admin\b [NC] # Don't mess with admin requests
    RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]

    # Remove ?p=
    RewriteCond %{THE_REQUEST} ^GET\ /\?(([^&\s]*&)*)p=([^&\s]+)&?([^\s]*)
    RewriteRule ^(.*)$ /%3?%1%4 [L,R=301]

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

This not only reformats /?p=about as /about, but it also preserves other parts of the query string.

For example, /?p=about&tag=stuff and even /?tag=stuff&p=about both redirect to /about?tag=stuff.


Omitting current entry from list of entries generated from a relationship On my template I am showing detail of an entry.
Beneath this I am showing a list of other entries that share the same kind of category relationship as the entry being viewed.

This list currently includes the entry being viewed and I wish to omit that from the list.

I'm retrieving the entries like so:

{% for category in craft.entries.section('apprenticeshipsCats').relatedTo(entry).id('not ' ~ entry.id) %}

and had expected the 'not' parameter to do what I wanted but it doesn't seem to be working. entry.id is outputting the correct ID and even if I hardcode the entry id then it still appears in the list.

You probably kind of confuse your "apprenticeships categories" with your "apprenticeships" section. Try something like this instead:

{% set relatedEntries = craft.entries({
    section: apprenticeships,
    id: 'not ' ~ entry.id,
    relatedTo: {
        targetElement: entry.apprenticeshipsCatsField
    }
}) %}

You now want to order them by your categories? Have a look at my answer I just posted here: "How do I display entries, grouped by distinct categories...".


Looking to create a dropdown field to select an icon I use the same icons across most of my projects, and typically just list them in Dropdown fields. However, this quickly becomes difficult to manage, so I'm looking to create a simple plugin that I can easily reuse.
I've started with pluginfactory.io to scaffold it out, selecting the Field Types component and installed via Composer but struggling from there.

How do I define the list of icons that should show in the dropdown field?
How do I get that to then reference the correct SVG file?
How do I output that properly in my templates with {{ entry.icon }}?

I realise that's literally asking how to build this thing  but I would appreciate some guidance!

What you are describing sounds a lot like the Position Fieldtype. I would look at that plugin for guidance.


Adding link type to Redactor Rich Editor I have a Craft CMS powered site which has "Suppliers" set up as a user group. A route is being used to link through to these suppliers on the frontend; example.com/supplier/loremipsum.
Is it possible to add an option to the link button on the Rich editor field, that would allow me to choose a user from the supplier user group? Much like the "Link to an entry" option.

You could do this with a custom plugin that used the addRichTextLinkOptions to add extra options to that dropdown.

You can use https://pluginfactory.io to generate boilerplate plugin code to get you up and running quickly.


Eager loading EntryElementType from custom ElementType in a plugin trying to get my head wrapped around eager loading element relationships in my plugin. A little context, I’m working on a navigation module and I have a Node element type, which belongs to a Navigation and has one Entry element type:

public function defineRelations(){
return array(
  'element'    => array(static::BELONGS_TO, 'ElementRecord', 'id', 'required' => true, 'onDelete' => static::CASCADE),
  'navigation' => array(static::BELONGS_TO, 'Navee_NavigationRecord', 'required' => true, 'onDelete' => static::CASCADE),
  'entry'      => array(static::HAS_ONE, 'EntryRecord', 'entryId', 'required' => false),
);

}

When I’m getting my nodes, I’d like to eager load the entry for each node. This is where I’m just sort of falling down on they syntax. If I currently have (without eager loading):

$criteria = craft()->elements->getCriteria('Navee_Node');

Would I eager load the entries by doing something like:

$criteria = craft()->elements->getCriteria('Navee_Node')->with(ElementType::Entry);

I should note that what I'm really trying to do is pull the uri for each related entry without having to run an additional query every time I iterate over the navigation. So maybe my thinking is wrong and I don't need to eager load the entire EntryElement type, but just a particular field?

Thanks so much in advance for any insight you can provide.

MW

The article on StraightUpCraft should be able to point you in the right direction. PHP stuff is towards the bottom of the article.

Examples of Eager Loading Elements in Twig and PHP

Also this Craft hangout is worth watching, it gives a lot of detail on Eager loading. It's over an hour long though, so set yourself some time aside to watch it.

Eager loading Elements


How do you use the Venti Calendar plugin with the Element API plugin? I want an endpoint in the Element API plugin that shows the last event entries from the Venti Calendar plugin. The Element API guide tells that's possible to use the plugin with custom element types. But how?

I don't have the Venti Calendar plugin, so I can't test this, but it should be as simple as setting the elementType propety to whatever custom element type the plugin has created and you want to use and (optionally) setting any criteria you want defined by the element type.

return [
    'endpoints' => [
        'news.json' => [
            'elementType' => 'Venti_Event',
            'criteria' => ['key' => 'value'],
            'transformer' => function(Venti_EventModel $eventModel) {
                return [
                    'key' => $eventModel->property,
                ];
            },
        },
    ]
];


Can I stop the logged-in user from selecting other users in the author dropdown? I have a member group that has very fine grain options when they log in. They should only be able to add, edit, and delete their own entries in a single channel. At the moment they can select any user as the author. Is it possible to not allow them to change the author?

They should only be able to add, edit, and delete their own entries in a single channel.

You can currently to this by granting "Edit Entries", "Create Entries", "Publish Live Changes" and "Delete Entries" permission to a user.

However, none of those affect what shows up in the "Authors" drop down and I'm not sure they should.  Technically, changing the author of an entry is still editing the entry.

Maybe what's needed here is an additional permission under "Edit Entries" called "Change Entry Author".


How can I try Craft Pro? I can't find the download links for Craft Pro. Where are they?

https://craftcms.com/support/try-craft-client-pro

Douglas's answer is correct... Also, if you'd simply like to try Craft Pro before purchasing it, you can do so while running Craft in your local environment.

  https://craftcms.com/support/try-craft-client-pro

UPDATE:

It's now possible to try Craft Pro from any non-public domain:

  https://pixelandtonic.com/blog/test-craft-client-pro-from-any-non-public-domain


Tag case sensitivity At the moment use of Tags seems to be case insensitive.
So, for example, it is possible to tag an article as both 'IT Support' and 'it support'.

Is it at all possible to make the Tags case sensitive?

One option is to use the onBeforeSaveTag event to capture the tag before it is saved. You can then use PHP's strtolower to normalize all of your tags.

In a plugin's main file, your init() function should have something like this:

public function init()
{
    craft()->on('tags.onBeforeSaveTag', function(Event $event) {
        $event->params['tag']->title = strtolower($event->params['tag']->title);
    });

}


Changing an entries data in onBeforeSaveEntry event depending on data set in saved entry Ok I'm buliding a plugin which changes the category of a news article if another article is set to the same category so that only one article is set as the featured category.

So far I have the onSaveBeforeEntry event working ok I'm just stuck on the updating the existing featured article. This is the flow so far followed by the code I'm having an issue with.

First check the article being saved to see if the category is set.
If it is check it has not changed.
If it has changed and it has changed to 'Featured' use getCriteria to find the entry that is currently set to 'Featured'
(the sticking point) set the existing featured entry category to 'Latest' and save it.
Finish off saving the entry.

Point 4 is not changing the existing featured article data.

The code I have is:

// Get the current featured news entry
$entry_criteria = craft()->elements->getCriteria(ElementType::Entry);
$entry_criteria->section = 'news';
$entry_criteria->search = 'category:Featured';
$featuredEntry = $entry_criteria->first();

// update exiting featured article and mark as latest
$featuredEntry->setContentFromPost(array('category' => 'Latest'));
$success = craft()->entries->saveEntry($featuredEntry);

Getting the existing entry works, changing the category and re-saving does not.

What am I missing?

Any help appreciated.

Ta

You need to set an array of category IDs to your categories field.

$featuredEntry->setContentFromPost(array(
    'category' => array(42)
));

Query for it with an craft.categories criteria model or if you're hardcoding it anyways you could just look it up in the CP:

  example.com/admin/categories/myCategoryGroup/42-myCategoryHandle


Is there a Zendesk plugin to fetch order information from Craft Commerce? I'm looking for the same functionality as https://wordpress.org/plugins/mwb-zendesk-woo-order-sync/ but for craftCMS's Commerce plugin and not Wordpress's Woocommerce plugin.
Basically, it would use the reporter's email from the zendesk ticket to get the order or orders from Craft Commerce and display the order information in a zendesk widget.
I've looked, and all I can find are plugins for creating tickets.
Does anyone know of an existing plugin for zendesk that does this?

As of today (08/06/2020) there isn't a plugin that does that in the Plugin Store, so you'd need to do some custom plugin development if that's what you're looking for.


Force Download a file using an Ajax request or Task The following code doesn't seem to work when called using an Ajax or Task but it does work otherwise:

craft()->request->sendFile($file, IOHelper::getFileContents($file), array('forceDownload' => true));

I was wondering, Is it not possible to force download a file using an Ajax or Task?

Any help much appreciated!

Many thanks

I don't think you'll be able to use Craft's HttpRequestService->sendFile() for this.  But there are plenty of non-Craft ways of doing this, depending on your specific requirements.


What is the optimal place to store CSS files? I'm trying to figure out the best place to keep my one master CSS file in craft.

I had the CSS linked in my template as

link rel="stylesheet" href="../craft/css/master.css">

But now Blog entries can't get to it, as they are looking in www.domain.com/index.php/blog/craft/css/master.css now.

Is there a better place to put the CSS, or a better way to link to it in templates?

In most cases, the best place to store CSS is in a publicly accessible directly, not managed by Craft at all. Such as:

public/assets/css/master.css

Storing your CSS and other front-end assets outside of Craft reduces the overhead of accessing those files. While Craft allows you to store css files in your Craft templates folder, there is additional overhead to access those files as they need to be processed by Craft.


Redirect to template from controller and pass data I am building a custom login process which follow these steps:

Request user email (submits to custom controller)
Check if user has an account
If they have an account, show a form requesting their password. Or if they don't have an account then send them to the registration form.

The forms exist as front end templates.

I can accomplish all these steps but when the user is redirected I need to make the email address that they entered available to the template.

My custom controller calls a service to check if the user exists which is all fine.
And I can redirect the user to the appropriate URL. But I can't figure out how to retain the email address they entered.

Currently I've just done it by appending the email as a query string but this is undesirable for a couple of reasons.

The controller currently looks like this although I feel this is totally the wrong way to be doing things.

public function actionEmailCheck() {
        $this->requirePostRequest();

        $email = Craft::$app->request->post('loginName');

        $result = MyModule::$instance->order->checkEmail($email);

        if($result) {
            $redirect = '/login/password?email='.$email;
        } else {
            $redirect = '/register?email='.$email;
        }

        $this->redirect($redirect);
    }

I feel like I should be able to set some template variables and load the appropriate template but that doesn't seem to work.

I also tried this

if($result) {
            $this->renderTemplate('/login/password', array('email'=>$email));
        } else {
            $this->renderTemplate('/register', array('email'=>$email));
        }

But while the template was displayed, I couldn't access the value for 'email'.

So how should I approach this?

You could do this by saving the email address to a custom session variable like this in your controller:

Craft::$app->getSession()->set('email', $email);

This should then be available in your template using:

{{ set email = craft.app.session.get('email') }}