How to set simple yes/no checkbox using Freeform Using Freeform, I am wanting to have a checkbox on a front end form that is not checked by default that posts 'Yes' if checked and 'No' if not checked. I am creating a manual HTML form that works fine for all the other fields, but I can't figure out what to write for the checkbox logic.

From the docs I know I can set the value in the back end to a default of either 'Yes' or 'No', I have done this and using the following template code but it always sends through the same value of either Yes or No depending on what you set in the back end.

<input type="checkbox"
        name="{{ receiveContactFromTFA.handle }}"
        value="{{ receiveContactFromTFA.value == 'Yes' ? 'Yes' : 'No' }}"
        {% if receiveContactFromTFA.value == 'Yes' %} checked{% endif %}>

I have also just tried not having a value attribute at all but again the value defaults to yes because it is set in the back end. I have also tried removing the value entirely and having the following template code:

<input type="checkbox"
        name="{{ receiveContactFromTFA.handle }}">

If I do that then then nothing posts. I know a checkbox will normally post a '1' if checked but how do you handle this logic using Freeform to be either 'Yes' or 'No'?

I don't think this has anything to do with your code, and actually appears to be a bug in Freeform itself, where the Submission object and email notifications are showing the value as whatever the default is set to.

I've made a note about this issue and we'll have it corrected shortly. :)


Plugin: Tags field for front-end Entry Form I would like to add tags via a front-end entry form - not like here, but as follows:

Text field in a front-end entry form where user add tags (separated by commas).
After pressing the save button, the plugin should:
check for every tag, whether it exists already (and create the tag if not)
save the tags together with the rest of the entry form [see also here](including the text field with the user defined tags)

Now, I am looking for a developer (I am willing to pay for it).

While the full answer to this probably requires some planning, and a plugin that handles various aspects of the tag management, here are a few components to consider:

You can submit tags from the front-end and, on the server side, they will behave like Craft handles them in the Control Panel. The syntax for your front-end form field is as follows:

<select multiple name="fields[fieldHandle][]">
  <option value="13">Tag Name One</option>
  <option value="42">Tag Name Two</option>
  <option value="144">Tag Name Three</option>
</select>

For a more friendly UI, there are a handful of javascript libraries that could help on the front-end. I believe the one that Craft uses in the Control Panel is selectize.js and it could be setup to be used on the front-end as well.

To handle the pre-processing of tag behavior before an Entry is saved, your plugin may need to use the entries.onBeforeSaveEntry Event.


Guest Entries - Saving entries as drafts We're using Guest Entries for comments. When the user posts an entry it automatically appears as a published entry. I'd like to change this functionality so that the entry will enter as a draft until approved.

I've set the user's permissions to "edit entry" but that doesn't seem to do the trick.

Any help would be appreciated.

Edited based on comment below

No sorry I see what you mean now. But I think with entry drafts you need to have first published an entry, then you create a draft from that entry, essentially creating two versions of the same one.

I think for approving entries as comments this is going to lead to a lot of complexity and you might struggle to get the results you want, and to do this the way you want would probably require writing your own plugin...

This plugin would listen to when an entry is saved, get that new entry id, create a new EntryDraftModel and then save it via craft()->entryRevisions->saveDraft() method. You would then need to set your new entry to disabled anyway (to stop it from showing) as creating a draft won't affect the newly created entry.

Then to approve an entry you would go into the newly created entry, switch to the draft (which would most likely be the same) and then apply it and enable the entry.

This is a complex process when your entire workflow could be condensed to:

Create a new entry as disabled
Enable an entry to approve it

Setting all new entries to disabled and then setting ones to active you want to approve will make your life easier and keep your build streamlined.

I don't think there is extensive info about drafts in particular but it might be worth checking the docs but essentially they are intended for entry revisions, not so much approving whole entries.

So...you can set entries to be disabled when they are submitted from within the guest entries plugin itself:

Just make sure the light switch is off for the correct section and entries wont be published. Then you will be able to set them to enabled as part of your approval process.

Doing this with a standard entry form

If you wanted to do this using crafts native entry form (with a logged in user), you would need to set the status at a template level

// entry form ...
<input type="hidden" name="enabled" value="0">

But a quick test revealed this didn't have any effect when using the guest entries plugin.


Create default password for new user registration in CP I have a situation where I want to assign a default password when a user is registered in the CP, but only if they are assigned to a specific user group. Plugin code looks like this:

craft()->on('users.onActivateUser', function(Event $event)
{
    $user = $event->params['user'];

    // Test to see if a user is in group
    if ($user->isInGroup('groupName'))
    {
        $user->newPassword = 'Password123';
        craft()->users->saveUser($user);
    }
});

I've tried latching on to both the users.onSaveUser and users.onActivateUser events, and in both situations, there are no groups are assigned to the user. Is there an event that is at the absolute end of user registration that I can watch to access their user groups?

If you have "Verify Email Addresses" checked in Settings->Users->Settings and you uncheck "Send activation email now?" users will start in a "pending" state, so the onActivateUser event won't get fired.

If you uncheck "Verify Email Addresses" in Settings->Users->Settings, the "Send activation email now?" checkbox will disappear when registering a new user, users will start in an "active" state and the onActivateUser event will fire.

As you've found, user group information isn't available to the user on the same request they get created in because user group permissions don't get processed until after the onSaveUser event has fired.  You could use onSaveUser, but you'd run into the same limitation.

What you can do, however, is directly check against $_POST (craft()->request->getPost()) to see if the user group you're interested in is there in the onActivateUser event.


How do I force www in URL along with the Patrol plugin to force https I'm using the Patrol plugin to force https in the domain, but I also need to force www into the URL. When I do that with some htaccess rewrite rules I found online I get an error when I try to load the site that there's too many redirects happening.

This is my htaccess code

<IfModule mod_rewrite.c>
RewriteEngine On

RewriteRule ^(.*)/$ /$1 [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]

And this was the code to force WWW that I was trying unsuccessfully to use that resulted in the "too many redirects" error.

<IfModule mod_rewrite.c>
RewriteEngine On
#force www in URL
RewriteCond %{HTTPS_HOST} !^www\.adacore\.com
RewriteRule (.*) https://www.adacore.com/$1 [R=301,L]

RewriteRule ^(.*)/$ /$1 [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]

I'm not sure how or if the Patrol plugin (https://github.com/selvinortiz/craft.patrol) factors into the htaccess file to be honest. Any idea what I'm doing wrong?

This is how our default .htaccess with https redirect and forced www. for all our projects looks like. So if you have the url example.com you'll get redirected to https://www.example.com.

<IfModule mod_rewrite.c>
    RewriteEngine On
    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]
    RewriteCond %{HTTP_HOST} !^www\. [NC]
    RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
    RewriteCond %{HTTPS} !=on
    RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]
</IfModule>
Action application/x-httpd-php70 /cgi-sys/php70-fcgi-starter.fcgi
AddType application/x-httpd-php70 .php .php70


Can I output custom or specific data (Not related to an elementType) on Element API? For example, an endpoint to retrieve all the languages available on the website

'endpoints' => [
   'languages' => function () {

            $sites = Craft::$app->getSites()->getAllGroups();

            $languages = Craft::$app->getSites()->getSitesByGroupId($sites[array_search('Languages', $sites)]['id']);

            Craft::dd($languages); // output this in a nice json

            return $languages;
        },
    ]

Or an endpoint to retrieve all the available sections

    'sections' => function () {

            $sections = Craft::$app->getSections()->getAllSections();

            Craft::dd($sections); // output this in a nice json
    },

Indeed as @robin pointed out, I couldn't figure out a nice way to making custom data outputs with Element API (Not related to a ElementType, like available Sites/Languages or available sections). What I did was:

I created a custom module, in this module I was able to register routes like:

        Event::on(
            UrlManager::class,
            UrlManager::EVENT_REGISTER_SITE_URL_RULES,
            function (RegisterUrlRulesEvent $event) {

                $event->rules['api/languages'] = '/endpoints/endpoints/languages';
            }
        );

And in the action of the module. (Still is a rough version, also needs to handle possible errors and that kind of stuff)

public function actionLanguages()
{
    $sites = Craft::$app->getSites()->getAllGroups();

    $languages = Craft::$app->getSites()->getSitesByGroupId($sites[array_search('Languages', $sites)]['id']);

    return $this->asJson($this->formatApiResponse($languages));
}

I don't know if it's the nicest way (Still open to suggestions) but this gave me the freedom I needed to enhance my Element API end-points.


How Do I group entries by Category and retain fixed Category Order? I found a solution to grouping entries by category here which is working perfectly but I need the categories in the order they were arranged in the categories tab in the Admin panel.

Currently, the categories are outputting in the order they were entered but they've been re-ordered since then.

I tried using .fixedOrder(true) in a few places but nothing good happened. This is the current code:

{% set entries = craft.entries({
  section: 'projects'
}).find() %}

{% for category, catEntries in entries|group('projectCategory.first().title') %}

{{ category }}

        {% for entry in catEntries %}

{{ entry.title }}

        {% endfor %} {# -- // for entry -- #}

{% endfor %}{# -- // for category -- #}

Depending on your needs, you may be able to ditch the group() filter and sort your list however you need.

Get all your entries and categories. Then use the relatedTo functions to filter those lists.

{% set categories = craft.categories.group('projectCategories') %}
{% set projects = craft.entries.section('projects').order('title').limit(null) %}

{% for category in categories.relatedTo(projects) %}

{{ category.title }}

    {% for entry in projects.relatedTo(category) %}

{{ entry.title }}

    {% endfor %}

{% endfor %}

One caveat might be that this solution pulls all your entries and categories. This worked for my situation where I had around 50 categories and under 200 entries. I also knew these numbers wouldn't get bigger in the future.

This also makes a few other assumptions too...

You DON'T need to show entries with NO related categories like this:

Category A

entry
entry

Category B

entry

(No Categories)

entry

Also, your entries can show up under EACH category they're related to, instead of just the FIRST category like your original code. For example, if Entry 1 has Category A and Category B selected, you'll get this:

Category A

entry 1

Category B

entry 1


Help developing point system for sports league (w/o plugins) I'm in the middle of a very long project developing a league site for the National Collegiate Wrestling Association in my spare time (once finished, could be a great showcase for Craft).

Currently, I'm trying to implement a points system, where athletes accumulate points based on the matches they win & how they win them.

Here's a screenshot of an athletes stat page (wip) http://cl.ly/image/3L2A0e2x1q3v

All the results are tied to an event, so the points can be recalculated easily if an event has to be removed for whatever reason, or a coach inputs the wrong kid by accident.

There is quite a bit of logic being done here, but manageable, and can be cached- but teams also accumulate points based on the points of the top 11 athletes in their roster!

This means the points will have to be calculated and displayed on

The Team's page (11x the queries)
The Index page of all Teams

Currently, the only way I know how to do this, will be some heavy nesting of conditionals in loops- repeating the process of each athlete.

I know doing it this way, all in the templates, is extremely unorthodox. I'm 99.9% this would be much easier to implement with plugins somehow, but unfortunately I don't know PHP nor do I have the time to invest in the trial/error learning process of how to write plugins in the time needed. So I'm kinda up against a wall here and looking for solutions to smooth out this process, regardless of how hacky it may be.

Maybe there's a way to only perform these massive queries in the middle of the night, and the points total only updates once per day, no matter how many results are inputted in the 24-hour period? I don't know. Please help me, very kind Craft community :)

Update: Added requested template logic... Removed extra unnecessary code for readability & sake of space. Team pages & Teams Index page won't require all the information displayed in screenshot (date, opponent, score/time, pt diff)

{% set athlete = craft.users.id( craft.request.lastSegment ).first %}
{% set results = craft.entries.section('results').relatedTo({
    targetElement: athlete,
    field: 'matches',
}) %}
{% set points = 0 %}
{% if results|length %}

  {% for result in results %}
    {% for block in result.matches %}
      {% if (athlete.id == block.winner.first.id) or (athlete.id == block.loser.first.id) %}

          {% if block.winner|length and (athlete.id == block.winner.first.id) %}
            {% if (block.result == "Maj") or (block.result == "Dec") %}
               {% set points = (points + 5) %}
               {% set difference = "+5" %}
              {% else %}
                {% set points = (points + 6.1) %}
                {% set difference = "+6.1" %}
            {% endif %}
          {% endif %}

          {% if block.loser|length and (athlete.id == block.loser.first.id) %}
            {% if athlete.id == block.loser.first.id %}
              Lost by {{ block.result.label }}
                {% set points = points - 1.75 %}
                {% set difference = "-1.75" %}
                {% set negative %}{% endset %}
            {% endif %}
          {% endif %}

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

{% set tournaments = craft.entries.section('results').relatedTo({
  targetElement: athlete,
  }) %}
{% if tournaments|length %}
  {% for tournament in tournaments %}

    {% if tournament.type.handle == 'minorTournament' %}
      {% for w in 1..3 %}
        {% for p in 1..3 %}
          {% if (tournament['w'~w~'p'~p]|length) and (tournament['w'~w~'p'~p].first.id == athlete.id) %}

            {% switch loop.index %}
              {% case "1" %}
              {% set points = (points + 6) %}
              {% case "2" %}
              {% set points = (points + 4) %}
              {% case "3" %}
              {% set points = (points + 2) %}
            {% endswitch %}

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

Points:>{{points}}

Without wanting to go into any PHP or plugin development, your best bet is to set a 24 hour cache on your chunk of processing code. As you suggested, it is probably smart to not have the cache clear itself when an entry is saved. To accomplish this, just set cacheElementQueries to false in your general config file.


How do I output the siblings position number? This question is related to this thread.

{% for sibling in entry.getSiblings() %}
{{ sibling.title }} {{ sibling.orderNumber }}
{% endfor %}

I thought you could pick this out of the ElementCriteriaModel, but that doesn't seem to be possible/available. Twig's for loop won't work either.

The result I am looking for is to echo the order number of the siblings in a structure.

Parent
Child order number 1
Child order number 2
Child order number 3

Building upon the answer I posted to this question How to get the order number of the current entry in a structure, you should be able to get the order number in your for-loop like so:

{% set parent = entry.getParent() %}
{% set childrenIds = parent.getChildren().ids() %}

{% for sibling in entry.getSiblings() %}
    {% set orderNumber = craft.entries({
        id: siblingsIds,
        order: 'lft desc',
        positionedBefore: sibling,
    }).total() + 1 %}

    {{ sibling.title }} ({{ orderNumber }})
{% endfor %}


Craft 3 - custom callback after Garnish onDragStop I would like to trigger a custom javascript function after an element in a matrix block was moved in the matrix but I'm not sure how to attach the event without changing the MatrixInput.js.

So far I've tried the easy way with attaching element handler in my plugins init() function

Garnish.$doc.on('dragStop', '.matrixblock > .actions > .move', this.onMoveEnd.bind(this))

But of course that did not work. The Craft.MatrixInput contains a the function

this.blockSort = new Garnish.DragSort($blocks, {
    handle: '> .actions > .move',
    axis: 'y',
    filter: $.proxy(function() {
        // Only return all the selected items if the target item is selected
        if (this.blockSort.$targetItem.hasClass('sel')) {
            return this.blockSelect.getSelectedItems();
        }
        else {
            return this.blockSort.$targetItem;
        }
    }, this),
    collapseDraggees: true,
    magnetStrength: 4,
    helperLagBase: 1.5,
    helperOpacity: 0.9,
    onSortChange: $.proxy(function() {
        this.blockSelect.resetItemOrder();
    }, this)
});

Can anyone please tell me how to extend this without breaking Craft updates?

Accessing this event with Craft.MatrixInput.blockSort to attach something does not work either and I'm not sure how I can make use of the this.trigger('dragStop'); event.

I've tried to dig into Garnish events to attach the handlers, but I'm not sure how. Garnish.on does not work, Garnish.Drag.on either, Garnish.Base returns a function but Garnish.Base() returns undefined.

Garnish’s Base class introduces its own concept of events, that is separate from DOM events.

Here’s how you’d set up the listener:

// get the Craft.MatrixInput object
var matrix = $('.matrix-field').data('matrix');

// attach a handler to its block sorter's sortChange event
matrix.blockSort.on('sortChange', function() {
    // event handler...
});


How to create a template file for Categories? below is my categories url.

http://example.com/index.php?p=categories/vaporizers

i create a template files for categories like

templates/categories/index.html
templates/categories/_entry.html

my index.html is not called when categories view. please tell me where i create a mistake.

Thanks

When you create a category you will need to tell craft which template to load:

So for your example you would put categories/index in there and you should find the template gets loaded when you visit the category url.

See more about templating in the docs


How can I add a favicon to the admin part of Craft? I've successfully added a favicon to the site template through the _layout.html template. So the question is, how do I add the favicon code to the admin/backend of the website?

Thank you.

If you go to Craft Settings > General you can add a site icon in there plus a logo for the login page.


Sprout Forms - An unknown error occurred when trying to view entries in CP I've installed Sprout Forms and created a contact form. I'm using displayForm to display the contact form.

The front end appears it's working as it should. Validation works and the success message works when submitting.

The issues are I'm not receiving any email notifications (I have defined my email under Notifications > Email Recipients) and I am unable to view entries under the Sprout Forms control panel. When I click on the Sprout Forms tab, I get an orange prompt that flashes "An unknown error occurred" then disappears.

An odd but promising clue is in the admin, when I click on Sprout Forms then Forms, my contact form is showing the total entries that I've been submitting.

I have tested that PHP Mail works. Does anyone have any clue as to what could be causing this?

You're experiencing two different things.

First, as Johannes suggested, if you update to the latest version of the plugin (using the same url that you were sent for the private beta), the error in the control panel will be fixed.  This issue was introduced in Craft 2.3 and was resolved in Sprout Forms 0.8.3

Second, it sounds like you have some issues with Email Notifications.  Assuming you have all the Form Notification settings in place and functioning email, as it sounds like you do, we recently discovered a bug where email notifications are not sent if you are using ajax to submit your forms.  We have a fix we can send you, and it should be resolved once we have a chance to release that and a few other fixes in Sprout Forms 0.8.4

Please send us a note if you have any more questions and we'll get you the updated file if you need it before we get those updates into the next release.

Ben


Case Sensitive username Is craft's username field case sensitive when logging in?

I'm importing 80 users into the database and when emailing the users I want to be sure how this works so we don't hit issues when they all try to log in.

Many thanks

I've tested this locally on Craft3 and Craft2 and it seems that the username field is not case sensitive (e.g. admin, ADMIN, and AdMiN all worked equally as well for me).


CloudFlare Shared SSL certificate forbids CraftCMS control panel sign in I am running a site using CraftCMS and have a shared CloudFlare SSL certificate in place. Based on my understanding, the content source (i.e. my website) is not safe, while the content delivered to the user by CloudFlare is secure. While accessing the website works perfectly fine, logging in to the Control Panel is a major issue.

Now I am assuming that I will need an SSL certificate available on my server to secure the content source and thereby be able to log into the control panel using the https domain as opposed to the IP address or the http alternative.

Am I getting this correct or is there some way to log into the control panel using a shared CloudFlare SSL certificate?

Here is the console message I am referring to:

Mixed Content: The page at 'https://www.mysite.com/admin/login' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://www.mysite.com/index.php/admin/actions/users/login'. This request has been blocked; the content must be served over HTTPS.

I'd give Patrol plugin a try, just activate secure connections.


Edit order from backend Is it possible to add products and discounts to an order from backend?
From what I see it's only possible to edit the orders custom fields.

Currently no, however the ability to edit completed order details is on the list for 1.1.


How do I display the Category Title? I need to be able to display the Category Title of a single category (as a h1 tag for a page displaying a list of the entries for that category).  I can successfully display the relevant entries for the category on the page, but when I have tried to display the category title it displays all of the categories titles (in a loop), not just the single category title.

My code:

{% if craft.request.getParam('category') is not null %}

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

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

        {% else %}
               {% set products = craft.entries.section('products').find() %}
        {% endif %}

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

{{ category.title }}

     {% endfor %}

Any help would be very much appreciated!
Many thanks!

It depends how you're fetching the category. But if you've defined the template when setting up the categories it would be called be within a var called 'category', which would be a category object. You should then be able to access it using:

{{ category.title }}

If, on the other hand, you were getting the category via a slug in the URL, you would do something like:

{% set category = craft.categories.group('productType').slug(craft.request.lastSegment).first %}
{{ category.title }}

UPDATE: Following on from your updated question, you've already got the category as an object so there is no need to get it again. Try replacing:

// THIS IS YOUR LOOP, BTW
{% for category in craft.categories.group('productType').find() %}

{{ category.title }}

{% endfor %}

with:

{{ category.title }}

But you might need to add a conditional in case the page is loaded without a category. Something like:

{% if category | length %}
    {{ category.title }}
{% endif %}


Conditionally apply a tax zone in commerce Many of the customers we'll be selling to are tax-exempt entities. We're located in OH, so for OH customers we're applying sales tax through the Tax Zone setup in Commerce. Is there a way to not apply the tax based on some conditional, even though their billing address is in OH?

OK So I figured this one out eventually. It's a very hacky fix. I added an adjuster that is basically an exact copy of the built-in Tax Adjuster (found at plugins/commerce/Commerce/Adjusters/Commerce_TaxAdjuster.php). The only difference is that I added a condition to check for my Tax Exempt field (and that we're in the OH tax zone), and then removed the tax amount instead of added it.

ie, I changed things like

$allRemovedTax += $amount;
$item->tax += $amount;

to

$allRemovedTax -= $amount;
$item->tax -= $amount;

And then added the whole thing to a new custom plugin.

What this results in is tax being applied normally, and then the same tax being removed.

If anybody comes across this and has a better solution, I'd love to hear it. But this works for now.


Order entries, exclude 'the' from order criteria I know this is partly a Twig question, but I've poked around quite a bit here, in Twig docs, Craft docs, and cannot find the right syntax.

I have a bunch of entries with titles like:

Hotel A
Grand Hotel B
Zither Hotel Grand Plaza
The Top Hotel

I want to order by title, alphabetical, but I need to exclude leading 'The ' from the order. I've tried this, but it barfs.

 {% for entry in craft.entries.section('hotels').order('(CASE when title LIKE
'%The ' THEN LTRIM(title, 4) ELSE title END )') %}

Completely untested, but try something like this:

{% for entry in craft.entries.section('hotels').order('(CASE WHEN title LIKE 'The %' THEN SUBSTRING(title, 4) ELSE title END )') %}

MySQL's LTRIM isn't what you want because that just removes leading spaces.  SUBSTRING should do it, though.

Also, keep in mind this is a MySQL specific query.  If you ever planning on running on PostgreSQL (that the Craft 3 beta supports), it would have to be adjusted.


Is there a better way to make tables in Craft? I'm using the table function built into Redactor, and all my tables are coming out with the minimum width possible, without any padding between columns. How do I modify how Redactor builds its tables?

I'd use a Table or SuperTable field

But if you want to stick to a Redactor Rich Text field, put a wrapper <div> around the {{ entry.redactorField }} Twig markup, and use CSS to style the table ala .myRedactorWrapper th etc.


Poor performance on midsized site / Queries without index? I'm running a mid sized website (couple hundred articles, between 30-50k visits per day) on a Digital Ocean 16GB / 8 Cores web server and I have two questions:

Most of the time the website runs smoothly, however, several times per day MySQL starts using all of the CPU and I see a spike on disk IO.

Running show process list on MySQL shows that most queries are "Copying to tmp table"  and look like this

I'm new using Craft and I want to know is this queries are normal and if there's a way to optimize them:

    EXPLAIN SELECT `elements`.`id`, `elements`.`type`, `elements`.`enabled`, `elements`.`archived`, `elements`.`dateCreated`, `elements`.`dateUpdated`, `elements_i18n`.`slug`, `elements_i18n`.`uri`, `elements_i18n`.`enabled` AS `localeEnabled`, `content`.`id` AS `contentId`, `content`.`title`, `content`.`field_airingDate`, `content`.`field_airingFrom`, `content`.`field_airingTo`, `content`.`field_awsPath`, `content`.`field_descripcion`, `content`.`field_descripcionSocialMedia`, `content`.`field_subtitulo`, `content`.`field_texto`, `content`.`field_titulo`, `entries`.`sectionId`, `entries`.`typeId`, `entries`.`authorId`, `entries`.`postDate`, `entries`.`expiryDate`, `structureelements`.`root`, `structureelements`.`lft`, `structureelements`.`rgt`, `structureelements`.`level`
    FROM `elements` `elements`
    JOIN `elements_i18n` `elements_i18n` ON elements_i18n.elementId =         elements.id
    JOIN `content` `content` ON content.elementId = elements.id
    JOIN `entries` `entries` ON entries.id = elements.id
    JOIN `sections` `sections` ON sections.id = entries.sectionId
    LEFT JOIN `structures` `structures` ON structures.id = sections.structureId
    LEFT JOIN `structureelements` `structureelements` ON (structureelements.structureId = structures.id) AND (structureelements.elementId = entries.id)
    WHERE (((((elements_i18n.locale = 'es') AND (content.locale = 'es')) AND (elements.archived = 0)) AND ((elements.enabled = 1) AND (elements_i18n.enabled = 1) AND (entries.postDate <= '2017-04-11 16:56:24') AND ((entries.expiryDate is null) OR (entries.expiryDate > '2017-04-11 16:56:24')))) AND (elements_i18n.enabled = 1)) AND (sections.handle='articulos')
    GROUP BY `elements`.`id`

Another example:

    SELECT count(`derivedElementsTable`.`elementsId`)
    FROM (SELECT `elements`.`id` AS `elementsId`, `entries`.`sectionId`, `entries`.`typeId`, `entries`.`authorId`, `entries`.`postDate`, `entries`.`expiryDate`
    FROM `elements` `elements`
    JOIN `elements_i18n` `elements_i18n` ON elements_i18n.elementId = elements.id
    JOIN `content` `content` ON content.elementId = elements.id
    LEFT JOIN `relations` `sources1` ON (sources1.targetId = elements.id)
    LEFT JOIN `relations` `targets1` ON (targets1.sourceId = elements.id)
    JOIN `entries` `entries` ON entries.id = elements.id
    JOIN `sections` `sections` ON sections.id = entries.sectionId
    LEFT JOIN `structures` `structures` ON structures.id = sections.structureId
    LEFT JOIN `structureelements` `structureelements` ON (structureelements.structureId = structures.id) AND (structureelements.elementId = entries.id)
    WHERE (((((elements_i18n.locale = 'es') AND (content.locale = 'es')) AND (elements.archived = 0)) AND ((elements.enabled = 1) AND (elements_i18n.enabled = 1) AND (entries.postDate <= '2017-04-11 16:56:33') AND ((entries.expiryDate is null) OR (entries.expiryDate > '2017-04-11 16:56:33')))) AND (elements_i18n.enabled = 1)) AND ((sources1.sourceId='175') OR (targets1.targetId='175'))

I understand that the i18n tables are where the locales data is stored. Is there a way to disable a locale without losing any data?

I can tell you that both of those are the semi-dynamic element queries that Craft uses to grab elements from the database.

The 2nd one is likely the result of someone calling a .total() or .count() on ElementCriteriaModel.

I see you ran EXPLAIN, but don't see the results from it.  You can use that as a starting point to see what index MySQL chose to execute that query and if it's not ideal.  Craft can't add an index to every content column (for obvious reasons), so if something in your templates is generating a SQL query frequently that causes MySQL to chose an index that isn't ideal and adding an index to content column would solve that for you, then that's something you can certainly do.

  I understand that the i18n tables are where the locales data is stored. Is there a way to disable a locale without losing any data?

No. It either exists or it doesn't.


Craft Controller gives 404 error So I am working on it first time. I created a Controller DB_DuhController having a method actionFoo()

I am then calling it as http://domain.craft.dev/admin/DB/duh/Foo but it's giving 404 all the time. What is wrong being done by me?

You need to use /actions (or whatever your Trigger word is) to access Controller actions.

Documentation: http://buildwithcraft.com/docs/config-settings#actionTrigger

EDIT: I realize I wasn't clear enough; this variable defaults to /actions. Unless you've set it to something else in your Config, add the /actions to your URL to access the Controller action.

So, your URL would be this: http://domain.craft.dev/actions/PluginHandle/Duh/foo

Note that capitalization matters.

It's also important to make sure that if you plan on making calls to this URL from outside Craft, you'll need to make sure that you're allowing anonymous access by setting that variable at the top of your controller:

protected $allowAnonymous = true;


Can I set color fields by hex value Can I set the value of a Color Field to a hex value? Or only if the particular browser's color picker supports this? Maybe this is a feature request: please let us get and set color values in hex.

If you have created a Color Field the color selector dialogue uses your browsers built-in color selector.

On Chrome and Firefox, you should see a dialogue like this:

|   |  |

If you click over to the 2nd tab (indicated by the sliders) you'll be able to insert a hex value for the color in the input field at the bottom.

In Firefox you'll need to select RGB Sliders from the dropdown, then you'll see the Hex color input at the bottom.


Output Checkbox Data on Template If you have a checkbox  field on an entry type, how do you display all the selected values for an entry in a template with twig?

Using this for page permissions via user groups. We have a plugin that adds a new field type "user groups". It lists all groups (which we have many) on the admin page of each entry. We want to check which groups will have access and then limit the page to users in that group only.

edit: not using a standard checkbox field but a new field (via plugin). https://github.com/quebecstudio/usergroupfield

You get all available options with the options attribute and you can check if it is selected in the current entry with option.selected

{% for opt in entry.checkboxFieldHandle.options %}
    <label>
        <input name="fields[checkboxFieldHandle][]" type="checkbox" value="{{ opt.value }}">
        {{ opt.label }}
        {% if opt.selected %}
            I'm selected
        {% endif %}
    </label>
{% endfor %}

But to be honest I don't really understand your second part

Edit
As for your field, you can display all the selected values with

{% set selectedUserGroupIds = entry.userGroupFieldHandle %}
{% for userGroupId in selectedUserGroupIds %}
    {% set usergroup = craft.userGroups.getGroupById(userGroupId) %}
    {{ usergroup.name }}
{% endfor %}


Prevent foreign characters in filenames? It seems that some of our users are uploading filenames with foreign characters...

Is there any way to prevent this?

I'd like to keep the filenames to all English letters (plus numbers, dash & underscore).

(If relevant, this is for Craft 2.)

Cant you just use preg_replace("/[^A-Za-z0-9 ]/", '', $stuff) for this? Seems that will strip away anything that isnt a number or a letter from the english alphabet?

EDIT ---------
Challenge accepted ;)

public function modifyAssetFilename($filename){
    return preg_replace("/[^A-Za-z0-9-]/", '', $filename);
}

Something according to the above strips out all unwanted characters using the hook if you place it in a plugins main class file. The above preg_replace should also keep dashes e.t.c.

Another way you might be able to approach the sanitation of filenames is listening to the onBeforeSaveAsset method and then using craft()->assets->renameFile() once you have sanitized it. Not sure which one is better. Both should work.


I have a table type field that I need to access to rows individually I'm new using Craft, I have a table type field display on one of my template but I need to display row 2 and 7 in different places of the page how can display only those two rows.

{{ entry.myTableField[1] }} and {{ entry.myTableField[6] }}

You also might want to check to make sure they exist.

{% if entry.myTableField[1] is defined and entry.myTableField[1] is not empty %}
     {{entry.myTableField[1]}}
{% endif %}


Element API: How to get entries up to a certain page? I have a query that is pulling entries from a structure with
elementsPerPage' => 3

If my pagination looks like this:

Page 1:
Entries: A, B, C

Page 2:
Entries: D, E, F

Page 3:
Entries: G, H, I

How should I write the query to get all entries up to page 2?

Request Page 2 Results:

Entries: A, B, C, D, E, F

Request Page 3 Results:

Entries: A, B, C, D, E, F, G, H, I

This tweet shows a way to adjust the elements per page dynamically with a query string param -> https://twitter.com/JakeDohm/status/1157305040278839296?s=20 so you could just request 6 or 9 items to get the same result.


How do I loop through entries for a specific entry type? I would like to loop through entries in a channel but only the ones for a specific entry type. Is this Possible?

I'm using the free version of craft on a test site, I have used the channel for my pages but also want to set up a blog. I have set up a blogPost entry type, is there a way to target this in a loop?

{% set entries = craft.entries.section('pages').type('blogPost') %}

{% for entry in entries %}
   {{ entry.title }}
{% endfor %}

Is what I have cobbled together... any pointers on improvements would be welcome.


Plugin Error: "Unable to find component class" I'm suddenly getting an error on my plugin fieldtype even though I didn't make any changes to it. On Craft's publish page where my field is supposed to be I get the error:

Unable to find component class 'kgrote\siteutilities\fields\Regionselect'.

Really have no idea where to start looking here. The Regionselect class exists in the fieldtype file and the name of the file matches the class. It might help if I knew where this error was originating from.

Additionally, the plugin shows as "Disabled" in the Settings area and I can't enable it, and there is no "Uninstall" option available in the dropdown.

So what happened was I un-gitignored my Composer files so I could deploy them to another environment. Then I switched from that branch to a different branch with different Composer files. After I switched back, I ran into a Composer bug (mentioned here in the docs) where Composer will forget about plugins loaded using the path method if the files change.

So I had to perform these steps:

navigate to my craft project folder in the terminal
execute composer remove kgrote/siteutilities
delete the kgrote directory from craft/vendor
execute composer install kgrote/siteutilities

SUUUUUPER annoying, but there you have it.


How can I get a specific product via plugin? I am able to inspect my cart using commerce_orders.onOrderComplete.

Next I loop through each line item & check for a specific product type. I need to be able to get the specific product, as there are attributes (values) within that product that I am saving to my plugin's records.

For example, if a user purchases "My Product", "My Product" has attributes that include things like "Follow-Up Meetings Qty" Where the admin is allowed to choose the number of meetings are included with "My Product".

Here is what I have that is close, I am stumbling getting the correct criteria model back. I know I'm not working with an entry, so I need to use the purchasable element type.

craft()->on('commerce_orders.onOrderComplete', function (Event $event) {
    user = $event->params['order']->getCustomer()->getUser();
    $orderNumber = $event->params['order']->number;

    foreach ($event->params['order']->lineItems as $item) {
        if ($item->snapshot['product']['typeId'] == 123) {
             $productId = $item->snapshot['id'];

            // Get order details.
            switch ($productId) {
                case 456:
                    error_log('---- My Product Was Purchased ----');
                    error_log('user id: ' . $user->id);
                    error_log('order number: ' . $orderNumber);
                    error_log('product id: ' . $productId);

                    // Get the specific product that was purchased.
                    $criteria = craft()->commerce_purchasables->getCriteria(ElementType::Purchasable);
                    $criteria->limit = 1;

                    ...

                    $products = $criteria->find();

                    if ($products) {
                        foreach ($products as $product) {
                          // Access the products' attributes
                          // $product->meetings_qty  (3)
                          // $product->foo_qty  (2)
                          // $product->bar_qty

                          ...

                          // Save the values to my plugin record.
                        }
                    } else {
                        error_log('no products found that match criteria!');
                    }

                break;
                ...
            }
        }
    }
});

Thank you for any suggestions!

EDIT

Thank you Brad!

Here is what the solution looks like after I removed the over-complication "stuff". Hope this helps anyone who comes across this thread.

craft()->on('commerce_orders.onOrderComplete', function (Event $event) {
        $user = $event->params['order']->getCustomer()->getUser();
        $orderNumber = $event->params['order']->number;

        foreach ($event->params['order']->lineItems as $item) {
            error_log('User id: ' . $user->id);
            error_log('Order number: ' . $orderNumber);
            error_log('Product title: ' . $item->purchasable->title);
            error_log('Product id: ' . $item->purchasable->id);
            error_log('Meetings qty: ' . $item->purchasable->product->myFieldHandle);

            ...
            do some other stuff...
            ...
            Save the record.
        }
});

I think you have direct access to the purchasable already via a simple

$lineItem->purchasable

E.g. I do things like this

foreach ($event->params['order']->lineItems as $item) {
    BusinessLogicPlugin::log($item->purchasable->title);
}

You should really just be able to access the fields directly on the purchasable via

$lineItem->purchasable->field

So I don't  think you need to use the snapshot side of things at all as long as you're doing this at this stage anyway - the snapshot is something you use if you're dealing with an order when the product data may have since changed etc. as I understand it.


Craft Commerce with WordPress I have a content site and I want to launch a department store, but I have over 5000 products.

I want to launch a department store with Craft CMS; of course, my blog's section is WordPress.

Is this possible?

Yes it's possible.

You're kind of making more work for yourself by keeping the blog on one platform and the store on another but there is no reason you can't do it that way.

You will need to run the blog and the store on separate domains i.e. www.yoursite.com and shop.yoursite.com or else move the blog over to Craft (or run your store on Wordpress).

There will be extra challenges involved if you want to share data between the 2 sites - because they will effectively be 2 separate websites. But again, totally possible with the right planning.

Commerce will cope fine with 5000 products.


Rearrange Headings Alphabetically Is there a way (or plugin) to organise headings alphabetically? You can drag and drop to rearrange but if its a contact list for example, being alphabetised is really useful.

My headings were created alphabetically but Z-A not A-Z, I solved by modifying the dom elements and then clicking save.

var source = document.querySelector('.cs-sidebar .sources');
var divs = [...document.querySelectorAll('.cs-sidebar .sources .customize-sources-item')];
divs = divs.slice(0).reverse();
source.innerHTML = '';
for(let i = 0; i < divs.length; i++){
  source.appendChild(divs[i]);
}


File upload issues on iOS Got a client who uses his iPhone and iPad to update his site (he doesn't have a laptop!). Craft does a much better job than most as a mobile CMS, but he's running into issues with file uploads. When uploading from his Camera Roll he gets the following:

  Upload failed for image.jpg. The error message was: "Error uploading
  the file: This file type is not allowed"

I've tried too and get same response. In config.php jpeg and jpg are set in allowedFileExtensions, and maxUploadFileSize is ample if that matters. Wondering if there's some weird proprietary stuff with iOS files that's causing this? Anyone else experienced this before?

Update: This bug is fixed as of Craft 2.4.2697

  Images uploaded from iOS now get renamed to
  “image_YYYYMMDD_HHMMSS.ext” (from “image.ext”), fixing a bug where iOS
  uploads would fail after the 51st image due to Craft’s limit on
  allowed same-name uploads.

iOS uploads images from the camera roll with the name image.jpg, and if this happens multiple times then an incremental number is appended to the filename, similar to what happens with slugs. I have found that after 50 such instances though, the error message you reported starts to appear and images cannot be uploaded.

This is a bug in Craft and P&T will hopefully release a fix soon, but a temporary solution is to rename some uploaded files so that the 50 limit is not reached. Alternatively, you could make the entry slug part of the upload path to avoid reaching the limit.


403 forbidden error when moving entries in structure We're running on fortrabbit.

I cannot sort entries in a structure without getting:

403 index.php?p=admin/actions/structures/move-element

Unauthorized
User is not authorized to perform this action

This is the only user and it's a super user / admin.

You've probably got a multi-node/web server setup in Fortrabbit, but haven't setup memcache for PHP session storage. They have an article on how to do it here: https://help.fortrabbit.com/craft-3-tune#toc-cache-amp-session-on-the-professional-stack

Moving items in a Structure in Craft requires a working PHP session.


Can we use PHP in our templates instead of Twig? Is it possible to use strait PHP in our templates along side of Twig and or instead of Twig?

If so how does one go about it?

No this is not possible.

If you really need PHP, you can write a plugin with one of the following:

a Template Variable class, which can be accessed from your templates via craft.myPluginHandle
a Twig extension, which can add its own global filters, functions, or tags, etc.
a controller, which can execute PHP before calling $this->renderTemplate(...)
a template hook, which allows PHP code to access and modify the current template variable context, wherever the {% hook %} tag is placed.

Why Twig anyway?

The question to use php in templates comes up every once in a while, but there are good reasons for not using it.

For example if Craft changes its code you don't have to worry about your templates. The upcoming update of the Yii framework would force you to rewrite all your templates if they were written in php.

There is also a great article from Fabien Potencier on this topic -- tl;dr php is too verbose for templating.


Dynamically create craft.entries Basically I want to add certain parameters to my 'craft.entries' based on whether a variable is set:

{# Get a start date value from the URL (my use case) #}
{% set start_date = craft.request.getSegment(3) %} {# e.g. '2015-12-10' #}

{% if start_date != "" %}

  {# Create .after() param #}
    {% set startDateQuery = ".after(" ~ start_date ~ ")" %}

{% else %}

    {# If there is no start date then set the param as "" so nothing happens #}
    {% set startDateQuery = "" %}

{% endif %}

{% set entries = craft.entries.section('events') ~ startDateQuery %}

{% paginate entries as pageInfo, pageEntries %}
  ... Do stuff

I've tried this other ways as well, but this one seemed the most appropriate. Either way, it's not working and I was wondering if anyone might know why - or have a suggestion of a better method?

Cheers!

Instead of using the chained syntax, you should build a parameter object and pass that in to craft.entries, like so:

{# Get a start date value from the URL (my use case) #}
{% set start_date = craft.request.getSegment(3) %} {# e.g. '2015-12-10' #}

{# Create a parameter object, with default values #}
{% set params = { section: 'events' } %}

{# If start_date exists, add the after parameter to the object #}
{% if start_date != "" %}
    {% set params = params | merge({ after: start_date }) %}
{% endif %}

{# Get the entries by passing the parameters to craft.entries() #}
{% set entries = craft.entries(params) %}


How can I show 3 entries at random from within the next 10 {% for entry in craft.entries.section('entertainmentEvents').status('live','pending').search('entertainmentBanner:*').order('RAND()').limit(3) %}

This is working to show 3 random entries from the full list of all entries with the entertainmentBanner field populated. How would I limit it to the first ten entries by entry date and then 3 at random from within them?

You could use Craft's shuffle() function to randomize your postDate ordered array of entry models:

{% set entries = craft.entries({
    section: 'entertainmentEvents',
    entertainmentBanner: ':notempty:',
    status: 'live, pending',
    order: 'postDate desc',
    limit: 10
}) %}

{% set entries = shuffle(entries) %}

{% for entry in entries|slice(0, 3) %}
    ...
{% endfor %}


Prepopulate Sprout Form using an entry I'm outputting a Sprout form on my site so that users can request an update to their profile using the short code

{{ craft.sproutForms.displayForm('updateStoreDetails') }}

I would like to pre-populate the form with information from the current entry object in the template. I tried to do something like this...

{{ craft.sproutForms.displayForm('updateStoreDetails', {
    "fields": {
        "memberId": {
            "value": 12345
        },
        "name": {
            "value": "Michael"
        }
    }
}) }}

but it doesn't seem to do the trick. Is there a way of doing this?

A solution is now available in the Sprout Forms documentation: Example > Pre-populating a Field.


Show tags for each entry I have one tag for each entry.

 - Entry1
     Tag1
 - Entry2
     Tag2

Now I want to show them in the title of each entry. But it doesn't work.

{% for entry in craft.entries.section('mainEntry').limit(4) %}
{% set tag = entry.mainEntryTag.first() %}
  <h2>{{ tag }} {{ entry.title }}</h2>
{% endfor %}

This results in displaying only the globally first tag:

- Entry1
     Tag1
- Entry2
     Tag1

If I just write: {% set tag = entry.projektart %} I get the error: Object of class Craft\ElementCriteriaModel could not be converted to string

How can I get to current entry tag?

You're very close. Change "set tag" to "set tags" so you have:

{% set tags = entry.projektart %}

And then loop through the tags:

{% for tag in tags %}
    {{ tag }}
{% else %}
    No tags found
{% endfor %}

You could also simplify this and instead of setting the "tags" variable you could write the following:

{% for tag in entry.projektart %}


Craft directory 403 Access Forbidden with XAMPP I've been using xampp for a long time and have never encountered a 403 error. I have many projects in my xampp/htdocs/ folder, none of them have ever had any problems until now. I have the craft files in a /craft folder inside htdocs but any time I try to visit files within this directory I am met with the 403 error.

I have been searching a solution for hours now, I edited httpd-vhosts.conf with the following but it didn't help:

<Directory "C:/xampp/xampp/craft/">
    Options Indexes FollowSymLinks MultiViews
    AllowOverride all
    Order Deny,Allow
    Allow from all
    Require all granted
</Directory>

Again, no other folders within my htdocs directory has ever had any 403 errors. Anyone got a clue as to what is causing this and how to solve it?

That’s a good thing - you definitely don’t want to allow direct HTTP traffic to your craft/ folder, as people would be able to access your config settings, license key, and plenty of other sensitive data.

There’s a .htaccess file inside your craft/ folder with Deny from all in it, which is what is responsible for that 403 error you’re getting. Keep it in there!


Avoid saving $_POST in Craft logs for certain URLs We know that Craft logs the $_POST variable in web.log. I wonder if we have some sensitive data going through the server side (collected from a front end form), even if we don't save it in the database, it can still potentially end up in Craft's logs, isn't it? E.g. when there's an error during the form submission.

Is there any ways which we could avoid saving the $_POST variable in the log, just for certain URLs?

As Oli commented, those will only be logged if devMode is enabled, which should never be the case in production.

Outside of that, Craft does have a sensitiveKeywords propery in the Security class: https://github.com/craftcms/cms/blob/develop/src/services/Security.php#L29 that defaults to these keywords: https://github.com/craftcms/cms/blob/develop/src/services/Security.php#L29 and will redact those from places like log files.

If you need to modify that list, you can do so from by extending the application config like so:

<?php
return [
    'components' => [
        'security' => [
            'class' => craft\services\Security::class,
            'sensitiveKeywords' => [
                'key1',
                'key2',
            ],
        ],
    ],
];


Images lose quality when I upload to Craft The images I upload to Craft lose their quality :(

Without applying any transformation, the original file is blurred and has a smaller size.

I read this on another question:

  Currently the images are being cleansed on upload, which means that they are being re-saved to make sure that no malicious code is injected in them.

There is a way to get Craft uploading my pixel-perfect images without re-save them?

An example of the problem:

There is a way to get Craft uploading my pixel-perfect images without re-save them?

You can upload via FTP and then run the Update Asset Indexes tool from the Settings page in the control panel.

If you want to continue uploading from the control panel make sure that you're using Imagick instead of GD.

Craft will use Imagick if it is available to PHP by default or you can force Craft to use one or the other via the imageDriver config setting.


Override a wildcard dynamic route template I have a dynamic route for individual user /profiles. I expected it would be possible to override this route for /profiles/all but apparently not.

This can be achieved in the template I expect, with a conditional statement on the url .segment(2), but it would save a little time if it was possible to override a wildcard route.

Sort order matters, move the more specific route up and you should be good. Alternativly set it up in routes.php using some regular expressions.


fixedOrder(true) not working? I thought that a simple .fixedOrder(true) would make the files order in the same way as in the CMS. Instead of that, there is no output. Where I go wrong?

{% set files = craft.assets.kind('pdf,word,excel').fixedOrder(true) %}

                {% for file in files %}

                    {{ file }}

                {% endfor %}

fixedOrder only works with the id param. (If fixedOrder is true and id is set to a list of IDs, it will return the elements in the exact order that the IDs were listed.) It’s currently not possible to query elements in a fixed order based on any other params.

For your use case, the |group filter should work nicely:

{% set kinds = ['pdf', 'word', 'excel'] %}
{% set filesByKind = craft.assets.kind(kinds)|group('kind') %}

                {# Loop through the file kinds in the order we want #}
                {% for kind in kinds %}
                    {% for file in filesByKind[kind] %}

                            {{ file }}

                    {% endfor %}
                {% endfor %}


How to allow Asset removal in the Control Panel for an Entry I've installed Craft Personal 2.5.2763, and have set up my own simple blog.

For each Entry in the Blog Channel, I've set up an Asset Field, which is used for the header image displayed on the blog entry template.

I'd like this Asset field to be optional, as I'll be displaying a default image if one isn't defined in the Control Panel.

Adding an image to the field works great, but I'm seemingly unable to remove it once it has been assigned and saved when I go to edit the Entry and click the "Remove" icon.

When clicking the Remove icon, The image disappears from the CP edit page as you'd expect, but when clicking "Save", it seems the removal of that image is not actually being saved, as it is still there when I go back in to edit the Entry.

UPDATE: I've also found this issue on a normal Text field too. If you set the Text field to some data, save, then go back to edit, delete all text, save, then the data is not removed and the original data remains.

Am I doing something wrong, or is this a bug?

Thanks in advance for any help.

Does everything else seem to be working? Maybe try removing the field from your section and then re-add it?

You might also try clearing the caches: Settings -> Clear Caches.

Craft logs various things to craft/storage/runtime/logs/craft.log If there's an error of some kind, maybe with your database, it'll show up there.

If that doesn't clear it up, shoot P&T a message and have them take a look at your install. You can do that right from the control panel.


How can I time-profile the page load for a Craft request? I would like to see how long plugins take to load, as well as other aspects of the page (loops and database requests).

My webpage can take ~2-3 seconds to return the initial request. It seems high and I'd like to figure out how I can optimize it.

Also, as I understand it, every plugin is loaded on each request (even if it's not loaded for that page). Is this true? And if so, why is this the desired behavior? If a plugin is performing poorly it can bring the entire website to a standstill (this just happened to me: Website taking 30+ seconds to load).

If you enable devMode, then database profiling information (number of queries, SQL executed, execution time, etc.) as well as PHP script benchmarking information for the request will be output to your browser's console as well as the craft/storage/runtime/logs files.

  Also, as I understand it, every plugin is loaded on each request

Installed and enabled plugins are initialized on every request.  The only time what you are describing is a problem is if a plugin is doing some time/resource intensive operation in it's init() method, which is generally considered bad form.


Any support for MongoDB? Does anyone know, if craft gets support for MongoDB in the near future? Or is any solution out there for using MongoDB? This would be awesome. :)

Kind regards
Ron

Not in the near, probably not in the long and a pretty slim chance in the very long-term future.

We'll add support for additional relational databases (MSSQL, SQLite PostgreSQL, Oracle) long before a NoSQL solution and they will each bring their own level of additional support and challenges.


Category Sources plugin not showing headings Like the title tells you the headings, titles of the category groups, are not showing in the sidebar.

This is a screenshot from the github page of the plugin.
The "FOOD" and "DRINKS" titles are not being displayed when I use the plugin. In the source I can see:

So the plugin knows that there should be a heading but It does not fill the  element.

Any Ideas?

I just tested this on the fresh install of the latest Craft 2.6.2989 and the latest Category Sources zip and it working as expected where "Food" and "Drinks" are the Category Group names.

I'd double check you're running the latest of each.


How can I get the id of an unverified user on front-end? I would like to build a send activation email form on front-end, for users who didn't get or accidentaly delete the activation email.

I can call the users/send-activation-email action to achieve this, but this action only accept a userId as parameter, not the email address.

As I can't load unverified users from the front-end, it seems that I can't get the id of the current unverified user.

I know I could write a plugin for this, but I was wondering if there's any way to achieve this without?

Example of non-working send activation email form:

<form method="post" accept-charset="UTF-8">
    {{ csrfInput() }}
    <input type="hidden" name="action" value="users/send-activation-email">
    {{ redirectInput('') }}
    <input type="email" name="email" required>
    <input type="submit" value="Submit">
</form>

You can get the user by email

{% set user = craft.users.status(null).email("a@b.de").one() %}
{{ user.id?? 'no user found' }}


Moved Craft 3 site to new server and getting "No primary site exists" error I moved a Craft 3 site to a new server. The previous server was a plain vanilla Ubuntu 16 LTS LAMP stack. The new web server is a Bitnami Ubuntu 16 LTS with a LAP stack (no local MySQL). In the new environment I have setup the Craft 3 site to connect to the remote server via SSL. The SSL connection seems to be working fine, but I am getting the following error when I navigate to the site on the new server:

  An Error occurred while handling another error:
  craft\errors\SiteNotFoundException: No primary site exists in /opt/bitnami/apache2/vhosts/ijm.org/htdocs/vendor/craftcms/cms/src/services/Sites.php:422
  Stack trace:
      #0 /opt/bitnami/apache2/vhosts/ijm.org/htdocs/vendor/craftcms/cms/src/web/Request.php(1120): craft\services\Sites->getPrimarySite()

I have tried adding a siteUrl setting in the general.php file, but that didn't help.

Does anyone have any ideas on how to fix this issue?

Thanks!

I was able to resolve this issue by reimporting the database.


List Orders with datePaid is within last 14 days using the Element API plugin I want to list the orders with datePaid is within last 14 days. But I cannot workout the correct criteria, and I don't know if isPaid works correctly as well:

'criteria' => [
    'dateUpdated' => '>=' . date('Y-m-d'.' 00:00:00', strtotime("-14 days")),
    'isPaid' => '1',
],

Here's an example elementapi.php that should get you going...this is returning shipping details but you can modify the transformer for whatever data you need of course...

return [
'endpoints' => [
    'api/json/orders/whatever.json' =>  [
        'paginate' => false,
        'elementType' => 'Commerce_Order',
        'criteria' =>   ['dateOrdered' => '>'. date('Y-m-d', strtotime("-2 weeks")),
                         'isPaid' => true,
                        ],

        'transformer' => function(Commerce_OrderModel $order) {
            return [
            "id" => $order->ISOrderNumber,
            "fullname" => $order->shippingAddress->firstName ?? '' . " " . $order->shippingAddress->lastName ?? '',
            "firstname" => $order->shippingAddress->firstName ?? '',
            "lastname" => $order->shippingAddress->lastName ?? '',
            "company" => $order->shippingAddress->businessName ?? '',
            "street1" => $order->shippingAddress->address1 ?? '',
            "street2" => $order->shippingAddress->address2 ?? '',
            "suburb" => $order->shippingAddress->city ?? '',
            "state" => $order->shippingAddress->stateName ?? '',
            "postcode" => $order->shippingAddress->zipCode ?? '',
            "phone" => $order->shippingAddress->phone ?? '',
            "mobile" => $order->shippingAddress->phone ?? '',
            "email" => $order->email ?? '',
            ];
        },
    ],

    // Next api thing to go here...

],

];


How to move Craft from a subdirectory to public_html I have my Craft 3 site all up and running on domain.com/2/

I need to move it to just domain.com

The Craft files are all one level above public_html like they should be. Not sure what I need to change to bring everything from /2/ to the root level. Would like to avoid installing a fresh copy of Craft if possible.

Without having seen your setup, I'd say this is what you need to do:

Move all files and folders (don't forget the hidden ones) to the correct location
Edit your web/index.php file, to make it look for Craft in the right location (it's looking 2 folders up now, it should only be one folder up.
Change your site's base url, in your config/general.php, .env, or wherever you've set it.
Change the paths and urls for the asset folders
Just to be sure, clear your cache (removing the contents of storage/runtime should do the trick)

Again, depending on your setup there's a thousand things that could prevent this from working, but it should get you going!


How can I specify order when getting all products of a given type? I am getting a list of all products for a specific type within commerce. All is well & working great.

I would like to know how I can dictate order. In my case, I always want the cheapest product first; the most expensive last. A perfect example would be if I were purchasing a level of membership in that "level" is a product.

So on my product index page:
mysite.com/memberships

I want to always have the cheapest membership listed first, all the way up to the most expensive.

As an element, it has the same order criteria as entries, assets, &c. So you should have no problem using order('defaultPrice') in your criteria. That's for price low-to-high. For high-to-low, you add desc to the criteria. So: order('defaultPrice desc').


Syntax for Multisort Filter I am trying to use the new multisort filter to sort an array in reverse order using a date key, but can't seem to figure out the correct syntax. Here is what I have:

{% for rides in allRides|multisort(eventDate,SORT_DESC,SORT_REGULAR) %}

This throws an error saying "Variable eventDate does not exist". eventDate is definitely a key in the array 'allRides'

If I do this, it works fine, but gets sorted by eventDate ascending:

{% for rides in allRides|sort %}

Some guidance on using the multisort filter would be greatly appreciated!

For those of you reading through this post, I thought it might be useful to provide a bit of background on my question. The Craft Docs list "multisort" under Filters and it sounded like something that would work nicely for me. However, the Craft Docs do not give an example, instead directing the reader to Yii docs. Those docs confirmed it was exactly what I needed - sorting an array by a given key, descending, numeric. However, the syntax does not make sense in term of using it within a template.

Here is the answer from Brad and Andrew, which works great:

{% for rides in allRides|multisort(['eventDate'],['SORT_DESC'],['SORT_REGULAR']) %}

Here is what you will find on the Yii docs page :

public static void multisort ( &$array, $key, $direction = SORT_ASC, $sortFlag = SORT_REGULAR )

I suppose if you are a php wizard, which, as you might have guessed, I am not, you might figure this out on your own. Having said that, it would save many of us lots of time if the Craft docs simply included the example that Brad was kind enough to provide.


Customizing front-end login/logout redirects I have "manage" link that redirects to domain.com/login.
"login" is custom front-end page that after logging in redirects to homepage.
After logging in when I click "manage" again the domain.com/login redirects me to CP dashboard.
Signing out from CP redirects me to default Craft login page.

How to redirect directly to dashboard after logging in?
How to redirect directly to domain.com/login or homepage after signing out?

I'm also using manager as cpTrigger, and this is my config:

'postLoginRedirect' => 'manager',
'logoutPath' => 'login',
'cpTrigger' => 'manager',

For some reason according to #1 postLoginRedirect doesn't take effect
same for #2 and logoutPath, maybe I'm using them in the wrong way?

login/index.html code:

{% extends "login/_layout" %}
{% set title = "Welcome back, friend :)" %}
{% block content %}

          <form method="post" accept-charset="UTF-8">
          {{ getCsrfInput() }}
          <input type="hidden" name="action" value="users/login">

            {% if errorMessage is defined %}

               {{ errorMessage }}

            {% endif %}

                <input class="input" id="loginName" type="text" name="loginName" placeholder="Email">

                <input class="input" id="password" type="password" name="password" placeholder="Password">

                <input type="checkbox" name="rememberMe" value="1">
                Keep me logged in

                <button class="button is-primary" type="submit">Login</button>
                Cancel

          </form>

              Register an Account
              |
              Forgot password
              |
              Need help?

{% endblock %}

How to redirect directly to dashboard after logging in?

Since your login form is on the front-end of the site, the postLoginRedirect should do what you're looking for.

You can see the logic Craft uses to determine where to send a user after a successful login here: https://github.com/craftcms/cms/tree/master-v2/src/controllers/UsersController.php#L1599-L1614

  How to redirect directly to domain.com/login or homepage after signing out?

You've got the logoutPath config setting set 'login', which is going to log a user out as soon as they hit the /login URI, which probably isn't what you're looking for.

There currently isn't a config setting to decide where to send a user after they've been logged out, but you could write a very simple plugin that listened to the onLogout event and redirected to wherever you wished.


Can I use Redactor on my front end? I'm building a simple user backend and I would like to use Redactor for a couple fields. I see Redactor is a commercial product.

When I pay for Craft Pro does that include a license to use Redactor?
From an implementation standpoint, can I use the libraries already available?

I guess I wouldn't mind loading in another version of redactor for my front end. But I'm mostly curious if my craft license covers a redactor license.

Brandon has answered this here.

tl;dr: technically possible, legally questionable, in practice not a good idea.


Moved from local to remote "Service Unavailable Our site is temporarily unavailable. Please try again later." I built a site locally and moved it up to a remote host. I am getting a page that says

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

It’s clearly a page coming from Craft so i know the CraftPath is set up right. I have multi-environment variables set up in config/general.php that seem to be working, i.e. it still works locally and there is a stylesheet being called properly in the error page so i think my {baseUrl} is working. I also have them in config/db.php and at least, the local connection is being made. I have devMode => true and it's not giving any hints...

So i uploaded /craft and /public and imported the database. I’m currently using an IP address because the Url is in use and will be moved later on. I had the IP set up so i get to my /index.php and it seems to go out and find /craft OK.

I don’t have to reinstall craft or anything do i?

The /craft, /public, database, and multi environment variables should do it? Is there some other thing i need to do?

Would a DB connection error be clear?

That error means your site is currently offline.  Check in the control panel under Settings->General to see if it's set to offline there.  Or maybe you're using the isSystemOn config setting and it's set to off on your production environment there.


How can I make a template output its own filename? Is it possible to output the template name being used? Using a global variable or something similar? I am wanting to check which template is being used in a conditional.

You can get the current template’s name like so:

{{ _self.getTemplateName() }}


Getting current entry element via plugin in Craft 3 without a hook Is it possible to query the current entry or category element via a Craft 3 plugin/module?

In the 2.6 era, I would use a hook. The Craft 3 iteration of a hook looks something like this:

$currentElement;

Craft::$app->getView()->hook('someHook', function(array &$context) {
  if (isset($context['entry'])) {
    $currentElement = $context['entry'];
  } else if (isset($context['category'])) {
    $currentElement = $context['category'];
  }
});

With an accompanying Twig snippet in the template:

{% hook 'someHook' %}

I'm wondering if there is a cleaner practice to accomplish the same goal? I find relying on Twig snippet reduces the flexibility of my plugin.

I've noticed the SEOMatic plugin is able to append entry specific data without any hooks in the template. I can't figure out how, but it gives me hope.

Check out Craft::$app->getElements()->getElementByUri() -- or you might also use Craft::$app->getUrlManager()->getMatchedElement() depending on your use case.

Your friendly neighborhood SEOmatic author :)


Frontend form to change Craft Commerce user's password? I'm trying to modify Craft 3's example 'Change password' form to work with a logged in Commerce 2 user, and have copied that code to templates/setpassword.twig.

Two problems...

(1) The {{ code }} and {{ id }} variables throw Don't exist errors.

(2) If I comment those variables out, I get a Page not found/"Unable to resolve the request: users/setPassword" error when submitting the form.

Clearly I'm doing this totally wrong ... can anyone set me straight?

<form method="post" accept-charset="UTF-8">
{{ csrfInput() }}
<input type="hidden" name="action" value="users/set-password">
<input type="hidden" name="code" value="{{ code }}">
<input type="hidden" name="id" value="{{ id }}">

New Password

<input id="newPassword" type="password" name="newPassword">
{% if errors is defined %}

        {% for error in errors %}

{{ error }}

        {% endfor %}

{% endif %}

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

The code you are currently using is for the Set Password form that is used when a user forgets their password and you send them a Password reset email as documented at https://docs.craftcms.com/v3/dev/examples/set-password-form.html.

Here is what I'm using to allow users to change their passwords on demand. It is based on the User Profile Form documented at https://docs.craftcms.com/v3/dev/examples/user-profile-form.html

<form method="post" accept-charset="UTF-8">
    {{ csrfInput() }}
    <input type="hidden" name="action" value="users/save-user">
    {# Change to suit your needs #}
    {{ redirectInput('users/'~currentUser.username) }}
    {# Get logged-in user's ID #}
    <input type="hidden" name="userId" value="{{ currentUser.id }}">

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

                {% for error in errors %}

{{ error }}

                {% endfor %}

        {% endif %}
    {% endmacro %}

    {% from _self import errorList %}

    {# Enter current password #}

Current Password

    <input id="password" type="password" name="password">

    {% if account is defined %}
        {{ errorList(user.getErrors('password')) }}
    {% endif %}

    {# Enter new password #}

New Password

    <input id="newPassword" type="password" name="newPassword">

    {% if account is defined %}
        {{ errorList(user.getErrors('newPassword')) }}
    {% endif %}

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

UPDATE: updated form to include error handling.


Pre populated New Entry Is there a way to pre-populate the 'New Entry' form in the back end?

The context here is a calendar where you can click on a day and see a list of events and have a "New Event" button. The "New Event" button should ideally open the CMS backend and pre populate the event date (and some other fields).

We've chosen not to build a a whole new form because the events are quite complex, containing more than one matrix and assets, and it'll only be admins creating events (they don't need all the glitz).

You can have placeholders and default values, but I guess that won't be enough for you.

You could create a plugin that injects some javascript into the new entry page that executes an AJAX call and fills these fields in.


Prev / Next Link Problem I've this macro:

{{ dh_macros.dh_postNav(entry, 'blog', 'postDate', 'prev article', 'next article') }}

I call it on my blog/_single template and it works for 90% of the posts. But the newest 6 posts doesn't show the next / prev links.

This is the last post how it works fine. In the next newer post it looks like this:

Here is the next post link missing. And one post newer there is no link shown neither next nor prev :/

To appreciation, there are next / prev posts there.

It feels really random and I've no idea what's going wrong.
Maybe someone has an idea.

Thanks!

Here the Full Code maybe someone need it:

{#
    Prev / Next Link
    Examples:

    {{ dh_macros.dh_postNav(entry, 'work', 'postDate', 'prev work', 'next work' ) }}
#}

    {% macro dh_postNav(entry, section, order, prevLabel, nextLabel ) %}

    {# Set vars #}
    {% set section     = section|default('blog') %}
    {% set order       = order|default('postDate') %}
    {% set prevLabel   = prevLabel|default(false) %}
    {% set nextLabel   = nextLabel|default(false) %}

    {# Set parameters for prev/next elements list #}
    {% set data = craft.entries.section(section).order(order).limit(null) %}

    {# Get the prev/next elements #}
    {% set prevEntry = entry.getPrev(data) %}
    {% set nextEntry = entry.getNext(data) %}

    {# And make sure to only output the links if the element exists #}
    {% if prevEntry or nextEntry %}

            {% if prevEntry %}

                        {% if prevLabel != false %}
                            {{ prevLabel }}
                        {% endif %}

                        {{ prevEntry.title }}

            {% endif %}

            {% if nextEntry %}

                        {% if nextLabel != false %}
                            {{ nextLabel }}
                        {% endif %}

                        {{ nextEntry.title }}

            {% endif %}

    {% endif %}

{% endmacro %}

Make sure you are using

.limit(null)

In your element criteria model


User Profile Not Saving Changes My edit profile page doensn't save all fields:

<form method="post" action="" accept-charset="UTF-8" enctype="multipart/form-data">
    <input type="hidden" name="action" value="users/saveUser">
    <input type="hidden" name="redirect" value="/users/{{ user.username }}">
    <input type="hidden" name="userId" value="{{ user.id }}">

    <fieldset>
      <legend>Your Photo</legend>
    {# Check to see if the user has a photo  #}
    {% if currentUser.photoUrl %}

    {# If a photo exists, give the option to change the user photo #}

    <input type="file" name="userPhoto" value="Change Photo" class="form-control">

    {% else %}

    {# If no photo exists, give the option to upload a new one #}

    <input type="file" name="userPhoto" value="Upload" class="form-control">

    {% endif %}
  </fieldset>

  <fieldset>
    <legend>Your Login Details</legend>

    Email address
    <input type="email" class="form-control" id="email" name="fields[email]" value="{{ user.email }}">

  </fieldset>

  <fieldset>
  <legend>Your Personal Details</legend>

  First Name
  <input type="text" class="form-control" id="firstName" name="fields[firstName}" value="{{ user.firstName }}">

  Last Name
  <input type="text" class="form-control" id="lastName" name="fields[lastName]" value="{{ user.lastName }}">

  Contact Number
  <input type="text" class="form-control" id="phoneNumber" name="fields[phoneNumber]" value="{{ user.phoneNumber}}">

  </fieldset>

  <fieldset>
    {% set pets = craft.fields.getFieldbyHandle('pets') %}

  <legend>Your Property Details</legend>
  {{ pets.instructions }}
  <select class="form-control margin-bottom" id="pets" name="fields[pets]">
    {% for option in user.pets.options %}
    <option {% if option.selected %}selected="selected"{% endif %}>{{ option }}</option>
    {% endfor %}
  </select>

  {% set renting = craft.fields.getFieldbyHandle('renting') %}

  {{ renting.instructions }}
  <select class="form-control margin-bottom" id="renting" name="fields[renting]">
    {% for option in user.renting.options %}
    <option {% if option.selected %}selected="selected"{% endif %}>{{ option }}</option>
    {% endfor %}
  </select>

  </fieldset>

  <input type="submit" class="btn btn-primary pull-right margin-top" value="Save Profile">
</form>

It only saves the last two fields which means that a user can't change their email address, name or phone number.

I've recently updated Craft to the latest build (Craft Pro 2.1.2566) and also changed user/saveProfile to user/saveUser.

firstName, lastName, and email are actual user fields (not custom), so their name= attributes shouldn’t have the fields[] namespace.

<input type="email" class="form-control" id="email" name="email" value="{{ user.email }}">

<input type="text" class="form-control" id="firstName" name="firstName" value="{{ user.firstName }}">

<input type="text" class="form-control" id="lastName" name="lastName" value="{{ user.lastName }}">

I’m guessing that once you fix those, your phoneNumber custom field will also start saving.


Cast Entry to appropriate type to access fields and functions in module Newbie to Craft CMS. I am trying to send a push notification to an app when an entry of specific type (NewsItem) is saved, and I'm doing so via a Craft Module. I got this code snippet from another StackExchange question, and I have changed it a bit to implement it according to my needs:

        Craft::$app->elements->on(Elements::EVENT_AFTER_SAVE_ELEMENT, function(ElementEvent $event) {

            // Make sure it's an entry.
            if ($event->element instanceof craft\elements\Entry) {
                $entry = $event->element;

                // Check if it's in the section you care about
                if ($entry->sectionId == 1) {
                    // Do your custom logic

                        if(isset($entry->photo))
                            $image_name = $entry->photo->getUrl();
                        else
                            $image_name = 'http://img.youtube.com/vi/' . $entry->youtubeVideoCode . '/0.jpg';

I'm getting this error:

Calling unknown method: craft\elements\db\AssetQuery::getUrl()

I may be wrong, but I'm assuming I have to cast $entry to (NewsItem) somewhere in the code to access the getUrl() function? How and where do I do that?

Thanks in advance for your help.

The actual answer is mostly unrelated to your question, but I wanted to provide some context, first!

Entry Types don't get their own PHP classes. All Entries are just instances of the craft\elements\Entry class, distinguished by their section ($entry->getSection()) and type ($entry->getType()) values.

If you need to check the section and type of your entry, you can compare against the sectionId and typeId properties. Keep in mind that these IDs may be different, across environments, so it's better to use the handle and keep it in sync with your project.yml:

if ($entry->getSection()->handle == 'mySectionHandle' && $entry->getType()->handle == 'myEntryTypeHandle') {
  // Your logic!
}

Ok, now on to the error you're seeing!

Calling unknown method: craft\elements\db\AssetQuery::getUrl()

This is actually telling you that the accessed field/property (photo) returns an object that doesn't have a getUrl() method.

Unless relational field data is eager-loaded, accessing its property will return an ElementQuery (in your case, an AssetQuery), prepped to return the related Elements.

So, before accessing methods on the expected value (an Asset Element), you have to execute the query:

$photo = $entry->photo->one();

if ($photo) {
  // At least one photo was attached! You can safely access the Asset object's properties + methods:
  $url = $photo->getUrl();
} else {
  // Set a default:
  $url = 'https://...';
}


How can I output a specific field in Sprout Forms email notifications? I'm trying to override a Sprout Forms email notification template. The example template loops over tabs and fields and outputs them all, that works. I'd like to manually reference specific fields in specific places (like first_name). How can I reach the field values?

Turns out, there's an element twig variable that I can use (it contains the Sprout Form entry), so I can output:

{{ element.first_name }}

for instance.


Confirm Password on Set Password Form Is there a way to send errors back to the set password form?

I am listening to the users.onBeforeSetPassword event in which I want to confirm that the string in a confirm password field is the same as in the newPassword field.

craft()->on('users.onBeforeSetPassword', function(Event $event) {
       // Only do anything if it is a front end submission
       if(craft()->request->isSiteRequest())
       {
           $newPassword = craft()->request->getPost('newPassword');
           $passwordConfirm = craft()->request->getPost('passwordConfirm');
           if(isset($passwordConfirm) && strcmp($newPassword, $passwordConfirm) !== 0)
           {
               $event->params['user']->addErrors(array('newPassword' => Craft::t('Passwords do not match')));
               $event->performAction = false;
           }
       }
   });
  }
}

This does prevent the user from resetting their password but doesn't send a error message back to the template.  How can I pass a variable back to the template so I can show the user their error?

You could use the craft()->userSession->setFlash('your message here'); functionality.

How it works is explained in this or this answer for example but it boils down to setting the message in your event handler and then checking in your template if there's a message and if there's one, display it.


How to add target to link within field instructions? I don't see anything in the documentation about how flexible the instructions fields are, as they use Markdown syntax. It's not clear how to add a target to a link, for example.

Craft uses Github Flavored Markdown and I don't believe targets are supported in links: https://github.github.com/gfm/#links
Honestly, not sure that I've seen any Markdown flavors that actually support that.


Access POST data to conditionally display form I'm working with the contact form plugin and would like to test for post data to see if the form was just submitted.

It seems this code always throws a template error.

Variable "test" does not exist

Is there a better way to do this?

{% set success = craft.request.getPost(test) %}
{% if success %}
    form was just submitted
{% endif %}

I think you want this:

{% set success = craft.request.getPost('test') %}
{% if success %}form was just submitted{% endif %}

Pass a string to getPost()


Logging IP with Guest Entries Plugin I'm using the Guest Entries plugin and it's all working great, the problem is I'm getting spammed like mad. I've got snaptcha installed which seems to be catching some of it but I could do with an IP log so I can see if it is coming from a certain IP or IP range.

I ideally want the IP logged with the form submission as server access logs are hard to match up.

You could add a field "IP Address" to your Entry Type and make the form submit the guest's IP (→ getIpAddress() method) via a hidden field.

<input type="hidden" name="fields[ipAddress]" value="{{ craft.request.getIpAddress() }}">

For further improvements you could make your own field type for "IP Address" with a plugin, that adds custom validation (→ block certain IP ranges). You could also hide the field from the CP or make it only readable.


Is FeedMe v2 supporting FTP with basic authentication I'm currently redoing a import mechanism for a site we've inherited.  I'm trying to use Feedme version 2 for this as opposed to the custom import script that was written (and is not working too well).

The import needs to be transferred via FTP with basic authentication.  I saw that version 1.4.7 included this FTP support and I'm wondering if that includes FTP with basic authentication and if that function is actually at all available in Feedme2

FTP should still work just fine in Feed Me 2. You can also use basic authentication by providing the username/password in the URL.

ftp://username:password@website.com/public_html/feed.xml

You can also use the curlOptions settings in the configuration.


Loop through related section's entries I have two sections:
games
publishers

For example, a games entry title would be "Mario Brothers" and a publishers entry title would be "Nintendo"

On the entry page for Nintendo, I want to display all games (entries) they published.

The "_entry,html" page for publishers right now only has the following code:

{% extends "_layout" %}

{% block content %}

{{ entry.title }}

        {{ entry.body }}

{% endblock %}

So I know I need to add it after:

In the games section, I have a field called "GamePublishers" set to type Entries. So I assign the publisher of a game via the admin cp. Wasn't sure if I need to also setup a field type entries in GamePublishers to reference to Games section. (If that makes sense)

Thanks

Wasn't sure if I need to also setup a field type entries in GamePublishers to reference to Games section.

Not necessary if you already have a "GamePublishers" Entry field in the "Games" section.

Something like this should work:

{% set games = craft.entries.section('games').relatedTo(publisher) %}

That's assuming you've already got a variable named publisher defined that's referencing the current publisher the user is viewing.

I'd suggest reading through the relations docs as well.  Craft has a pretty powerful relations engine you can do all sorts of crazy stuff with.


onBeforeSaveEntry listener to add/modify data of some fields I'm trying to build my first, very simple, one file plugin.  I'm having difficulty with a basic task and I can't find any documentation to help me out. Keep in mind that there is no validation whatsoever, I'm just trying to get it to work first.

public function init()
{
    parent::init();
    craft()->on('entries.onBeforeSaveEntry', function(Event $event)
    {
        $entry = $event->params['entry'];
        $section = craft()->sections->getSectionById($entry['sectionId']);
        if ($section['handle'] == 'institutions')
        {
            $full_address = urlencode(rtrim($entry['adresse'].','.$entry['ville'].','.$entry['province'].','.$entry['codePostal']));
            $json = json_decode(file_get_contents("https://maps.googleapis.com/maps/api/geocode/json?address={$full_address}&sensor=false&region=ca&key=AIzaSyDhPYj9UwwUYNZYSz9Fo-j75gCJKWVdFeY"));
            $entry->setRawPostContent('latitude' ,$json->results[0]->geometry->location->lat);
            $entry->setRawPostContent('longitude', $json->results[0]->geometry->location->lng);
        }
    });
}

I have a listener on entries.onBeforeSaveEntry and it works well.  I check if the section handle is what I need and then I look into the entry data to grab the address fields and query Google map.  All of that is working like a charm.

I can't figure out how to put the data back into the entry for the lat and long filed that exists in my entry type.

$entry['latitude'] = $json->results[0]->geometry->location->lat;

That gives me an error saying latitude is not defined, which is false because I can output the value from it.

Also tried:

$entry->setRawPostContent('latitude' ,$json->results[0]->geometry->location->lat);

Any idea?  I can't find any documentation or google search that can help me out.

See Brandon's post on this here:
What is getContent() / the ContentModel, and how do I use it to get and set custom field values?

Basically when you're setting new custom field values, you should use setContentFromPost

$entry->setContentFromPost(array(
    'latitude' => $json->results[0]->geometry->location->lat,
);


How can I disable relative dates in elements index? In control panel, specifically when displaying elements table under any section, postDate and expiryDate values are in relative format i.e. Today, Yesterday, Monday, Wednesday, ..etc.

How can I disable that and display them in dates only?

Until this feature get implemented, I think I'll go with the following workaround that I'm using right now.
It's based on  getEntryTableAttributeHtml hook where I reformat the date value to match the user locale preferences.

public function getEntryTableAttributeHtml(EntryModel $entry, $attribute)
{
    if ($attribute == 'postDate')
    {
        $localeData = craft()->i18n->getLocaleData(craft()->language);
        $dateFormatter = $localeData->getDateFormatter();
        $format = $dateFormatter->getDatepickerPhpFormat();
        return ($entry->postDate ? $entry->postDate->format($format) : '');
    }
}

or simply

public function getEntryTableAttributeHtml(EntryModel $entry, $attribute)
{
    if ($attribute == 'postDate')
    {
        return $entry->postDate;
    }
}

which will return the date in Y-m-d format regardless of locale.


Including author in search for entries I've got a site-wide search box (based on the example in the documentation). It's doing a good job of searching through the entries, but is there a way that I can include a search through a user group like authors as well and include it in the same list of results?

Currently I just have this but its not getting any results for author searches even though I know they exist. It seems like the authors should be searchable since they're linked to the entry...

{% set entries = craft.entries.search(query).order('score') %}

If I did another search through craft.users.search I could get another list of results, but I'd like to have one combined list. Is something like that possible?

You could use the Twig functions merge and default to merge the two sets of entries.

{% set entries = craft.entries.search(query).order('score')|default([]) %}
{% set authors = craft.users.search('fullName:*' ~ query ~ '*')|default([]) %}

{% if authors %}
    {% set results = entries|merge(authorArticles) %}
{% endif %}

<p>
    You have {{ results|length }} {{ results|length == 1 ? 'result' : 'results' }}.
</p>

The default function is a handy stand-in for short circuit evaluation in twig, so that you can be sure to at least pass an empty array to merge.


Commerce: Template error: “Variable "option" does not exist I am getting this error when trying to send a confirmation email to the user.

Template error: “Variable "option" does not exist

If I remove every bit of markup from my email template, and literally only have
Hello World
 I get an email.

I am able to click the "Download Receipt" link, and everything works great.

When I output the option variable: {{ option }}:
When I click on the "Download" link, I see receipt.

I am using the default template that ships with commerce, with the addition of a jpg header image. At the bottom of the template is this:

...
{% endset %}

{# Use the option param passed into the pdf template to show different
   order pdf's depending on the context #}

 {% switch option %}
 {% case "receipt" %}

Receipt for Order #{{ order.number[:7] }}

    {{ orderTable }}
{% case "ajax" %}

NA

{% default %}
    {{ orderTable }}
{% endswitch %}

So clearly it has something to do with option not getting set. I'm not sure where I might have un-done setting that variable.

Any suggestions are greatly appreciated!

The option variable is only available in the pdf template, it is not available in the email template.

order variable available in both.


500 Internal Server Error after moving index.php Installed using composer. No issues. Installed in /craft directory. Used the command line setup with what seemed like no issues. Moved my files from /craft/web to /public_html. When I try to get the site I get a 500 error. I CAN get http://domain.com/phpinfo.php. What could be the issue?

Edit
I changed file permission of index.php to 644 and now get a different page with the same error. The first page is the standard cpanel 500 error with formatting. The second error page is a less formatted 500 page:

  This page isn’t working
  67.227.155.172 is currently unable to handle this request. HTTP ERROR 500

You have to change your Craft path accordingly. When you move your web folder, you have to edit your index.php obviously.

Your php file does not magically know where your vendor folder is