Dropdown field value getting outputted multiple times I have a dropdown field that has three options. In my template, I want to do one thing if option 1 is selected and do something else if option 2 is selected.

Here is what my code looks like:

{% for option in entry.transparentMenu.options %}
    {% if entry.transparentMenu.value == "menuLight" %}

white

    {% elseif entry.transparentMenu.value == "menuDark" %}

black

    {% endif %}
{% endfor %}

The code seems to work but the output is: black black black; I only want black to display once.

What am I doing wrong?

You don't need the for loop in this case. What's happening is you're looping over each option in your dropdown field, and each time it's checking the value of the dropdown and displaying white or black. Since you have three options, you're going to get the dropdown value displayed three times (which is why you're seeing black black black).

All you need is just the if conditional:

{% if entry.transparentMenu.value == "menuLight" %}

white

{% elseif entry.transparentMenu.value == "menuDark" %}

black

{% endif %}

  Also, fwiw looks like you have a typo in your code  - you use entry.transparentMenu twice and entry.header.transparentMenu once. I'm guessing you want entry.transparentMenu everywhere...

The only time you'd want to use the for loop to get all the dropdown field's options is if you wanted to display those in the template (in a list for example or to create your own dropdown on the frontend):

    {% for option in entry.dropdownFieldHandle.options %}

{{ option }}

    {% endfor %}

But in your case, you just want the current value and not all the options, so just remove the for loop.

I don't know your structure, but if transparentMenu is a select or checkbox or something with menuLight and menuDark as options, it should be:

{% for option in entry.transparentMenu.options %}
        {% if entry.header.transparentMenu.value == "menuLight" %}

white

        {% elseif entry.header.transparentMenu.value == "menuDark" %}

black

        {% endif %}
    {% endfor %}

instead of:

{% for option in entry.transparentMenu.options %}
        {% if entry.transparentMenu.value == "menuLight" %}

white

        {% elseif entry.header.transparentMenu.value == "menuDark" %}

black

        {% endif %}
    {% endfor %}

right?


Reset password with MySQL Is there a way to reset an admin account's password by modifying the MySQL directly?

I've found the craft_users table where the hashed password is stored but I don't know how to hash a string so that it will be read correctly by Craft.

Future me, looks like you forgot your password again and locked yourself out of Craft. You also made your way back to this Stack Exchange question with @chris' perfect answer. Good! And to make your life really easy this time around, I've already generated a password/hash combos for you that works:
|--------------|---------------------------------------------------------------|
|  *Password*  |                        *Resulting Hash*                       |
|--------------|---------------------------------------------------------------|
|  password    | $2y$13$i1fEVeKiboWR/Hx07N9JtuSZj46KNueAg0IgpwL2TId0sXN.oyibC  |
|--------------|---------------------------------------------------------------|
|  NewPassword | $2y$13$YA.7RIgllODUDcmQPf/.FuXjOmKJYot5QxpFhhf4og9fdJWsIPWK6  |
|--------------|---------------------------------------------------------------|
|  admin       | $2y$13$Nlvh.kEu8FLIITusfjzQgOIIDryqLnJ3TsV/1UINRCFLfVnjJtILK  |
|--------------|---------------------------------------------------------------|

Update: The hashing algorithm didn’t change in Craft 3, so the above combo still works.

If you don't want to mess about trying to insert code in the Craft/Yii stack, v3 just calls password_hash():

password_hash($your_password_string, PASSWORD_DEFAULT, ['cost' => 13]);

As a possibly helpful addendum (I was just trying to run the site locally and needed to log in); if you find you still can't login after changing the password via the database and are running PHP locally, it might be because you're accessing via socket and should add this to config/general.php:

'requireUserAgentAndIpForSession' => false,


Does Craft have an installer error log I can check? I've tried to install Craft on a variety of systems, and it seems that no matter what I try, I cannot get all the way through the installation process. In most cases, my install hangs on the "Oops" screen.

I've learned not to trust this screen, because if I immediately close the window and cancel my installation, the installer screen continues to show up when trying to access the admin login /admin/.

Instead, if I just let it sit for a few minutes then close the screen, it seems like the install actually works as expected. Visiting /admin/ in my browser has the desired affect, and I'm able to use the CMS as expected.

My thought is that it might be something related to the install cleanup process - but I'd like to take a peek at the install log file to see exactly where things went wrong.

I've checked system requirements, although on some systems, I'm unable to personally verify all of the requirements are met. But I'd like to know why I got that "Oops" screen. It's obviously a non-critical error, or else the db and system would not function properly - which it does.

Typically the Craft logs are stored here:

/craft/storage/runtime/logs

I don't know how much logging the installer does, but if it does any at all, that's where you'll find the log data.

In the meantime, you can also try this script by Ben Croker which will check your server configuration to make sure it has everything it needs to proceed.

Turn off your MySQL server in System Preferences, that worked for me.


Is there a way to manually trigger an asset transform before calling getUrl()? I have a site where I serve quite the amount of images which are saved on Google Cloud Storage. I have set generateTransformsBeforePageLoad to true in my general config because I'm caching the output for Fastly (based on Varnish). The downside is that on first request it's awfully slow and at one point even returns a 503 error.

Is there a way that assets can be transformed before getUrl() is being called? Other solutions are more than welcome.

You could use my Preparse Field plugin to generate transforms when an entry (or any other element) is saved.

Create a preparse field and create some twig that makes the same transforms that you do in your template. Don't care about the output, the only thing you want it to do is generate the images on save. Assuming you attach the field to an entry, and you have a field named myImageField, the code could look something like this:

{% if entry.myImageField | length %}
  {% for image in entry.myImageField %}
    {{ image.getUrl({ width: 1600 })
    {{ image.getUrl({ width: 1200 })
    {{ image.getUrl({ width: 800 })
    {{ image.getUrl({ width: 400 })
  {% endfor %}
{% endif %}

When you save the entry, this code will run, and create any new image transforms. When the entry is displayed in the front-end, the image transforms will already have been created.

Beware that this will not actually increase the speed of the transforms, only shift the time it takes from the front-end user over to the admin. But I find that this is more acceptable in most of my use-cases.

You can set transforms in the CMS, then in your template you call the actual name of the transform you make in the dashboard instead, you still use getUrl, but you can generate the assets with "Update Image Assets" on the settings page in the dashboard.

read more here: https://craftcms.com/docs/image-transforms#applying-cp-defined-transforms-to-images

note*: The fixed nav covers this area slightly now...

Also, I think I remember hearing/reading it's better for performance for assets not to be cached with varnish too.


Craft 3: Cache element query or variable assignment Is it possible to cache a variable assignment and/or an element query with TWIG in Craft 3? With Yii2 this is possible, but is there a wrapper to TWIG?

2 use cases:

{% set entries = craft.entries.someThingVerySlowHere() %}
{% set myObject = customVerySlowTwigFunction(...) %}

Why would I want to do that? Let's assume I have 2 blocks in my page, both make use of the variables assigned above, then I can not cache this within the block itself (where the {% cache %} tag belongs, unless I assign/query twice.

The request makes sense, but I thought that Craft did some magic to make sure that a duplicate query/variable-assignment wasn't an issue by re-using the query internally. I have no idea why I think that though.


How to remove Link To Category from Redactor Is there a way to remove the 2 Craft specific menu items from Redactor's Link menu without losing access to the "Insert link" menu item?

Removing the Link button in the redactor configs is too draconian as I don't want to lose access to the basic Insert and Unlink functions previously in that menu.

I've dug into the src, and the only hook/event I can find related to the redactor settings allows addition of menu items to the Links menu, but not removal of the Craft added "Link to an Entry" and "Link to a Category".

I don't think there's an easy way to do this natively in Craft.

Maybe you could pull it off with combination of https://github.com/lindseydiloreto/craft-cpcss and/or https://github.com/lindseydiloreto/craft-cpcjs and manipulate the DOM directly.

Or maybe by going from the Redactor site and listening to their click event.

In craft->app->fieldtypes->RichTextFieldType.php there is a function called _getLinkOptions. In there if you just return an empty array, there will only be the option to link to a URL.


How to transform German umlauts when creating slugs? First of all, I want to thank you for creating Craft. It's really one of the best content management systems I have ever worked with.

I encountered an issue while working on a multilingual site: German Umlauts are not automatically transliterated (Ä -> Ae) for slugs. In other parts of Craft (e.g. field handles) Umlauts are transliterated automatically.

Personally, I would prefer if this behavior could be controlled by a config variable (e.g. slugExpandUmlauts).

Try enabling the config setting limitAutoSlugsToAscii, that should do what you want.

If it´s a one-time operation, maybe you could just import everything and search/replace in MySQL?


How to get user's information when registering or logging in via ajax form I did search for this but was unable to find the documentation for getting user's data on a return when logging them in from a front-end facing login form (I need to do the same for a registration as well).

I need to get a return of the user's Id and their email.

This is my code for the form. It works fine,  I just cannot seem to find the user's info in the data return so if anyone has an example or suggestion it would be greatly appreciated.

$('#workshop-registration-user-login-form').submit(function (e) {
  e.preventDefault();
  var data = $('#workshop-registration-user-login-form').serialize();

  $.ajax({
    type: 'POST',
    url: '/users/login',
    data: data,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
  })
  .success(function(data) {
    console.log(data.currentUserId);

    ...

    // get data populate the fields
  })
  .error(function(data) {
    console.log('error');
  });

Not sure what other user info you're looking for, but Craft's UsersController will only return two things in the JSON response of a successful login for an AJAX request.

A success key set to true and a returnUrl key set to where the login redirect should go to.

In your case, i think you can use element-api, this is a great plugin for extracting data through ajax.


Reverse count with paginated entries? I have this loop

{% paginate craft.entries.section('sermons').limit('10') as pageInfo, entries %}

        {% for sermon in entries %}
        ...
        {{ loop.revindex }}
        ...
        {% endfor %}

That outputs a count from 10 to 1 - however, there's more entries than just the 10.

How can I output the count of what would be absolute total results?

You already pass the array keys into the loop as a variable pageInfo. There's a couple of properties you can access from it, see the Craft docs:

Templating Reference → {% paginate %}

Of interest for you is probably these:

  pageInfo.total – The total number of elements across all pages
  pageInfo.currentPage – The current page number.

It looks like there's no property for the "current element number" and you need to do some math to output it:

{% paginate craft.entries.limit(10) as pageInfo, pageEntries %}
    {% for entry in pageEntries %}

        {% set index = (pageInfo.currentPage - 1) * 10 + loop.index0 %}

        {{ pageInfo.total - index }} of
        {{ pageInfo.total }}

    {% endfor %}
{% endpaginate %}

{% set sermons = craft.entries.section('sermons').limit(null) %}

{{ sermons|length }}

By default, the .find() method, which is what gets called when you call craft.entries automatically gets limited to 100. Get round that by using .limit(null)


Incorrect content/mime-type on S3 SVG upload I've setup an S3 asset source for images and it's working well for everything but SVGs.

SVGs are uploaded with the default content-type of binary/octet-stream where the correct content-type would be image/svg+xml.

Am I doing something wrong or is this a bug?

Your SVG file is probably missing the the XML declaration at the top (<?xml version="1.0" encoding="UTF-8"?>). PHP's FileInfo detects XML files (which SVG is) without that declaration as text/html files.

Lots of SVG editors/exporters will (annoyingly) omit that.

On old versions of python, the python library mimetypes didnt have a definition for svg file types.

See this issue: https://bugs.python.org/issue19377

I added '.svg' : 'image/svg+xml', into the types_map in mimetypes.py and then the aws cli got the correct type for SVGs.


Are there any poll plugins for Craft CMS? Since many of us are coming from EE, I will reference these EE addons as examples:
- channel polls
- vwm polls

I found this question but it didn't help much:
How to deal with client input your site?

Also there is UPVOTE plugin but it's not really polls.
https://www.doublesecretagency.com/plugins/upvote

It is important that it works like field type and that you can add as many options as you need.

Thank you

The only public listing of plugins that I'm aware of is on the straightupcraft site — so if nothing is there that meets your requirements then probably not. New plugins are getting added all the time though.

Depending on your requirements, developing a custom solution would probably not be too difficult though. If you want to give it a shot and have questions feel free to ask.

Poll need to work as field type  so it can be done per entry

as https://devot-ee.com/add-ons/channel-polls
or
https://devot-ee.com/add-ons/vwm-polls

Its important to not have row limits about voting options..


Deploying CraftCMS to Digital Ocean Currently I'm having an issue deploying to Digital Ocean and would love some advice, i've followed numerous tutorials but they seem to just drop off half way through the process so just need some clarity on this. I've broke down what I've done below:

Developed my CraftCMS site in localhost using MAMP.
Committed everything to Github apart from db.php
Created a droplet with LAMP
Setup my database names so it corresponds with my localhost
Setup my database user
Created a deploybot setup which contains my     db.php file
Deployed the application using deploy bot which deploys my latest
push in the git repo.

Am I supposed to be reinstalling CraftCMS on the droplet and upload my localhost database after these steps?

I would suggest to read through the following articles:

https://nystudio107.com/blog/multi-environment-config-for-craft-cms

https://nystudio107.com/blog/database-asset-syncing-between-environments-in-craft-cms

About reinstalling craft on your droplet and uploading the local database:

the craft install i used in my local dev environment will be pushed onto the droplet, like this i can assure that it doesn't differ in any of the enviornments. About syncing the database read through the articles it will clear things up. In general all of the articles in nystudios blog are more than helpful. i hope it helped at least a bit.

https://www.youtube.com/watch?v=M6BhLZFslRw install CraftCMS directly on DigitalOcean Droplet.


Security Headers in htaccess Don't Work We have an issue on our server when our Security Headers are not working. We added the following to our htaccess file after installing Craft CMS: -

<IfModule mod_headers.c>
    Header always set X-Xss-Protection "1; mode=block"
    Header always set X-Content-Type-Options "nosniff"
    Header always append X-Frame-Options ALLOWALL
    Header always set Strict-Transport-Security "max-age=31536000"
    Header always set Referrer-Policy no-referrer
</IfModule>

These settings worked on our previous CMS which was completely developed in house. We have recently upgraded our server to PHP 7 and Apache 2.4. We have been using https://securityheaders.io to check our results.

Any help trying to get this to work would be really appreciated.

I'm assuming mod_headers is installed & active? Otherwhise I can't say why the .htaccess rules are not applied (devOps is not my forte) but you could set them through the twig template.

See here for the tag to use. Basically it comes down to something like this (untested):

{% header 'X-Xss-Protection "1; mode=block"' %}
{% header 'X-Content-Type-Options "nosniff' %}
{% header 'X-Frame-Options ALLOWALL' %}
{% header 'Strict-Transport-Security "max-age=31536000"' %}
{% header 'Referrer-Policy no-referrer' %}

You can make those in a block and just include the block on all the relevant pages.

For Apache 2.4, please configure in httpd.conf without mod_headers

.
.
.


Craft CMS solo licence It mentions developers can use it for personal usage. Does that include commercial usage as well? It seems so, but am not sure.

I have a few small personal sideprojects running with some Adsense and Affiliate links (currently on CodeIgniter, etc.).

According to Pixel & Tonic:

Can I use Craft Solo for client work?
Technically yes, however, we don’t recommend it. Craft Solo is meant to be a solution for developers to get to know Craft and create one-off sites for themselves and their friends. We do not recommend giving admin access to non-developers and therefore strongly recommend that any professional work is done on Craft Pro. This ensures the best experience for everyone.

So as long as you're ok with everyone having admin access (and no branding and no developer support), it's fine, including for commercial usage.

I believe that you may only use it this way if you are a developer and the site is promoting your development services. So in a sense yes it is commercial but I think the use case you describe would fall outside the permitted use.

However, I don't represent P&T, so it may be worth contacting them directly for clarification.


if statement in a template not working I am making a condition to use a certain template for a specific article category, but it's not working and giving me an error.

{% extends "_layout" %}

{% set title = category.title %}

{% block head %}
{% endblock %}

{% block content %}

    {% if category.postType=="video" or category.videoLink|length%}
        {% include 'news/hiwar.html' %}
    {% elseif category.postType=="file" %}
        {% include 'news/file.html' %}
    {% else %}
        {% include 'news/articless.html' %}
    {% endif %}

{% endblock %}

5th line: category.videoLink|length%}
Could you try to insert a space between "length" and "%"?


Change profile in frontend with ajax I'm trying to update some checkbox fields through the frontend with ajax.
After clicking / change of the checkbox the form needs to update the profile.

Template code:

<form class="form-horizontal form-ajax" method="POST" action="" accept-charset="UTF-8" id="notificaties">
{{ getCsrfInput() }}
<input type="hidden" name="action" value="/users/saveUser">
<input type="hidden" name="redirect_" value="account">
<input type="hidden" name="userId" value="{{ user.id }}">

            Ontvang updates over leuke nieuwe producten

                <input type="hidden" name="fields[emailUpdates]" value="0">
                <input class="ajaxcheck" type="checkbox" id="fields_emailUpdates" name="fields[emailUpdates]" value="1" {% if user is defined and user.emailUpdates %} checked="checked"{% endif %}>

            Ontvang email updates over geinteresseerde kopers

                <input type="hidden" name="fields[emailReactie]" value="0">
                <input class="ajaxcheck" type="checkbox" id="fields_emailReactie" name="fields[emailReactie]" value="1" {% if user is defined and user.emailReactie %} checked="checked"{% endif %}>

            Ontvang wekelijks een upate over de producten van jou favoriete verkopers

                <input type="hidden" name="fields[emailFavorieten]" value="0">
                <input class="ajaxcheck" type="checkbox" id="fields_emailFavorieten" name="fields[emailFavorieten]" value="1" {% if user is defined and user.emailFavorieten %} checked="checked"{% endif %}>

            Ontvang email updates van de reacties van jou producten

                <input type="hidden" name="fields[emailComments]" value="0">
                <input class="ajaxcheck" type="checkbox" id="fields_emailComments" name="fields[emailComments]" value="1" {% if user is defined and user.emailComments %} checked="checked"{% endif %}>

 </form>

JS code:

 $(".ajaxcheck").click(function(){
    var data = $(this).parents('form').serialize()

    $.ajax({
        context: this,
        method: "POST",
        dataType: "json",
        url: "/actions/users/saveUser",
        success: function(data, response){
            $(this).parents('.account-item').remove();
            console.log("success", response, data);
        }
    });
});

But it gives me an error: GET http://shop.craft.dev/actions/users/saveUser 400 (Bad Request)

The form gets updated. So it works. But it still gives me this error:

In my craft.log file:

exception.Craft\HttpException.400
Message exception 'Craft\HttpException' in /Volumes/HDD Drive/Sites/Shop/app/controllers/BaseController.php:191

The 400 error you’re getting is coming from BaseController::requirePostRequest(). It’s happening because this line:

type: "post",

should be:

method: "POST",

This worked for me. Add data: data, before dataType: "json",

I had the same error, and still get the same error if data source is not defined..


How do I delete a tag? Where in the Craft Control Panel can I globally delete a tag?

Not from a specific entry, but completely out of the system.

Delete the Tag Field in Settings > Fields.

More about Tags Fields: http://buildwithcraft.com/docs/tags-fields

EDIT

This answer is incorrect. The correct answer is:

  Currently it’s not possible to delete tags (or otherwise manage them).

https://craftcms.stackexchange.com/a/1118/298


Sprout Reports plugin - How to output a Matrix field into a row I'm not clear on how I would iterate over a Matrix field to be able to include the content in the row.

Wish there was an example in the docs: https://sprout.barrelstrengthdesign.com/docs/reports/custom-twig-template-report.html#template-settings

{% for entry in entries %}

    {% do craft.sproutReports.addRow([
      entry.title,
      entry.myMatrixField
    ]) %}

{% endfor %}

I got it to work with this code:

{% for entry in entries %}

    {% set myArray = [entry.title] %}

    {% for block in entry.myMatrixField %}

        {% set myArray = myArray|merge([block.field1,block.field2,block.field3]) %}

    {% endfor %}

    {% do craft.sproutReports.addRow(myArray) %}

{% endfor %}

Try the below code

{% for block in entry.myMatrixField %}
  {% if block.type == "sproutReports" %}

{{ block.sproutReports}}

  {% endif %}
{% endfor %}


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.

I raised a PR for this last week but it was closed. Apparently you're not supposed to load those templates from the front end as those variables are not auto-populated by craft. (This code fixes the problem)


Why are some entry detail views empty in the control panel? I can't seem to edit entry details all of a sudden: in this Products section (and only this one section), the page title and "Current Version" button will render, but the rest of the page is missing.

The only clue is this line from Craft's log:

  [31-Jul-2014 19:07:36 UTC] PHP Fatal error: Maximum function nesting level of '100' reached, aborting! in /Users/gob/projects/gobias/craft/app/vendor/twig/twig/lib/Twig/Node.php on line 140

I've loaded earlier MySQL backups, restarted MAMP Pro (PHP 5.5.10), cleared Craft's caches, tried different browsers and machines, and the problem persists.

That error isn't a Craft or PHP error, it's coming from older versions of xDebug.

It can happen on more complicated pages (lots of fields, tabs, etc.), but you can get around it by adjusting the xdebug.max_nesting_level to something higher than the default 100 or to upgrade xDebug to 2.3+, which has changed to the default value to 256.

Note that you don't have to have an active debug session going on in order to run into this, you just have to have the xDebug extension installed.

Simplest solution is just to deactivate all debugger stuff in mamp's PHP settings -> Uncheck: Debugger Activate Xdebug.


Overwrite value in object in array I'm strangely having trouble with this simple Twig merge problem and can't find anything online. Simplified, let's say you had:

{% set users = [
    {name: 'Bill', age: 25},
    {name: 'Tim', age: 30},
    {name: 'John', age: 32}
] %}

How would you change, for example, Tim's age from 30 to 31?  I've tried:

{% set users = users[1]|merge({age: 31}) %}
{{ users[1].name }}: {{ users[1].age }}

But this doesn't work.

Solution

This won't work in Twig as presented in the question (see why below). Instead, users would need to be changed to an associative array (or "hash" in Twig terminology) with keys that aren't integers, and you'd have to insert a merge inside a merge to change the value:

{% set users = {
    person0: {name: 'Bill', age: 25},
    person1: {name: 'Tim', age: 30},
    person2: {name: 'John', age: 32}
} %}

{% set users = users|merge({ person1: users.person1|merge({age: 1000}) }) %}

{% for key, user in users %}
    {{ key }}: {{ user.name }}, {{ user.age }}

{% endfor %}

...which now outputs:

person0: Bill, 25
person1: Tim, 1000
person2: John, 32

If you need to change the keys' integers dynamically, you will write it like this using Twig's attribute function and using brackets:

{% set loopIndex = 1 %}
{% set users = users|merge({ ('person' ~ loopIndex): attribute(users, 'person' ~ loopIndex)|merge({age: 1000}) }) %}

The Reason Why the Question's Array Doesn't Work

Twig's merge filter uses PHP's array_merge function, and according to PHP's docs when using array_merge:

  If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. If, however, the arrays contain numeric keys, the later value will not overwrite the original value, but will be appended.

So trying to overwrite an existing hash in the original array

{% set users = [
    {name: 'Bill', age: 25},
    {name: 'Tim', age: 30},
    {name: 'John', age: 32}
] %}

...will just add the hash as a new, fourth item in the array, not replace the second one.  To demonstrate this clearer, we can rewrite users as a hash like this (it's considered the same as above):

{% set users = {
    0: {name: 'Bill', age: 25},
    1: {name: 'Tim', age: 30},
    2: {name: 'John', age: 32}
} %}

By trying to target the key 1 to change its hash and output users:

{% set users = users|merge([ users.1|merge({age: 1000}) ]) %}

{% for key, user in users %}
    {{ key }}: {{ user.name }}, {{ user.age }}

{% endfor %}

...we get this list:

0: Bill, 25
1: Tim, 30
2: John, 32
3: Tim, 1000

A new "Tim" user will get appended even if you make the keys strings like '0', '1', etc, or using Twig's attribute function. An issue for this was posted in Twig's github and the conversation explains it some more. You can only change a value if it's an array with a list of single values (not a hash) or if it's a key/value hash, and the key can't be an integer.

Did you try something like:

{% set users[1]['age'] = 31 %}


Using setTemplateMode on the frontend I'm trying to access a CP template from the frontend, and i'm doing something like this in my plugin:

<?php

...
$oldMode  = craft()->templates->getTemplateMode();
craft()->templates->setTemplateMode(TemplateMode::CP);

$widget = craft()->templates->render('plugin/Plugin_Template', array(
    'chatraID' => $chatraID,
));

craft()->templates->setTemplateMode($oldMode);
...

I'm getting the Unable to find the template error, though. I have verified that the plugin is installed, and that the template  plugin/Plugin_Template is accessible from the CP.

May have answered on Stack/plugindev:

@sjelfull  was intrigued, so started reading code about this, until the thought occurred: you seem to be asking a front end instance to access a CP template? This shouldn't be allowed unless it was a CP or action request, no?  The setting to TemplateMode can't fail this way, must be in trying to use the template, and that may fall apart at line 904 of TemplateService.php, would think. I don't put it past you to have another clever idea, though :wink: -- Takk for de...


How do I access an asset field in the 'onSaveEntry' event? I'm listening on an entries save event with:

craft()->on('entries.saveEntry', function(Event $event) {
  //$event->params['entry']); -> passes to function
});

How can I assess assets that are also part of that saved entry?

$event->params['entry']->getContent()->{fieldname} doesn't give me the array with information I was hoping for.

This gives you an EntryModel:

$entryModel = $event->params['entry'];

This will give you an array of AssetFileModels:

$assetFileModels = $entryModel->myAssetFieldHandle

You can loop through them like so:

foreach ($assetFileModels as $assetFileModel)
{
    $url = $assetFileModel->getUrl();
}

What about $event->params['entry']->{fieldname}

Wouldn't that be enough?


How to display data in field type with dropdown multi select checkbox? I'm able to get data using API but when I use checkboxField then it only display the blank checkbox without value. In Model,

    if($result){
        if (isset($result->error)) die($result->error_message);
        //convert json data to array
        $arr = json_decode($result, true);

        //Get project array from API
        $json = $arr['projects'];

        foreach ($json as $i => $v){

            return array_merge(parent::defineAttributes(), array(
                'someField'     => array(AttributeType::String, 'default' => $v['name']),
            ));
        }

And my template,

{% import "_includes/forms" as forms %}

{{ forms.checkboxField({
id: id ~ 'someField',
class:'nicetext',
name: name ~ '[someField]',
value: values.someField,
checked: value,
errors: values.getErrors('someField'),
required: false,}) }}

Need some help. TIA!

A checkbox field is just a checkbox, usually checkboxes don't have several values beside true/false or checked/unchecked, Are you sure you don't want to use a select or multiselect

{{ forms.selectField({
    label: "Some Label"|t,
    id: id ~ 'someField',
    name: name ~ '[someField]',
    options: options, //<-- array [label => X, value => y]
    value: values.someField // <-- not sure what this should be.. usually you want to pass an id
}) }}

However - your PHP actually doesn't make much sense. Not sure what your goal is with that code

Solution:
After did some research in plugin development it worked for me, twig doesn't seem to accept php array so I pass string first and than explode the string with the returned value. Then in template, for checkbox(need to make different checkbox name to make boxes clickable),

{% for check in options %}
{{ forms.checkboxField({
    id: id ~ 'someField',
    class: 'nicetext',
    name: name ~ '[someField]',
    value: check,
    errors: values.getErrors('someField'),
    required: false,
    label: check
}) }}{% endfor %}

and in model,

$result = array();
foreach ($json as $key => $value){
    $result[] = $value['name'];
}
$projects = implode(",",$result);

return  array('someField' => array(AttributeType::Enum, 'default' => $projects),
);


PHPUnit - Warning: "Header already sent" I'm trying to cover the plugin controller with unit tests, but when I try to run phpunit this error shows up:

  Warning: Cannot modify header information - headers already sent by (output started at /craft/app/vendor/phpunit/phpunit/src/Util/Printer.php:172 ) in /craft/craft/app/helpers/JsonHelper.php on line 25

The same error indicates also line 26 and 27 of JsonHelper.php

Did someone already had this issue? Can somebody help me on this?

Thank you very much.

You could try setting PHPUnit's @runInSeparateProcess flag, as discussed here.

However, it sounds as though you're attempting to use PHPUnit for acceptance or integration tests, when it's really designed to be used for unit testing.

A couple of options:

You could mock the JsonHelper::sendJsonHeaders method, but that may prove tricky;
You could use something like Behat for integration testing. This may be more appropriate for a controller.

Stephen

You can run phpunit with --stderr to redirect the phpunit output to stderr.


how to access to event object propereties I want to access for particular information which is contained in event object.

public function init()
{
    parent::init();

    craft()->on('entries.saveEntry', function(Event $event)
    {

        var_dump($event->params['entry']);
    });
}

it dumps info (brining a needed part)

     ......
["_preppedContent":"Craft\BaseElementModel":private]=>
  array(1) {
    ["tweet"]=>
    array(23) {
      ["created_at"]=>
      string(30) "Thu Nov 13 09:15:40 +0000 2014"
      ["id"]=>
      float(5.3282410346476E+17)
      ["id_str"]=>
      string(18) "532824103464763392"
      ["text"]=>
      string(115) "'The innovation insight you didn't get from Forbes' great blog by @LydiaRagoonanan @nesta_uk http://t.co/PImPVvWeAv"
      ["source"]=>
      string(63) "Hootsuite"
      ["truncated"]=>
      bool(false)

How can I extract text, id_str information?
Thanks

I assume both text and id_str are custom fields?

$event->params['entry']

Is an EntryModel, so you should be able to do this:

$entry = $event->params['entry'];
$idString = $entry->id_str;
$text = $entry->text;

It's an array, so:

$entry = $event->params['entry'];
$text = $entry['text'];