Simple webshop solution (Craft Commerce)?

You could use https://snipcart.com/, with the product data populated via Craft fields, for an easy/low-cost solution.

No plugin required for this - although https://superbig.co/plugins/snipcart is in the works for an even tighter integration.

For example see https://www.bernatkleinfoundation.org, here's a screenshot of the product entry used to populate products in Snipcart:


Is it possible to create this type of custom field?

I don't fully understand it. But since modules can quite freely design their fields in the CP, this should be possible with a custom field type.

It sounds to me like a variation of the select field.


How can I access or set a Task's properties inside a class or method?

Have you defined the settings and their type in your Task file?

I've had success using the array of things passed to the task to set the total steps like so:

class RerouteTask extends BaseTask
{

  protected function defineSettings()
  {
    // Files passed from controller
      return array(
        'files' => AttributeType::Mixed,
      );
  }

  public function getTotalSteps()
  {
    return count( $this->getSettings()->files );
  }

Then inside a controller you create the task.

$task = craft()->tasks->createTask('Reroute', 'Importing routes', array(
  'files' => $files
));


Not really the answer you are looking for, but it might be easier to change the tag hidden to a checkbox or lightswitch field and add a condition to the for..in loop, as explained in the twig documentation, which may do what you need and keep the query count lower.

{% for entry in allEntries if not entry.hidden %}
    ...
{% endfor %}


Address form not redirecting to payment form in Craft Commerce

I extended my code to include the billing address and it worked. So I guess the answer to my question is yes, shipping and billing address need to be submitted together.


Contact Form Required Fields Plugin – formEntry error

The plugin expects the the ID of the entry you are using to build the form fields to be submitted along with the form so it is available as a request variable.

You should include the ID of the entry you are using to build the form’s fields when you are submitting to the contactForm/sendMessage controller. For example:

{% set form = craft.entries({
    section: 'forms',
    slug: 'contact-form',
}).first() %}

<form method="post" accept-charset="UTF-8">
    <input type="hidden" name="action" value="contactForm/sendMessage">
    <input type="hidden" name="formId" value="{{ form.id|hash }}" />
    ...
    {# Loop through the form fields here #}
    <button type="submit">Send</button>
</form>

The code above assumes you have a section with the handle forms and the slug of the entry you want is contact-form.

If you want a more robust solution that provides the form builder and validation out of the box, you might consider checking out Freeform from Solspace.


Get the section name based on a url segment

Do you mean

{% set section = craft.sections.getSectionByHandle(craft.request.getSegment(1)) %}
{{ section.name }}


Custom URI to exclude entries in structure

You have the full power of Twig in your template to render the entries Uri so you can conditionally render what you want. This could be your template in your section settings

{% if object.parent.field == true %}{{ object.parent.uri }}{% else %}{{object.parent.slug}}{% endif %}

There are no real limitations since you can do what you are used to in Twig in your frontend


Can I add another filter option to element index views?

I made a small plugin that nests Entry Types under their section in the sources list that might be good enough for what you're after:

https://gist.github.com/mdcpepper/548fd04939e040507960


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

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

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

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

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


Is it typical that data is fetched from within templates rather than in controllers?

From what I've seen so far of Craft and plugins developed for it, the requests are typically forwarded directly to Twig templates and those templates are responsible for analysing query strings and request data and fetching data from exposed template variables or built in "entries".

Not necessarily required.  You can register a custom CP route in your plugin and have a request routed directly to your plugin's controller action.

public function registerCpRoutes()
{
    return array(
        'path' => array('action' => 'pluginHandle/controllerAction')
    );
}

And have that controller render a the template directly, passing in whatever variables it needs:

$this->renderTemplate('pluginHandle/template', array('foo' => 'bar');


How can I relate a FK back to the purchasable ID?

Thanks Brad for breaking it down like that. It helped me take a step back and see what it was I was doing.

Here is the relationship I have that is working:

public function defineAttributes()
{
    return array(
        'id' => AttributeType::Number,
        'packageId' => AttributeType::Number,
        ...
    );
}

public function defineRelations()
{
    return array(
        'element' => array(static::BELONGS_TO, 'ElementRecord', 'id', 'required' => true, 'onDelete' => static::CASCADE),
        'package' => array(static::BELONGS_TO, 'Commerce_PurchasableRecord', 'onDelete' => static::CASCADE),
    );
}

Now I am able to have a relation to the user id element and back to my product package.


Custom validation rules on frontend form

If your validation rules are truly custom and aren't covered by the default Craft validation rules, the only way I can think of getting them into the Guest Entries EntryModel is to fork the plugin and add your own MyPluginEntryModel that extends EntryModel adding a rules method with your custom validation logic.

Read here for more details on that.


Usually I have a {{baseUrl}} defined in config or .env available globally;
then {{baseUrl}}/{{entry.uri}}


Currently nothing native like that. The full list of Craft config settings can be found here.

You might want to consider adding this as a feature request, though!


Is there a safer way to Cycle Through Post Data in Craft

I wouldn't consider it as good practice to do what you want, there are good reasons why something like this is not possible by default and why all functions to get all parameters are private.

A better way is to send your parameters inside an array and fetch this or you can create an array of all possible parameters and loop it

$secureParameters = ['A', 'B', 'C'];
$request = Craft::$app->getRequest();
$values = [];
foreach($secureParameters as $key){
    $values[$key] = $request->getBodyParam($key);
}

If you really don't care about receiving unexpected parameters and raising exceptions you can also loop your $_POST directly foreach($_POST as $key => $v){ and fetch the $request->getBodyParam($key) at least


I'm curious to know your use case for this, but have you tried using Twig's do tag?
https://twig.symfony.com/doc/2.x/tags/do.html
i.e. {% do craft.app.session.set("mySession", "someValue") %}


If anybody is interested, I created a simple unique text field plugin that extends the core text field: https://github.com/fuel-digital/Craft-Unique-Text-FieldType.


There are multiple ways to set the URLs to your files. I don't know if I got your folder structure right. But let's suppose that your web root is set to
/var/www/craft-portfolio/public/,

your CSS folder is
/var/www/craft-portfolio/public/css/

and your Craft folder (actually not relevant) is
/var/www/craft-portfolio/craft/.

Root-relative URL

Root-relative URLs start with a / character.

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

If you are using multiple environments, the path from the web root to your file has to be the same on each environment.
Something like this won't work with root-relative URLs:

http://mysite.com/css/build.css
http://192.168.178.20/projects/mysite/css/build.css

Absolute URL

Add the complete URL of the CSS file to the link tag:

<link rel="stylesheet" href="http://mysite.com/css/build.css" />

You can also use Craft's global siteUrl variable. To do that define the site's URL (http://mysite.com/) in Settings → General in the Control Panel and add the variable to your tag:

<link rel="stylesheet" href="{{ siteUrl }}css/build.css" />

If you want to use the variable in a multi-environment setup, define it in your general.php file (this overrides the CP settings):

return array(

    '192.168.178.20' => array(
        'siteUrl' => 'http://192.168.178.20/projects/mysite/',
    ),

    'craft.dev' => array(
        'siteUrl' => 'http://craft.dev/',
    ),

    'mysite.com' => array(
        'siteUrl' => 'http://mysite.com/',
    )
);

Just be careful if you want to use this on a multilingual Craft site. If you have multiple locales configured, siteUrl will be set to each locale's site URL, which might point to different folders.
You can avoid this by setting a custom variable (eg. baseUrl) in your general.php file:

'environmentVariables' => array(
    'baseUrl'  => 'http://example.dev/',
)

and then use the absolute URL like so:

<link rel="stylesheet" href="{{ craft.config.environmentVariables.baseUrl }}css/build.css" />


How can I manually update the URI of an entry?

For most cases, it should be as simple as updating the slug for that entry to vacancies-1444 on the entry edit page.

This is assuming it's not in a Structured Section and you haven't defined some custom URI rules where the last segment of the URI isn't {slug}.


Trouble getting an asset bundle registered

Because your FooBundle has the classname MyPluginAssetrename your class to FooBundle and it should work (if your namespace is correct, since your information are not really detailed as always)

The docs are not supposed to be a place for copy paste but a source for information.


Issue with Vagrant/Homestead setup (server requirements message)

You can look at server logs and craft logs to begin with. You can also check the browser console.


Is it best to use jQuery for the Ajax-request?`

Not necessarily. jQuery provides an easy-to-use ajax function, but nowadays it's perfectly simple to make an AJAX call with vanilla JS.

  How can I load the "next" five entries in a news-feed, so the call doesn't load the latest five entries over and over?

You will need to pass an offset and limit to your element query, or use Craft's paginate tag, in order to only receive data for one 'page' of elements at a time.

  I've seen that you need to build a specific template for ajax-calls. Is there any good examples of those?

I prefer to use the Element API plugin to serve up my JSON for front-end consumption... but you can also build a JSON feed using a Twig template.

Here are some links that might be helpful:

Basic intro info about AJAX
Tutorial on front-end lazy-loading with Craft ... (site appears offline at the moment, so you can also use a Wayback copy)
Element API plugin, which allows you to easily create a JSON feed of queried elements:
Other answers from SE questions about AJAX pagination/loading


Redactor or another HTML editor that can inherit actual page styles?

The best solution I know of is to install the Control Panel CSS plugin. When you add the css you'll want to target the elements inside Redactor so you don't change the whole Craft CP. For example, add ".redactor-box " before any elements you need to style.

.redactor-box p {
    margin-bottom: 50px;
}


How to render a template from within a module?

You need to include your template roots Enhancing a Craft CMS 3 Website with a Custom Module

public function __construct($id, $parent = null, array $config = [])
{
    Craft::setAlias('@modules/sitemodule', $this->getBasePath());
    $this->controllerNamespace = 'modules\sitemodule\controllers';

    // Base template directory
    Event::on(View::class, View::EVENT_REGISTER_CP_TEMPLATE_ROOTS, function (RegisterTemplateRootsEvent $e) {
        if (is_dir($baseDir = $this->getBasePath().DIRECTORY_SEPARATOR.'templates')) {
            $e->roots[$this->id] = $baseDir;
        }
    });

    // Set this as the global instance of this module class
    static::setInstance($this);

    parent::__construct($id, $parent, $config);
}


Difficult, if not impossible, to do accurately in Craft 2.4.

In the upcoming Craft 2.5, the actual search score is being returned in the results, so you'd be able to take the two arrays, merge and sort them via their score into one result-set.


Charge/Stripe and "Missing required param: exp_month."

I got this resolved by official support.

When using the combined date input you'll need to include the exp_month and exp_year inputs as hidden fields in the form.

And here's the working hidden fields:

  <input type="hidden" name="cardExpMonth" value="" data-stripe="exp_month">
  <input type="hidden" name="cardExpYear" value=""data-stripe="exp_year">


How can I import users from WordPress to Craft CMS?

I don't know how to export users from WordPress, but importing them in Craft can be done with a plugin like Feed Me. There are other plugins out there too depending on the export file you can get out of WordPress.

If you don't know how to export users from WordPress, you'd need to ask that on the WordPress SE if that exists :)


This worked well for me!
Be sure to change directory out of the drive you want to unmount first!
Just to keep it all together here is what you need to do -

sudo nano /etc/wsl.conf

Paste this into the open file -
[automount]
enabled=true
options=metadata,uid=1000,gid=1000,umask=022

Then paste and enter these one at a time into Terminal -

sudo rm /your_craft_path_to/cpresources
cd /var/www
sudo umount /mnt/c
sudo mount -t drvfs C: /mnt/c -o metadata
sudo service apache2 restart

Head to your Craft URL and et voila!


What is the best approach of updating existing Craft installs with new features?

This approach assumes that the individual websites won't diverge from the original blueprint by, for example, modifying sections and fields to suit their specific requirements.

That seems pretty unlikely.

I'd be inclined to stick with the idea of creating a "blueprint" site, to get new websites up-and-running quickly, but ditch the idea of updating previously-created sites whenever the blueprint is updated.


How do I force Craft to regenerate assets transform?

If you simply go into your craft_assettransformindex table and empty it, that should trigger brand new transformations for everything.


How does Craft handle uploading assets to AWS?

They are uploaded to Craft first to a temporary file, then Assets uses the Asset Source to work out where to send them next - either the local file system or a remote one.

For handling large uploads in general you could look at this plugin: https://superbig.co/plugins/large-upload


You can do this using the twig attribute function:

{% set data = [
    {'column':'1','title':'Quick Facts'},
    {'column':'2','title':'Inspiration'},
    {'column':'1','title':'Agencies'},
    {'column':'2','title':'Industry Experience'}
] %}

{% set cols = {} %}
{% for item in data %}

    {# create a dynamic property if one doesn't exist #}
    {% if not attribute(cols, 'col' ~ item.column) is defined %}
        {% set cols = cols|merge({ ('col' ~ item.column) : [item.title] }) %}

    {# else update the dynamic property with the new title #}
    {% else %}
        {% set titles = attribute(cols, 'col' ~ item.column) %}
        {% set titles = titles|merge([item.title]) %}
        {% set cols = cols|merge({ ('col' ~ item.column) : titles }) %}

    {% endif %}
{% endfor %}

{{ dump(cols) }}

{#
array(2) {
    ["col1"]=> array(2) {
         [0]=> string(11) "Quick Facts"
         [1]=> string(8) "Agencies"
    }
    ["col2"]=> array(2) {
        [0]=> string(11) "Inspiration"
        [1]=> string(19) "Industry Experience"
    }
}
#}


Getting current entry element via plugin in Craft 3 without a hook

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 :)


Is it possible to convert string to uppercase?

The upper filter is what you are looking for:

{% set var = 'Hello World' %}

{# Print in UPPERCASE #}
{{ var|upper }} {# 'HELLO WORLD' #}

Besides upper there are also some other filters available to modify the capitalization style of your strings. Of course there is the lowercase equivalent lower and additionally there are some Craft exclusive filters available.

  {# Set test strings #}
  {% set strLower = 'this is a test string' %}
  {% set strUpper = 'THIS IS A TEST STRING' %}
  {% set strMixed = 'this Is a TEST stRing' %}

  {# Apply Twig filters #}

upper: {{ strLower|upper }}
 {# 'THIS IS A TEST STRING' #}

lower: {{ strUpper|lower }}
 {# 'this is a test string' #}

  {# Apply filters provided by Craft #}

ucwords: {{ strLower|ucwords }}
 {# 'This Is A Test String' #}

ucfirst: {{ strLower|ucfirst }}
 {# 'This is a test string' #}

lcfirst: {{ strUpper|lcfirst }}
 {# 'tHIS IS A TEST STRING' #}

  {# Combine filters for predictable application #}

ucwords: {{ strMixed|lower|ucwords }}
 {# 'This Is A Test String' #}

ucfirst: {{ strMixed|lower|ucfirst }}
 {# 'This is a test string' #}

lcfirst: {{ strMixed|upper|lcfirst }}
 {# 'tHIS IS A TEST STRING' #}

  {# Examples for possible use cases #}

PascalCase: {{ strMixed|lower|ucwords|replace(' ', '') }}
 {# 'ThisIsATestString' #}

camelCase: {{ strMixed|lower|ucwords|lcfirst|replace(' ', '') }}
 {# 'thisIsATestString' #}


How can I install Craft Commerce 2 alpha release?

You have to contact P&T (at support@craftcms.com) directly to get installation instructions.


I believe you're looking for the aptly named autoLoginAfterAccountActivation config setting.


Charge 2 form that has multiple one of plan amounts?

check out the docs here - http://squarebit.co.uk/software/craft/charge/usage/reference/payment-options and note this bit:

  planIntervalCount accepts int The number of periods for a recurring
  plan. If you're creating recurring charge, this is required, and must
  be 1 or higher. Not including, or passing a 0 value will create a
  one-time charge.

So, you could do

<input type="hidden" name="planIntervalCount" id="planIntervalCount" value="0"/>

for a one off payment.


Logged in admin, can't see front end site when system is off

I resolved this by adding a redirect to get rid of the www. The issue was my admin would be www but the front end wasn't.


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


This seems more like a jquery issue then a craft issue. You might look into jquery's load method. Doing a quick google search I came up with this possible solution, which you would need to adapt.

function callIframe(url, callback) {
    $(document.body).append('<iframe id="myId" ...>');
    $('iframe#myId').attr('src', url);

    $('iframe#myId').load(function() {
        callback(this);
    });
}


Intercept all requests before a Controller Action is executed

You're correct about both beforeAction() and onBeginRequest().

However, you could put an init() method in your main plugin class file and this will execute on every request as long as the plugin is installed and enabled.

public function init()
{
    // Whatever code you were going to put in onBeginRequest can go here.
    parent::init();
}


live and pending entries together not working

Use status(['live','pending']) to get all entries with both states.

Later, to get the linked entry you need to setup a custom route like `podcasts/{slug}. In the template you query the entry like this:

{% set slug = craft.request.lastSegment() %}
{% set entry = craft.entries.slug(slug).status(['live', 'pending']).one() %}


Create order programmatically in Craft Commerce

First of all, it's important to know what version(s) of Craft and Commerce you're referring to. The code used in this answer applies to Craft 3, with Commerce 2-beta. Code for Craft 2 and Commerce 1 would look different, but the logic is similar.

I would start by looking at Commerce's codebase on Github (or in your plugins folder, if it's Craft 2), and more specifically the OrdersController, and even more specifically the actionSaveOrder and _setOrderFromPost methods.

It looks to me like you need to do two things:

Get an Order model:

// Find an existing order by ID
$order = Commerce::getInstance()->orders->getOrderById($orderId);

// ... Or create a new one
$order = new Order; # Don't forget to place use craft\commerce\elements\Order above your class

Populate the model (untested)

If you have an order model, you have to populate all the fields that matter. Status, addresses, I think you'd best start on an individual order page in the admin to see what fields are needed.

$order->isCompleted = true;
$order->billingAddressId = 4;
$order->gatewayId = 7;
... etc (includes creating and adding line items for your order)

Save the order and show why it doesn't work magically the first time around ;)

This is where the fun starts, which might depend on your definition of fun.

if (!Craft::$app->getElements()->saveElement($order)) {
    var_dump($order->errors);
}


Set fields from two different Matrix blocks, merge them and then set the output in a pretty way

I think your problem might be that you're overwriting the metaDescribe variable on each iteration of your for loop at the end of your first example. Given that you know you'll only be dealing with two blocks, you could try replacing the loop with something like this:
{% set metaDescribe = artNameMat[0].artistName ~ ' ' ~ '(' ~ artNameMat[0].birthDeathLocationDate ~ ')' ~ ' ' ~ artNameMat[1].materials ~ ' ' ~  artNameMat[1].dimensions  %}

[Aside: it may also be worth revisiting your content model, as it sounds a little convoluted! Investigate the possibilities of moving some pieces of content out into dedicated sections or category groups and using relationships to tie everything together.]


I would use a combination of things:

Twig's replace filter to convert ä to ae etc.
Twig's convert_encoding filter to eliminate any remaining non-ascii characters
Craft's kebab filter to do its thing

and of course wrap the thing up in a macro

{% macro ascii_kebab(s) %}
  {{ s
    | replace({
        'ä': 'ae'
      })
    | convert_encoding('ASCII', 'UTF-8')
    | kebab
  }}
{% endmacro %}


I'm not sure if that's possible since I never used Sproud Forms but you can easily create a custom field type with the additional validation rule.

Create a Plugin you can use Pluginfactory.io for that and install it
Create a new Field
Just extend the basic AssetsFieldType

class myNewAssetField extends AssetsFieldType{

}

Take a look at the default validation rules for BaseElementFieldType

public function validate($value)
{
    $errors = array();

    if ($this->allowLimit && ($limit = $this->getSettings()->limit) && is_array($value) && count($value) > $limit)
    {
        if ($limit == 1)
        {
            $errors[] = Craft::t('There can’t be more than one selection.');
        }
        else
        {
            $errors[] = Craft::t('There can’t be more than {limit} selections.', array('limit' => $limit));
        }
    }

    if ($errors)
    {
        return $errors;
    }
    else
    {
        return true;
    }
}

Copy the function above in your new class and include something like this somewhere

foreach ($value as $assetId){
    $asset = craft()->assets->getFileById($assetId);
    if($asset->size >= 10){ // insert your size here
        $errors[] = Craft::t('Your file is too large');
    }
}

It took me about 5 minutes to create this new field type to allow the validation of file sizes

If you want to make it look pretty and create a setting to dynamically set the individual max file size for each field you can include the function getSettingsHtml in your new class and change add your new value (for example maxSize) you can then grab the new size with $this->getSettings()->maxSize


Try replacing {id} with {slug}. I guess it needs a slug, not an ID.


I recently dealt with a similar issue. Keep your tasks small and quick by using subtasks or by creating multiple instances of your main task. In your example, make each entry creation its own tasks or subtask, so that each step only has one process to take care of. You can have a private array on the task object to store an array of entry data to iterate through.

private $entry_data = array();
//Fill array with the data you want to use

public function runStep($step)
{

    $new_entry = $entry_data[$step];
    //code to create new entry

    return true;

}


Craft Commerce: fixed product variants/multiplier

I'm not sure if the base cost is global across all products, or varies between products - but either way you could use an Adjuster module or plugin to modify the price of line items in the cart.

That way you don't need to worry about creating any variants in the backend at all, and can store the price multipliers in Global fields if you want to.

To my knowledge there aren't any plugins that do this, but don't be put off my the thought of creating a plugin/module, I'm not much of a developer but have managed it myself : )

This proof-of-concept Adjuster gist should set you in the right direction, and here's another one for good measure.


I ended up fixing this with a variable and querying it myself.

In this case I needed the related entry if it was linked and a false if it wasn't.

$neoElement = craft()->db->createCommand()
    ->select('craft_relations.sourceId')
    ->from('relations')
    ->where('craft_relations.fieldId = 110')
    ->andWhere('craft_relations.targetId = :entryId', ['entryId' => $entry->id])
    ->queryColumn();

if(!empty($neoElement)) {
    $parents = craft()->db->createCommand()
        ->select('craft_neoblocks.ownerId')
        ->from('neoblocks')
        ->where('craft_neoblocks.id = :neoElementId', ['neoElementId' => $neoElement[0]])
        ->queryColumn();

    if(!empty($parents)) {
        $entry = craft()->entries->getEntryById($parents[0]);
        return $parent;
    }
}

return false;


Looking for a simple way to add/update information records with CraftCMS

Based on the information in the comments I'll provide an example how to save elements in Craft. I'll just show an example with an existing element type Entry. You can see how to create a custom element type well documented in the docs

You'll create a new section in your CP and add the required fields to the layout. In your case you'll need title (Booktitle), author (BookAuthor), summary (BookSummary) and pages (Pages)

// get the section and the entrytype
// when you know your section id and entrytype id you don't
// need this. You can get the Ids by looking at the URL in the
// when you edit them
$section = Craft::$app->sections->getSectionByHandle('books');
$entryType = reset($section->getEntryTypes());
// Create an entry
$entry = new Entry([
    'sectionId' => $section->id,
    'typeId' => $entryType->id, // or insert the required type id manually
    'fieldLayoutId' => $entryType->fieldLayoutId,
    'authorId' => 1,
    'title' => 'A cool title of a book',
    'slug' => 'a-cool-title-of-a-book', // <- not required
]);

$entry->setFieldValues([
    'author' => 'Me and Myself',
    'summary' => 'it was awesome',
    'pages' => 9000
]);

// Save the entry
Craft::$app->elements->saveElement($entry);

// in case there is something wrong..
$errors = $entry->getErrors();

When you are going to create your custom element type without a field layout your code could look like this

$book = new Book([
    'title' => 'A cool title of a book',
    'author' => 'Me and Myself',
    'summary' => 'it was awesome',
    'pages' => 9000
]);
// Save the entry
Craft::$app->elements->saveElement($book);

// in case there is something wrong..
$errors = $book->getErrors();


How do you add a core twig extension in plugins using addTwigExtension()?

The Twig extension package is not included with your Craft install. So you need to download it and add it to your Craft plugin manually.


A structure is a section that allows for a 'tree' like layout with hierarchy. A good example of where Structures might be used for instance is the Craft documentation pages, or building a navigation using a section.


Add user to entry user field [RSVP to Event]

You could do this:

<form method="post" accept-charset="UTF-8">
    {{ csrfInput() }}
    {{ actionInput('entries/save-entry') }}
    {{ hiddenInput('entryId', event.id) }}
    {% for user in event.eventAttendees %}
        <input type="hidden" name="fields[eventAttendees][]" value="{{ user.id }}">
    {% endfor %}
    <input type="hidden" name="fields[eventAttendees][]" value="{{ currentUser.id }}">
    <button type="submit" class="btn btn-primary">RSVP</button>
</form>

The for loop in there is to ensure that you do not remove any value (users) that have already RSVP. This is similar to Uploading Files from Front-End Entry Forms


Commerce - how to display order address in email to customer?

Sounds like order.shippingAddress is all you need!

{% set orderAddress = order.shippingAddress %}

{{ orderAddress.firstName }}
{{ orderAddress.lastName }}
{{ orderAddress.address1 }}
{# ...etc! #}


The Matt's answer was pretty complete and worked almost, but for the benefit of others, there is the changes required files to make it works:

in integration.php

find

define('SET_SESSION_NAME','');

change for

define('SET_SESSION_NAME','CraftSessionId');

and make your getUserID functions look like

function getUserID() {
            $userId = 0; // Return 0 if user is not logged in

            if ( $_SESSION[ 'craftUserId' ] )
            {
                $userId = $_SESSION[ 'craftUserId' ]; // Set this session variable in a Craft plugin
            }

            return intval( $userId );
    }

and in a Craft plugin, add this to a init() function

public function init()
    {
        craft()->on('userSession.onLogin', function(Event $event) {
            $currentUser = craft()->userSession->getUser();
            craft()->httpSession->add( 'craftUserId', $currentUser ? $currentUser->id : null );
        });
   }

If you want to be full-padded, you can also add something to unset your CraftUserId variable onLogout event, but I don't think it's needed.

Thanks a lot to Matt and Brad who helped me out on Easter day!


If your Redactor config included an "html" value in the "buttons" array, you can remove that, and add a "source" value to the "plugins" array instead.

https://craftcms.com/help/redactor-ii-configs


You could use this variable to get the template name: {{ _self.getTemplateName() }}

Put it at the top of all your template files:

<!-- {{ _self.getTemplateName() }} -->

And then for every template called it should have the commented out template name.

In Craft 3, there's a nice plugin called "Template Comments" which is great for this... But I don't see a version for Craft 2.


It should be a string:

{% for entry in craft.entries({ section: 'news', limit: 2, id: 'not 42' }) %}

so concat your variable like so:

{% for entry in craft.entries({ section: 'news', limit: 2, id: 'not ' ~ this_id }) %}


Can random be used for ordering with related/assets, in cached code?

What about composing a custom Twig array containing all the data you need. This does all your DB queries and because you write it in default sort order (randomize afterwards), you can cache all the heavy lifting of your template:

{# Cache an array of fake "ElementModels" #}
{% cache %}

{% set imagesArray = [] %}
{% set tagsColor = [] %}

{% for image in craft.assets %}

    {% for tag in image.tagsColor %}

        {% set tagColor = {
            slug: tag|slugify,
            tag: tag,
        } %}

        {% set tagsColor = tagsColor|merge(tagColor) %}

    {% endfor %}

    {% set imageObject = {
        url: image.url,
        title: image.title,
        tagsColor: tagsColor,
    } %}

    {% set imagesArray = imagesArray|merge(imageObject) %}

{% endfor %}

{% endcache %}

Then randomize your images and print the JSON:

{# Randomize our array #}
{% set imagesArray = shuffle(imagesArray) %}

{# Print the thing into our JSON #}
{% for image in imagesArray %}
    ...
{% endfor %}


The answers to your questions will inevitably be, that it depends, however I have tried to present examples of situations that may help clarify things a bit further.

  Does creating a single job with 10,000 steps use more resources than creating 100 jobs with 100 steps?

Each queue job is stored as a row in the queue database table. If a job had 10,000 steps and needed to store a unique piece of information about each step, then the amount of data stored in the job column (a LONGBLOB) could be very large. Fetching, storing that large blob in memory and working with it would require more resources than working with smaller blobs one at a time. If part of the job execution involved fetching and working with 10,000 elements, then again that would require more resources than working with smaller collections of elements. So in theory, creating multiple, smaller jobs would take longer to complete but would be less prone to the memory and/or time limit being exceeded and the job failing.

  If breaking things out into batches makes sense, what is a reasonable batch size for modifying Elements using a job?

If you want to account for queue jobs that are run through the browser (in addition to through CLI commands) then you should try to avoid allowing a job to exceed the memory limit at all costs. However, since the memory limit can be different on every environment (Craft 3 requires at least 256MB of memory allocated to PHP) this can be difficult to do. 100 feels like a conservative batch size but again, it depends on how many resources the job requires.

What I have done in the Campaign plugin is added a block of code to each iteration in the job that checks whether the memory used by the current job (memory_get_usage(true)) and the time that has passed since it was requested (time() - $_SERVER['REQUEST_TIME']) are nearing the respective limits. If they are then I create a new job, give it a delay, add it to the queue and stop execution of the current job. That means that the SendoutJob can continue sending emails indefinitely and without a fixed limit, until it detects that the job is close to failing. Setting a delay on the new job allows the current request to end without failing and the new job will be executed the next time the queue is run. Here is the relevant code:

// If we're beyond the memory limit or time limit or max batch size has been reached
if (memory_get_usage(true) > $memoryLimit || time() - $_SERVER['REQUEST_TIME'] > $timeLimit || $count >= $batchSize) {
    // Add new job to queue with delay
    Craft::$app->getQueue()->delay($settings->batchJobDelay)->push(new self([
        'sendoutId' => $this->sendoutId,
        'title' => $this->title,
        'batch' => $this->batch + 1,
    ]));

    return;
}

Note that $memoryLimit and $timeLimit have been set to thresholds lower than that of the server (source).

  Would the need to do different actions lead to a different answer? For example, would the same recommendations hold for modifying Elements and deleting Elements?

If you decide to set a fixed limit then it would make sense that it should probably be lower for resource intensive jobs. If the completion of the job is critical then you might consider implementing a similar approach to the Campaign plugin's SendoutJob, which is not perfect but has worked well in the field.

If this is a distributed plugin then the best you can do is try to avoid jobs failing and communicate to your users what they can do to avoid it, as described in Robust queue job handling in Craft CMS.

See also: How to prevent "Failed" errors in job scheduler in Craft CMS 3?


If you use make your section a Structure, it will allow a hierarchy of entries.

See the docs on section types to learn more about the different types of sections in Craft.


Craft Commerce payment gateway: general info requested

How far does Craft Commerce go when a user puts an order?

When an order is paid in full it is marked as complete and gets a default order status that you can configure, after that a store admin would move the order to another status.

An order can also be completed if the payment gateway 'authorizes' the full amount of the order, allowing a store admin to 'capture' that payment at a later time.

But does it handle cancelations or order credit notes?

Cancellations of an order are a manual process. You would usually perform these steps:

Refund the transaction
Change the order status to a status you set up like 'cancelled'.
Have an email automatically go to the customer notifying them of the cancellation based on the order status.

Or does Craft Commerce quits when the order is created?

Not sure what you mean here, but you can manage the order in the CP after the order is completed.

Magento has some sort of built-in bookkeeping, but how far does Craft go?

Craft Commerce does not keep any type of accounting ledger, it simply allows you to manage order and take payments on those orders. Most developer build a custom sql query to export data to their accounting system.

What gateway is best for global/international payments?

Craft Commerce allows a single store with a single currency for all prices entered into that store for products / discounts / taxes etc.

You can have your products be manually translated for other regions since they are multi-locale aware.

Craft Commerce does have the ability to accept payment in currencies other than your primary currency so that your customer gets charged in a currency they expect to show up on their credit card statement - but you control the conversion ratio yourself.

It would be best to find the right payment gateway to use that supports the currencies/global regions for payments and then find out the level of support for that gateway in Craft Commerce. We always suggest Stripe.

Hope that helps.


There's a chance that one of your plugins is causing this behavior. Go into your craft_plugins table, and change the value of enabled to 0 for every single plugin.

If your Settings page is then accessible, cautiously re-enable each plugin one-by-one. This will help you hone in on which plugin may be causing the problem.


You need both because there is no way to define custom validation rules from defineAttributes().

Ultimately things like 'maxLength' => 14 in defineAttributes() automagically get normalized down to the $rules array that gets returned from the rules method, so you're just appending your custom rule onto that when you call:

$rules = parent::rules();
$rules[] = ['email', 'Craft\MyPlugin_EmailValidator'];


How do you save custom fields along with the user/saveUser action?

Got it, just need to use the getContent() function exactly the same as entries:

$user->getContent()->setAttributes(array(
    'postCode' => 'SO23 9UG',
));


To generate the url, use the slugify plugin: href="{{tag.name|slugify}}". Slugify uses Craft's slug technology, so the slugs are always recognized by the router.

To resolve the url back to a tag, use search in the news/_tag template:

{% set thisTag = craft.tags.search('name:"'~tag~'"').first() %}

craft.tags.name(tag).first() will often work, but not for all slugs, so this is also possible, and may be more efficient if that is an issue:

{% set thisTag = craft.tags.name(tag).first() %}
{% if not thisTag %} {% set thisTag = craft.tags.search('name:"'~tag~'"').first() %} {% endif %}


Seems like the only option at the moment is to follow this post's technique:

Prevent Asset Transforms from scaling Image past 100%

Hopefully it will be implemented in the CP in the future... according to this feature request:

https://plus.google.com/110881688132908256910/posts/FAzrGAJ99W7


When viewing an entry, click the arrow on the save button and you'll see an option to "Save as new entry". This duplicates the entry and you can immediately begin editing the new entry.

I'm not sure if this is what you mean by "use one article as template for the others" or not. It seems you can either manually create a new entry and then copy and paste content, or use this method.


How to merge multiple 'relatedTo' queries via query parameters

I figured it out with help from https://craftcms.stackexchange.com/a/5339/7356

This could probably be further refined but...

  {# Get query parameters from URL #}
  {% set colour = craft.app.request.getQueryParam('colour') ?? null %}
  {% set range = craft.app.request.getQueryParam('range') ?? null %}
  {% set texture = craft.app.request.getQueryParam('texture') ?? null %}

  {# Tee up the product query #}
  {% set queryParams = [colour, range, texture] %}
  {% set hasValidQueryParams = false %}
  {% set relationParam = ['and'] %}
  {% set query = {
    type: 'fabric',
    limit: 999,
    orderBy: 'defaultSku asc'
  } %}

  {# Store any valid query parameters #}
  {% for param in queryParams %}
    {% if param != null %}
      {% set hasValidQueryParams = true %}
      {% set relationParam = relationParam|merge([{targetElement: craft.categories.slug(param) }]) %}
    {% endif %}
  {% endfor %}

  {# Merge query parameters into the main product query  #}
  {% if hasValidQueryParams %}
    {% set query = query|merge({relatedTo: relationParam}) %}
  {% endif %}

  {# Display the result  #}
  {% set swatches = craft.products(query).all() %}
  {% for swatch in swatches %}
    {% include 'range/_fabric_swatch' with { 'visible': true } %}
  {% endfor %}


How should one go about using Craft with Git? [not duplicate]

Have a look at the project config feature in craft 3.1, it generates a yaml file describing all developer created data, e.g. fields, sections etc. which can be stored in GIT. However this does not save user created data e.g entries.

https://docs.craftcms.com/v3/project-config.html

Also look at migrations; php scripts to create schema / data in DB. (Which can be stored in GIT) Migration Manager plugin will auto generate them for you

https://docs.craftcms.com/v3/extend/migrations.html

https://packagist.org/packages/firstborn/migrationmanager


How to use a plugin to add own fields, values, forms,...?

I'll try and cover as much as I can:

Can you please point to some (working?) sample of implementing a barebone default / dev setup (css, js, basic templates, custom fields, groups, users, matrix forms, front-end forms,...) using a plugin?

I don't think there would be anything where this is implemented with a plugin (unless i'm mistaken), but P&T have an installation of Craft you can either clone on Github or generate from their website called HappyLager, this contains a bunch of boilerplate to you get you started including sections, entry types, matrix fields, relations, assets.

I don't think there is anything with users on there though due to licencing, Craft personal only allows one user and Client 1 Admin and 1 Client account : http://buildwithcraft.com/pricing

Generate a site for you to log in to: https://demo.buildwithcraft.com/
Download the Repo and install it to your own server: https://github.com/pixelandtonic/HappyLager

Is there a way to "enforce" presence (installation and activation) of "related" plugins ("must use" plugins) so I can develop a theme with functions/features related to other plugins I do not own?

There is sort of a way to do this I believe, you would need to have a set of dependancies you could define as an array in your main plugin class, then when your plugin's CP/settings page is loaded, do the checks through a controller to see if the correct plugins are installed and proceed with notifications, errors when conditionals are met etc.

An example of a plugin i've seen that has done this is the Twitter plugin from Dukt, its free so you should be able to download it and find what you need. TwitterPlugin.php is where the logic is (from what I can see) then controllers/TwitterController.php to put it all together and then  templates/settings/_dependancies.html is how it's dealt with in the front end.

https://dukt.net/craft/twitter

It might be worth having a read about plugin development: http://buildwithcraft.com/docs/plugins/introduction

But I think in your themes readme, a simple list of required plugins with links on how to get them would be good enough for most situations.

In craft I don't get the point / simply don't understand where to start just to add custom fields and relations

This should be solved or become apparent in the HappyLager demo? if not the documentation is quite helpful with this:

http://buildwithcraft.com/docs/sections-and-entries
http://buildwithcraft.com/docs/fields
http://buildwithcraft.com/docs/relations

I also don't see how I could use a plugin to create a theme / copy the related files and have them "managed" by my plugin.

I think the problem with building a theme is there are so many factors involved with regards to how someone might have their backend set up (if retro fitting a theme) as you if you had something like craft.entries.section('news') in one of your templates but the section is called blog your theme isn't going to work.

For a clean install your problem might be with licensing, I'm not an expert on it by any means so if anyone else knows more information please edit this answer, but I would assume you would need to be careful how you add sections and users at the least.

Your plugin could generate sections on it's install, it could even generate users but I would probably check with Craft directly with this or read their license to be sure, but the methods to create such things are there in the internal API, you could take a look at the full class reference to see whats going on and whats available: http://buildwithcraft.com/classreference

With regards to template files, you can change the location of these file, see Custom template location, but I don't think you can get your plugin to do this, unless i'm mistaken.

As for theme files etc you could have a set directory structure when people install your theme and then use something like the File class to interact with these files http://buildwithcraft.com/classreference/etc/io/File

I hope that helps you get off to a start with building on Craft


Issue Importing Data to Matrix Fields With FeedMe Plugin

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


Sprout forms internal server error after migration

It sounds like you're missing some necessary Sprout Forms files.  Maybe they weren't FTP/copied over to the new server properly or if you're deploying from Git, maybe there was a gitignore rule that they got caught up in.

If you enable devMode, you'll probably get an error message on the front-end.

Regardless, I'd grab a fresh copy of the plugin and replace the existing craft/plugins/sproutforms folder with the new one.


Feedme plugin - importing users into craft commerce

Users will be imported without passwords. Would this provide some kind of security risk, for example, someone being able to log in with empty password?

I don't think the imported users will be able to login at all without a password.

Setting new passwords for users - would I need to write custom module to send password reset form to each imported user? Would not sending 5000 emails at once choke Craft - maybe I should use tasks for that?

I handled this by setting a message on the login and forgot password pages, skipping the need to send an email. Something like "Our systems were upgraded on 10-20-2020, if you've not logged in since then you'll need to reset your password first".

Addresses - do i need to write some custom plugin for importing adddress data along with basic user data like email? I didnt saw any fields for setting up user address when i tested importing users using feedme. Did someone managed to tackle this issue in the past?

Yes, you will need to use a custom module/plugin and listen to feedme events and handle address import with your code.
Something like:
 Event::on(Process::class, Process::EVENT_STEP_AFTER_ELEMENT_SAVE, function (FeedProcessEvent $event) {
   /// your code here dealing with $event->feedData;
});


Here's how I'd do it...

Create a channel called Allergens with a custom field for the icon. If the icon is an image, make it an assets field.
Create a channel called Ingredients with a custom field for the allergens. It will be of the Entries field-type and only allow the user to select Allergens entries.
Create a channel called Recipes with a custom field for the Ingredients and another custom field for the description of the dish. The Ingredients field will be of the Entries field-type and only allow the user to select Ingredients entries. The description field would probably be a simple Rich Text field.
Create a channel called Menu. If there is only one menu needed, I'd probably make it a Single. If more are needed, make it a standard channel. It'll need a custom field for the Recipes, which would be an Entries field where the user can only select Recipe entries.

There are other ways of doing it, but this would probably give you the most flexibility in the long run, and keep things simple for the users.


This seems to have fixed the issue.

{% if reldata %}
    {% set tag = craft.tags.title(reldata|join(', ')) %}
    {% set feat = craft.entries.section(data|join(', ')).relatedTo(tag).limit(8).all() %}
{% else %}
    {% set feat = craft.entries.section(data|join(', ')).limit(8).all() %}
{% endif %}


Replacing content a specific URL/page already reserved in Structured Data Entries

First off, for communication reasons, let's refer to the "Structure" as a section, not a page type. Anytime you create either a Channel or Structure section, you have the ability to create what are called "entry types".  You will see them listed on the far right of Settings > Sections in Craft.

The Solution in a nutshell

In your case, you will want to create a new Entry Type in your Structure to accommodate this custom deviant page, which will allow you to choose different fields for that type and its own template for its own custom code.

What is an "Entry Type"?

Ok, so what is an Entry Type?  You know when you go to post a status on facebook and you have the ability to just write text, or you could choose to upload an image, or you might want to check in?  All of these different types of status posts may share the same fields (like the text field to post your status), but some have additional or completely different fields (like uploading an image), but they are all "Status Posts" to Facebook, just different types of status posts.  This is a very over-simplified example, I know, but it's kind of what Entry Types in Craft are for a Channel or Structure.  They're like an inherent built-in category group that allow you to design different custom field layouts for different types of entries within that one Channel or Structure.

So if you make a Structure called "Generic Pages", you could then create different entry types in that Structure like "Single Column", "With Sidebar", "Top Banner", etc, and they can all get their own custom field setup with their own templates.  Or you could just use one template for them all. I've created Events channels before using things like "Event", "Concert", "Party", "Meetup", etc as the different types.  When I create a new entry in the "Events" channel, I then choose which type of event it is, and by doing so, I'm able to customize which type gets which fields.  They all have a "Start Date" field, but maybe the "Concert" type has a "Door Price" field, whereas "Meetup" doesn't. This way you don't have a confusing "Door Price" field for "Meetup" events that shouldn't be or don't need to be filled in.

Templating

Ok, so how do we handle this in the templates? When you create the section in Craft, you'll point to whatever template you want for the section as a whole (let's say /generic-pages/_entry for example).  In that _entry template, add just this line:

{% include "generic-pages/" ~ entry.type %}

Then inside the /generic-pages/ directory, you create a different template for each entry type you made in Craft.  Name that template exactly how the handle looks like.  So if you made a "Single Column" entry type and the handle is singleColumn, then "singleColumn.html" is the name of your template.  Customize that template all you want.

Here's a proper article on Craft's site talking about this method:
https://craftcms.com/support/entry-type-templates

Even if you're using one template for all entries in this Structure/Channel regardless of entry type, you can still be selective with how you grab your entries like:

{% set entries = craft.entries.section('genericPages').type('singleColumn') %}

Or be conditional based on type:

{% if entry.type == 'concert' %}
    // do something
{% endif %}

Read more about Entry Types in the Craft Docs: https://craftcms.com/docs/sections-and-entries#entry-types


Based on your description, this should do it:

{% if entry.style|length %}

Related Posts

            {% set styleCategory = entry.style.first() %}
            {% set relatedEntries = craft.entries.section('news').relatedTo({
                targetElement: styleCategory,
                field: 'style'
            }).id('not '~entry.id) %}
            {% for relatedEntry in relatedEntries %}

{{relatedEntry.title}}

            {% endfor %}

{% endif %}

A few notes:

– I've wrapped the whole "Related posts" in a conditional testing if the entry.style categories field is not empty (if entry.style|length).

– Personal preference, but for readability's sake I find its usually a good idea to be specific/semantic with variable names (e.g. styleCategory instead of just category, relatedEntries instead of entries etc).

– The targetElement and field attributes for the relatedTo() parameter are not required – you could just do .relatedTo(styleCategory). Being specific is a minor performance win and avoids wrong results if you have multiple relations involving the same elements.

– The id('not '~entry.id) prevents the current entry from being returned


Save Entry Data as CSV and Email it to the Author / Logged in User

For this purpose there is not such a thing like a "best" way. Every thing has advantages and disadvantages. Depending on your goal you should decide what fits best for you.

I personally prefer to have my files attached to the email so I can be sure I actually have the file on every device and I can redownload it every time. Other people might say it's better to just have a link for whatever reasons.

So I would create a temporary file and attach it to the mail like you do. Make sure to name each file separately. If you have really large entries (that need more time to generate the csv) and two authors click the button at the same time they could eventually overwrite each other. So it might be a good idea to include the author ID or something in the filename. You can delete it afterwards.

If you want to keep these files you could store them as Craft assets but i don't think this is necessary for your purpose. You could create a record if you like to track the activities. So if you need to see how many authors used that download how often you can insert it into your database.

However, the more interesting thing is how to fetch the entries and fields.
Btw you know you have to parse the body content in order to replace the twig tokens?

Edit
You could use this function

 /**
 * Send Email
 *
 * @param $message string
 * @param $subject string
 * @param $mail string
 * @param array $attachments
 * @return bool
 */
public function sendMail($message, $subject, $mail, $attachments = array()){
    $adminEmail = craft()->systemSettings->getSetting('email', 'emailAddress');
    $email = new EmailModel();

    $email->fromEmail = $adminEmail;
    $email->replyTo = $adminEmail;
    $email->sender = $adminEmail;
    $email->fromName = craft()->getSiteName();
    $email->toEmail = $mail;
    $email->subject = $subject;
    $email->htmlBody = $message;

    if(is_array($attachments) && count($attachments)){
        foreach($attachments as $attachment){
            $email->addAttachment($attachment['path'], $attachment['name']);
        }
    }
    return craft()->email->sendEmail($email);
}

with

$attachment = [
    [
        'name' => "The name you want to display.csv",
        'path'  => $file // path/to/your/file
    ]
];

$subject = "Your CSV";
$email = $user->email;;
$message = craft()->templates->render('path/to/template', array(
    'username' => '...',
    // .....
));
if($this->sendMail($message, $subject, $email, $attachment)){
    // message send
}else{
    // some errors
}


How to show if a user is logged in to control panel

Check out the MN Snitch plugin. It probably comes the closest to what you're looking for.


I'm basing this response on the incomplete statement {% set image = craft.assets.filename('').one() %}.

To get an asset named the same as the SKU of a Product's default Variant, try this:

{% set exampleImage = craft.assets({
    filename: "#{myProduct.defaultVariant.sku | lower}.*"
}).one() %}

This does a couple things:

Collapses the transformation of a product into a search string using Twig's string interpolation, and the filter you'd applied;
Appends .* to match all extensions (optional, but recommended, in the event you have some PNG, JPG, and JPEG images in your library);
Executes the query and returns a single Asset Element or null.

Always check you have results before attempting to access properties of your image:

{% if exampleImage %}

{% endif %}

I think the original problem you were encountering was that (by default) the filename query parameter matches strictly, meaning that your SKU would need to be the complete filename in order to be returned. You can view the fuzzy-matching syntax/options in the Asset Query documentation.

With respect to the overall structure of the code, I'd recommend an approach like this:

{# First, look for an attached image: #}

{% set image = myProduct.productImage.one() %}

{# If there wasn't one, try looking in the Asset library: #}

{% if not image %}
    {% set image = craft.assets({
        filename: "#{myProduct.defaultVariant.sku | lower}.*"
    }).one() %}
{% endif %}

{# We might still be missing an image. If so, fall back to fetching a specific one: #}

{% if not image %}
    {% set image = craft.assets({
        id: 9225
    }).one() %}
{% endif %}

{# Ok, now we're guaranteed to have one of the above images—we can safely use `image` the same, regardless of where it came from: #}


Where to store asset backups for plugin?

The only thing that Craft guarantees to be writable is craft/storage (and to a limited extent, craft/config).

But, 99% of things in craft/storage can and will be rebuilt as needed depending on the request, even if the entire folder has been nuked.

You can either work within that context, save your assets as blob's in the database (would not recommend) or in your plugin's installation instructions, make sure that you specify they create a craft/plugins/pluginHandle/writable folder you can save your asset revisions to.


Issue is resolved, as @bradbell said the version for ImageMagick module and library was old and need to be update. You can check the latest relase from here: https://www.imagemagick.org/script/changelog.php

From some servers apt-get update won't really update the package. So you need yo install manually. There is a great how to article regarding this


What are the risks of using Gmail for sending email from Craft CMS?

It's mostly tongue-in-cheek, I think.

When sending emails from Craft using Gmail, Craft uses SMTP, which Gmail considers "insecure", hence the reason they make you enable the "less secure apps" from your Google account.


Digital Ocean: Dev + Production Droplets

Does the license allow this if I don't map a domain to it and operate it as an IP address OR use an obscure term (staging etc.) in a odd domain (vs. sub-domain as mentioned in docs)?

Yes. As far as I'm aware, Pixel & Tonic consider a development site to be any non public domain.

  Is this a feasible approach?
  Is there a better (noob-friendly, learnable) way to do this?

Lumping these 2 together since they're directly related.  This question and subsequent answers  might help you out as well as Craft's own list of resources.

It really depends on what you want to learn. When you spin up a droplet or other virtual machine, there's a lot of moving parts there. You'll be dealing with a lot of server management and not necessarily Craft development. It's easy to go really deep down the rabbit role and come out with a lot of (depending on what you seek out) useless knowledge. If you're just tinkering around, you probably want it as hands-off as possible.

Instead of paying for 2 droplet instances, you could spin up a virtual machine locally, like Virtualbox or something prebuilt like Laravel's Homestead. A droplet is also on the internet, thus a "public" server, so unless you want people hacking your instance, you'll want to secure it down. That just adds another layer of complexity.

Virtual machines are great solutions but they're also overkill usually. I find the easiest approach is to develop locally and use something like MAMP and then push it to staging and/or production servers. You don't need to worry much about the nitty gritty of permissions, firewalls, etc.


The Users field uses the username for the display label by default when showing what users have been selected.

My guess is you've got the useEmailAsUsername config setting set to true?


Schoolboy error alert!

I had the wrong field in my news entries. There was a category field set up which had the same values as the sector names. Once I'd replaced the field with the proper one it all worked as expected!


Craft queue not being processed, listen not running

You will need to investigate the log files to determine the source of the problem. There should be a storage/logs/queue.log file. This article might be helpful https://nystudio107.com/blog/zen-and-the-art-of-craft-cms-log-file-reading


How to add a button or format style in Craft 3 CKEditor (rich text field)

I asked the question on the Slack channel & got my answer. Thank you @kenyonkowal.

The best way to customize your rich text editor is to use Redactor instead of CKeditor.

You need to add a config file to the config folder, i.e. config/redactor/basic.json and then in that you would put

{
"formatting": ["p", "h2"],
"buttons": ["formatting", "bold", "italic", "underline", "link", "ul"],
"toolbarFixed": true
}

You can edit add or remove a lot more, here's a link to the documentation:
https://imperavi.com/redactor/docs/


Complete user profile after social public registration

Via https://dukt.net/craft/social/docs/templating/craft.social#getLoginUrl you may give up a page like { redirect: 'user/finish' } on which you could check if a user agreed to the license agreement and if they have redirect them to the regular page.

Here is an example profile edit page that might be useful https://github.com/dukt/social-demo/blob/master/craft/templates/social/profile.html


Javascript 'hack' in browser console:

$lightswitches.each(function(){
    var lightswitch = $(this).data('lightswitch');
    lightswitch.turnOff();
});


Use blog index template as category template

Yup, you can totally re-use the same template. When it is a category page, you will have access to a category variable which is a CategoryModel, and you can use that to filter your entries by category.


How do you manage master db across multiple environments?

See carlcs' comment. What's the best practice for handling data migration and organization across development environments? is one of the biggest discussions on this S/E.


See here for how to add a field to a user's field layout.

Users, Globals, Tags, Categories, etc. are all elements in Craft so they behave very similarly.

You can also check out Craft's own InstallService's private _createDefaultContent() method for examples on how Craft creates the default content on a fresh install of Craft.


How to programmatically update a plugin's settings?

It's not 100% clear from your question, but I'm guessing that by "update the settings" you mean actually storing the new settings in the database, which the setSettings() method will not do; it will only update your plugin's settings model. This means that any following calls to e.g. getSettingsHtml() should return the updated data, but it will not persist.

To store the new settings in the database, you'll need to use Craft's PluginService:

craft()->plugins->savePluginSettings( $this, array( 'spriteDefs' => $this->getSpriteDefs( $url ) ) );

The $this variable in the call above refers to an instance of BasePlugin – meaning that the above code will only work if called from your plugins main class. I notice that your code is contained within your plugin's init() method, so you should be fine, however if you ever want to update a plugin's settings from outside the main class (e.g. through a service), you would first need to fetch an instance of the plugin:

$myPlugin = craft()->plugins->getPlugin( 'myPluginHandle' );
craft()->plugins->savePluginSettings( $myPlugin, $settings );


Your best bet is going to be to write your own field type for this. You can extend one of the built-in field types if you want.

You would put your custom validation logic in your field type’s validate() method.


You can do something like this (with lots of refactoring possible):

{% set thisYear = now | date("Y") %}
{% set startYear = thisYear - 1 %}
{% set endYear = startYear - 4 %}

{% set yearRange = startYear..endYear %}

<select name="">
{% for year in yearRange %}
    <option value="{{ year }}">{{ year }}</option>
{% endfor %}
</select>


How do I pull the first image from the first entry of the first subcategory?

This should work!

This code is to pull the first image, from the first entry of the first sub category given that the 'slug' passed into the first set is your top level category.

    {# Get the category from the slug. This will return one CategoryModel #}
    {% set topCat = craft.categories.slug('someSlug').first() %}

    {# Get the first subcategory under the top level category using the getChildren() method on the category model.  #}
    {% set firstSubCat = topCat.getChildren().first() %}

    {# Grab the first entry under that category using the relatedTo function and appending the .first() method to return only one item. #}
    {% set firstEntry = craft.entries.relatedTo( firstSubCat ).first()  %}

    {# Set your image from your asset field #}
    {% set image = firstEntry.assetField.first() %}


Different templates for different entry types within a section

Sounds like you're looking for something like this: https://craftcms.com/support/entry-type-templates


How do I display a list of assets with the entries they are related to?

You probably have to query a new ElementCriteriaModel for each asset in your loop and use the relatedTo parameter to filter the relevant "content" entries.

You could use the targetElement property with the relatedTo parameter to be more spezific on that relation. But you should be fine using the element property or the short syntax relatedTo(element), if you don't do any (reverse) relations (e.g. with an entries field as an asset meta field).

Tested this on an install with 400 images and yes, you want to wrap it in cache tags!

{% set content = craft.entries.section('content').find() %}
{% set usedFotos = craft.assets.relatedTo(content).order('filename').find() %}

{# Loop throught the array of assets #}
{% for usedFoto in usedFotos %}

{{ usedFoto.filename }}

        {# Loop throught entries related to this asset #}
        {% for entry in craft.entries.relatedTo(usedFoto).order('title') %}

{{ entry.title }}

        {% endfor %}

{% endfor %}


Get related posts excluding current post in Craft 3

To exclude the current post use the current post's id with a "not" clause in the id query param.

{% for relatedPost in craft.entries.relatedTo(entry.newsCategory).id('not ' ~ entry.id).limit(5).all() %}


I figured this out:
{% set token = craft.app.tokens.createToken(["preview/preview", {"elementType": "craft\\elements\\Entry", "sourceId": 123, "siteId": 1}]) %}
Preview

Make sure sourceId and siteId are set correctly.


How do I configure Varnish to work with Craft?

Ok, Carlo, I'll get in this improved answer tonight, anyway, probably cut down and informate the other answer in morning here, so comments stay. I've got a sick animal here house-sitting for brother & family, why I'm a little slow.

To accelerate what you have, it really depends on the content - whether you have logins or other personalization among your high ten-thousands of daily hits. If you don't, it may be possible to get some quick improvement, and then move up through the other things. Throughout this I'm going to be thinking of a big sports site I've seen you have, thinking it may have timely content updates while not personalization; but I don't remember it with assurance on that detail.

Digging into CloudFlare, since you do have it there on EC2, I find I was mistaken about what it does before you may configure it. This also explains some things I thought I saw in earlier brief shakedown tests myself.
With automatic, stock configuration, CloudFlare only edge caches media referred to, like jpgs, js, css etc. -- not html of any kind, to keep things safe for first users. There are three further levels of caching possible, which includes the ability to do whole pages. You use PageRules to enable this, and can for a whole site depending on the match filter. If you don't have personalization, I think you could get a huge benefit right away by setting this up, rather than using Railgun. Or for some pages, anyway? So this is what I'd look into first, if the content fits. CloudFlare doc link here. You can set time to live, so as to have essential static pages which still update regularly if you have timely but not personalized content.
If you have personalization of pages, then you do indeed need server-side caching to rein in such large page demands, I would agree. Railgun working as intended is only going to help with cutting out handshake latency, compressing, and so forth. This is great, but it still requires that you run the (Craft) CMS each time someone requests a page, in order to see if there is a delta Railgun would send.

The next stage then I would think would be to enable Craft's own caching, to cut  Craft's overhead way down, as this is very effective, targetable to what should and shouldn't be cached in your site, and can use EC2's ElastiCache, w/doc link here, to get you memory-resident caching's speed. Craft's /app/etc/config/defaults has scripts for both Redis and Memcache(d) setup, which I think you just copy into your /craft/config folder once the facility is up on your EC2 machine.

With fortune, this could be an easy solution to deal with, again if you need to have personalized or otherwise dynamic content, and you can try it out for gain before any ElastiCache by just turning it on in the file or db modes, for which there are also default scripts in the same location.

I'd read very carefully the information that's in Victor In's link reference, as it gives quite a bit of information straight from Brandon (and with others' interpreting) compared to present doc. I agree with what he says about effectiveness of  using db caching from experience before, as databases tend to have very efficient caching for their own operation, including sorting out high numbers of requests. What he says about the db as basis for the great effectiveness of Craft's detailed cache breaking with content updates is also very astute, and one of those things which makes Craft very intelligent with how it handles your content.

What about Varnish, then? Well, it does look very powerful and proven; also requiring the most detail of any speedup to configure. Setting it up in the first place is simple; you just set your webserver to run on a non-visible port, and tell Varnish where to find it while arranging Varnish to handle your visible standard http and possibly https ports. That installs the engine, as in their pretty good-looking Varnish doc with a kind of guide on this link.

I don't remember if EC2 comes with a C compiler installed, but easy to do, and this will be necessary to compile the VCL scripts you configure Varnish with to know your page requirements. VCL itself? Again, there's good doc, but you are really going to want to know exactly what your pages need, if they need personalized results. This is really about the site design, not anything about Craft itself, and here we are considering the original question directly.

In summary, I think that depending on your content, you have three levels you can go through here to reduce load and increase apparent speed for your site.

If you are so fortunate as to have non-login and otherwise non-personalized content, you can probably do the large arrangement by configuring CloudFlare to actually edge-cache the html pages as well as media content. This will give you essentially static site page speed, also hosted out near many visitors (if you're lucky on CloudFlare sites), plus having off-loaded your page request handling out to those edge sites. Using embedded monitoring may keep you lucky on getting enough access data to satisfy the client.
If your client needs logins or personalization of other kinds, then one of the levels of Craft caching (and selection of what to cache) is going to help a lot. This would really take advantage of Railgun, while feeding it the information it needs very efficiently for your EC2 instance(s). This might be enough, and might see Railgun operating as you'd expect it to reliability-wise. Again, you could start with a file- or db- level Craft cache configuration, and then after working up redis or memcached on a staging server probably, fitting that in for even higher efficiency and speed.
Varnish itself, then. I seem to feel this would be the most effort to configure, but if needed, give the highest effectiveness, if you need to go that far. The configuration itself is about your static vs. dynamic page content design, not Craft itself, so you can use such sources as stackoverflow's varnish tag to get hints or questions answered on it. Here's a link to an interesting start for that, mentioning relationships between varnish and memcached in the frame as I've put some thoughts here. ElastiCache-driven native Craft caching will give you the highest performance for necessary dynamic content here, and it looks like Railgun will improve on Varnish alone, by getting that fast-resolved dynamic content out to the edges in much less time than a standard internet request would do so.

Carlo, hope it's been helpful to have another head looking at this, and that possibly these stages in some form may give you ideas to do a useful rapid response, then refine. Craft community advancing on many fronts at the moment, anyway ;)


How do you wrap text with HTML within a Plain Text field?

You can use the raw Twig filter. Try this:

{{ product.name | replace({'®': '<sup>®</sup>' })|raw }}


How do I output all field values from a Category on the current entry?

If you have a Categories field on your entry called myCategoryField, you can check if it has any Categories selected by going:

{% if entry.myCategoryField | length %}
    There are categories selected!
{% endif %}

If you want to loop through all of the selected categories for that field, you can do:

{% if entry.myCategoryField | length %}

        {% for category in entry.myCategoryField %}

{{ category.title }}

        {% endif %}

{% endif %}

For more info you can read more in the templating section of the Categories field's documentation.


You can't use entries from the control panel in other control panel fields without the use of a plugin. The only plugin I'm aware of that does this is https://plugins.craftcms.com/craft-dynamic-fields.
Depending on the use-case, which I don't totally understand, you might look at using an Entries or a Categories field too if you just want to relate an entry to another entry.


Is it possible to create a field group that can be modified across entry types?

No, field groups are just a way to have your fields grouped in the field layout designer and fields index page. Another advantage is the possibility to drag a whole group in the designer to create a new tab.

Approaches, other than a max 1 Matrix field you mentioned, that I can think of are:

multiple predefined rows in a Table field
multiple predefined rows in a Set Table field, which allows you to have a read only "Label" column and set a max rows
custom solution implementing a new field type that has multiple input fields


Animated GIFs not working in Craft with ImageMagick installed

I ended up applying this configuration to config > general.php so GIFs aren't transformed.

'transformGifs' => false

https://docs.craftcms.com/v3/config/config-settings.html#transformgifs


CraftCMS with Cloudfront Full Page Delivery

That's the dream, isn't it? CDN everywhere, no database hits, etc. How "static" is your site? Unlike other CMS, the great thing about Craft is that you can store information everywhere and pull it out anywhere. That gets to be dynamic content problem nightmare unless you're very diligent about knowing what will happen, for example:  "updating this page will also update content on the home page, the blog index, related white papers section, author archives, etc".

Let' say you update the title of one of your main areas that's also part of your navigation: Services becomes Products for example. Now you have to invalidate every single page.

So it can get complex quickly but if you have a very simple site, obviously, the above doesn't apply.

One way to pull this off would be to create a subdomain, like admin.whatever.com. Your admins would login to this URL. As far as Craft is concerned, it'll serve up on whatever domain you need, you just need multiple environment config.php and template trickery.

In your template files, check for the server name.

{% if craft.request.serverName is not "domain.com" %} {% reqireLogin %} {% endif %}

This will prevent non-logged in users from trying to accesses the admin pages, otherwise Craft will serve up your non-CDN on that domain to anyone who hits it (which is not something you want to have happen generally).

Unlike something like WordPress where it actually stores URLs in the database, Craft uses reference tags and builds up the URL on the fly so you generally don't have to worry about relative vs absolute URLs.

The hardest part of this is going to be the cache invalidation. Unlike static files, where you can just upload a new file with a different filename on the CDN to invalidate them, pages are much different. To make matters worse, it can take up to 10-15 minutes for that invalidation to happen on Cloudfront.

I use nginx here for static/microcaching and it works pretty well but the idea is the same. I can share some code I use to invalidate its cache but basically you want to create a plugin that listens on entries.SaveEntry and then tell CloudFront to invalidate the cache after it's saved. Something like:

public function init()
{

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

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

        if ($entry->url && $entry->enabled) {

        $url = $entry->url;

            try {

                 // do CloudFront stuff here
                if (!$response->isSuccessful()) {
                    return;
                }

            } catch (Exception $e) {
                // something happened.
            }

        }
    });
}


Can I manage/change the default flash message text?

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

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


Outputting Matrix blocks with grouped values based on Entries field id

Try something like:

{% set breadGroups = entry.breads | group('bread.first.id') %}

{% for breadId, blocks in breadGroups %}

    {% set sum = 0 %}

    {% for block in blocks %}

        {% set sum = sum + block.quantity %}

    {% endfor %}

    Total qty for Bread ID {{ breadId }}: {{ sum }}

 {% endfor %}

The group filter consumes a list — in this base, an array of Matrix blocks — and produces an array of arrays where the key is the grouping parameter, and the value is an array of items from the original list for which the group criteria matches the key.

c.f. Craft docs: http://buildwithcraft.com/docs/templating/filters#group


How do you pull a entry field in a global out in a template

You can access and loop the entrie in any template like so:

{% for entry in globalSetHandle.entriesFieldHandle %}
    {{ entry.title }}
{% endfor %}

If you want to change the sort order to show the most recent blog post first use the relatedTo parameter:

{% for entry in craft.entries.relatedTo(globalSetHandle).order('dateUpdated desc') %}
    {{ entry.title }}
{% endfor %}


Events calendar for Craft - which one should I use?

I haven't used Venti, so I can't comment on it. However, I have tried out both Calendars from Top Shelf Craft and Solspace Calendar on a recent project.

I started out using Top Shelf Craft Calendars (Solspace Calendar hadn't been released at this point). However, during the project, I switched to Solpsace Calendar which has ended up being used on the final build.

In my view, Craft Calendars and Solspace Calendar have distinctly different approaches as to how they work.

Top Shelf Craft Calendars

In Craft Calendars, any element (entries, users, assets, etc.) can be attached to a calendar event. If you want to store custom fields associated with an event, then you would store these on the element you are attaching to the calendar event, not on the event itself.

In this way, you can think of Craft Calendars as creating a specialist fieldtype which enables you to schedule events, either on a one-off basis, or using sophisticated recurring rules. So to create an event, it must be associated with another element, since the event date is set using the Event Dates Fieldtype on the host element, rather than creating an event directly on a calendar element.

Craft Calendars doesn't currently have a nice GUI for the control panel and the front end output and styling are also left to you. This means that there is no native way to see an overview of the events that have been created. This may or may not be important to you.

Solspace Calendar

On the other hand, with Solspace Calendar, events belong to a calendar first and foremost. There is an Events Fieldtype which can be used to relate another element (entries, users, assets, etc.) to a specific event using native Craft relations.

Events can also have their own custom fields. However, at the moment it is is not currently possible to search for Solspace Calendar events based on the contents of their custom fields. You can only search for events based on 'native' Solspace Calendar attributes, such as calendar name, start date, end date and author (see the docs for full details).

The control panel GUI for Solspace Calendar really shines and is very easy to use. It is based on Full Calendar, a JavaScript event calendar JQuery plugin. Solspace provide sample front end templates using Full Calendar, so it is fairly quick and easy to get a similar system up and running on your site.

The Full Calendar interface, plus the ability to have events that weren't associated with existing elements, were the main factors in my choice of Solspace Calendar for the project I used it on. Though at the time I developed it, Solspace had not yet released their Full Calendar front end templates and there was little support for calling the event creation controllers from the front end, I was able to work through their code to see how they had achieved it in the control panel and create what I needed for the front end of my site.

However, it wasn't an easy choice between the two so I completely understand the motivation behind your question.

Comment on development and coding style

I have spent a lot of time looking through the code for both plugins and Solspace Calendar in particular. From a development and coding point of view (if that matters to you), Craft Calendars seems to me to follow Craft coding conventions more closely.

Solspace seem to have introduced extra levels of complexity and abstraction into Calendar that, in my opinion, for what it's worth, make it more complicated that it perhaps needed to be and lose some of the native behaviour you would get if they had used a more 'Crafty' approach. I have noticed this before with some of their EE add-ons. That said, they were very responsive to all the bug reports and questions I raised with them during the active development of the project.


Q: Freeform - have users update form on the frontend

I was able to find a solution. It's probably not the best way to go, but it works.

In the form add a new action: <input type="hidden" name="action" value="freeform/submissions/save"> which will override the standard action. It's the same form action Freeform uses to save entries in the CP.

Then add the id you want to update as value=.
For example:
<input type="hidden" name="submissionId" value="{{submission.id}}" />

One disadvantage is, is that this POST does not support the handle, values,.. input data for the fields - you need to use the fields id. So
<input name="{{ firstName.handle }}" value="{{ firstName.value }}" >
becomes
<input name="field_1" value="{{submission.FirstName}}" />

You can find the field id in the CP. Some fields might need a bit more info, like email is field_3[].


Misconfiguration error when accessing URL without file name

On some servers you might need to add in general.php

'omitScriptNameInUrls' => true

See https://craftcms.com/docs/config-settings

Hope that helps


Enabling Assets Image Edit Option for Assets in Amazon S3

The issue was with Imagik configuration. GD worked fine.

I fully remove Imagik, and reinstalled with it with default settings.

brew remove php71-imagik && brew services restart php71


Does your shipping method have any conditions set? Like a country or region? I think getAvailableShippingMethods() takes into account your shipping address (if any) and only shows shipping methods that apply to the current shipping details.

Second thing to check: does your shipping method have at least one shipping rule? Commerce needs a shipping rule to be checked against your order.


Updating matrix field from font-end with $entry->setFieldValue() pulls in Cp bundle on save

Turns our it was this line causing the issue:

'collapsed' => true,

Removed it and all works as expected.


Sprout Email conflicts with Craft Contact Form

This issue has been resolved in Sprout Email 3.

Be sure to read the upgrade notes. This is a major release and some scenarios may require a few manual steps to get updated.


Instead of slug try using * in your route definition


EmailService now has Twig render email messages in safe mode

OK so it's pretty easy to pass additional variables to the email template using the email.onBeforeSendEmail event:

craft()->on('email.onBeforeSendEmail', function(Event $event)
{
    $event->params['variables']['craft'] = new CraftVariable();
});

Although I guess there are security reasons for email templates being rendered in safe mode in the first place so I don't know how much of a good idea this is...


Avoid notice of variable's not being set within dev mode

I've had luck using "is defined" before using other logic operators.

This should do it:

{% if entry.title is defined and entry.title | length == 0 %}
    {% set entry = craft.entries.section('sectionname').slug(craft.request.segment(2)).first() %}
{% endif %}


Plugin (SyncDB) issue breaking site and unable to do anything

It seems like the easiest way to address this issue is to remove the dependency from your composer.json file and to then run

composer update


No, Craft will not be able to generate JPGs from SVGs out of the box (I tested it), but it should be relatively easy to write a plugin handling it.

As GD doesn't support SVG, ImageMagick support is a must. Craft actually does use ImageMagick, if its installed on your server – so your first step would be to check for ImageMagick support. An easy way to do that, is to use Craft's ImagesService.

From there, the actual PHP code generating the JPG should be relatively straight-forward – check this Stack Overflow thread for a concise example (not tested the mentioned code myself).

Note: Be advised that Craft actually implements all of its image manipulation through the Imagine library – I'm pretty sure Imagine would handle the generation, but if you need to work with ImageMagick directly you could do

$factory = new \Imagine\Imagick\Imagine();
$svg = $factory->open( $path );
$imagick = $svg->getImagick();

Finally, when it comes to implementing the JPG generation you have a few options – for example you could create a Twig filter:

You could also implement it as a template variable method:

...or you could even hook into AssetsService events if you needed to generate the fallback automatically.

Updated answer: The original question asks if "image transforms can be modified to handle this". The short answer is no – ideally there would be a beforeTransformApplied hook or something like that, but as of 2.3 there isn't (see this thread for reference). My opinion is that your best bet is creating a variable method or Twig filter, as outlined above.


Combine .htaccess. ( http to https AND www to non www AND remove trailing slash ) extending normal craftcms .htaccess

Update 12/06/2018:

Tested now succesfully following version on my server

# Redirect www to non www
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]

# Redirect http to https
RewriteCond %{HTTPS} !on
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

# redirect /bla/ to /bla
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [R=301,L]


First Craft website: how to organize different content

I'll try answer each question as best as I can... Feel free to ask for more information if you still have questions.

First: For your use case, it might indeed by a good idea to put all actual pages in 1 structure, it allows you to better visualise the content structure. You can than pull in the required news, locations, jobs content with corresponding fields.

Second: It depends on how many pages you'll have, if you put it all in one big structure, and you have to many pages in there, you might loose the overview. From what you lined out, I'd put it in 1 structure, and you can still use different entry types if you need different content.

Third: Singles are ment to be one-off pages, mostly with a specific design, but yes, pages for registering, logging in are excellent candidates for singles. Once you'll use the fields or design on it more often, you might be better off putting it as an extra type in a section.

Specifically for Jobs, if those are again their own set of entries (I'd put them in a channel) you can use jobs/index.html as template for your overview page (assuming you specified jobs/_entry as path when registering the section).

Fourth: It all depends on how much the content itself will vary between posts, press and media. IF you'll need a different set of fields, you'll be better off creating different entry types. If however they'll all follow the same set of fields, you can work with categories to differentiate between the different pages.


504 error on home page of Craft 3 website

This is kind of hard to debug without any logs, but because 504 is a gateway timeout error, I would start by checking if your site uses any external services, other servers it tries to reach (only from within your templates, because the admin works fine).

This could be anything from Google's geolocation API to an external image service, that can not be reached because of server settings on either side.

Is there anything in your server logs, or could you activate logging for your server to get more details?


You could write a simple plugin, that exposed an anonymous controller action that mimicked Commerce's Commerce_DownloadsController's actionPdf() method.


Generating responsive images from cropped source file

Here's what I've ended up with:

{% macro srcset(image, maxCssWidth, maxCssHeight, includeDimensions) %}
{%- spaceless %}

    {# Is this a 2X image? #}
    {% set is2x = image.is2x %}

    {# Determine the CSS width for the image, if it were output at 100% #}
    {% set cssWidth = (is2x ? round(image.width / 2) : image.width) %}

    {# Determine the image size that 1X screens should get #}
    {% set width = (cssWidth > maxCssWidth ? maxCssWidth : cssWidth) %}
    {% set height = maxCssHeight %}

    {# Determine the image size that 2X screens should get #}
    {% set width2x = (width * 2) > image.width ? image.width : (width * 2) %}
    {% set height2x = (height * 2) > image.height ? image.height : (height * 2) %}

    {# Output the srcset= attribute value #}
    srcset="{{ image.getUrl(image.width != width ? { width: width, height: height, mode: 'crop' }) }}, {{ image.getUrl(image.width != width2x ? { width: width2x, height: height2x, mode: 'crop' }) }} 2x"

    {#- Output the width= and height= attributes if needed #}
    {%- if includeDimensions %} width="{{ width }}" height="{{ image.getHeight({ width: width }) }}"{% endif %}
{% endspaceless -%}
{% endmacro %}


Get query string param that has no value

A parameter with no value set returns an empty string '' for craft.request.getParam(). But if the whole parameter is not included at all, it returns null.

This means you can test for null (→ see Twig docs) like so:

{% if craft.request.getParam('myparam') is not null %}
    My Parameter is included in the query string!
{% endif %}


Overriding a structure section's template for a single structure entry

I think my answer here should provide you with exactly what you need, as well as an elegant and reusable way to do it:

How can I route a specific entry in a structure section to its own template?


How is Craft able to reuse fields in different Sections? (As opposed to EE.)

In Craft, all fields are stored in the craft_content table. They are otherwise independent of any field groups, layouts, sections, or anything else.

PRO: This means that any element (Entry, Category, Asset, etc) can access any field.

CON: This means that every element carries the weight of every field. Though if those fields are all empty, the performance impact is almost non-existent.

There's historically been some minor debates over whether or not this tradeoff is worth it... But I think it's safe to say that the benefits vastly outweigh any negligible performance issues. The simple fact is, having all fields in the same table is rarely (never?) the true bottleneck.


Email Before Membership / Subscription Renews via Charge / Stripe?

Developer of Charge here.

While it's not a feature that's currently supported out the box with Charge, it is something that's on the FR list, and is something I'm looking at adding.

If you drop me a line directly I can talk over some of the options with you.


What's the differences between the Mailer and the Message classes?

They're both valid options.

$message->send() is a wrapper for Mailer:

https://github.com/yiisoft/yii2/blob/master/framework/mail/BaseMessage.php#L41-L50

It will take an optional Mailer parameter.  If one is not passed it, it will default to the default Yii/Craft::$app->mailer and ultimately just call send() on it.


How to show a product from a field entry

This should work:

{% set image = block.chooseProduct.first().mainProductImage.first() %}

Explanation:
your field handle in your product is called recommendProduct (matrix) that contains a relation chooseProduct. Your block.chooseProduct is an object of type ElementCriteriaModel so in order to fetch the product you need to call the first() method (or something similar). So if you have multiple products in your chooseProduct field your code would look like this

{% for block in product.recommendProduct %}
{% set i = i + 1 %}

       {% for relatedProduct in block.chooseProduct %}
            {% set image = relatedProduct.mainProductImage.first() %}

{{ relatedProduct.title }}

       {% endfor %}

{% endfor %}


The approach you described is interesting and should actually work. Separate root folders would allow you to define the template folders individually (→ see Ben's answer on how to set this up), but it looks like that's not what you need and your subdomains are more part of one and the same site.

Even with multiple root and template folders you could still include shared template partials, but sharing CSS, JS and assets would be troublesome. But, then again, more easy to have these individually for each subdomain.


Edit meta property value in Open Graph meta tag

Right now, SEOmatic assumes an og: namespace for all OpenGraph tags, which clearly isn't correct. So you'd just need to add these tags yourself if you want to use them.


Translate filter and nested vocabulary properties

Not currently.  Might be worth a feature request, though?


This sounds like a mod_security issue.

You'll need to reach out to whoever manages your server and ask them to relax the security around saving data to all URLs under your /admin URL area.

What is happening behind the scenes is that the security on your server thinks that you may be trying to query the database and do something malicious. i.e. SELECT * FROM craft_users;


Craft 3: query matrixBlocks and eager load its owner?

Currently no, but I suppose since Craft 3 added the craft.matrixBlocks() template function, it would make sense to make this possible.

Just created a FR about this: https://github.com/craftcms/cms/issues/1820