You're so close it's maddening—you should be able to order by a custom field as well:

{% set assets = craft.assets.find({sourceId: 2, order: 'date desc'}) %}

Where date is the name of your custom field.

From the Craft docs (emphasis added):

  Possible values include 'title', 'id', 'sourceId', 'folderId', 'filename', 'kind', 'width', 'height', 'size', 'dateCreated', and 'dateUpdated', as well as any textual custom field handles.


Is there a way to remove the admin panel logout timer?

The duration of the session can be extended via userSessionDuration in your Configuration

'userSessionDuration' => 7200


Query a subselection of Sales and Discounts

While this may not be the best solution, here is a working example for anyone else who has a similar problem (pure twig).

The saleContainsOtherProduct variable is an indication that the sale did NOT match the criteria of only related to product type so in order to check for only related, use not saleContainsOtherProduct.
Additionally, this only lists sales, but the code within the loop will work for discounts too, so just repeat with a for loop on craft.commerce.discounts.getAllDiscounts()

{% set ignoredProductTypes = ['bundles'] %}
{% for sale in craft.commerce.sales.getAllSales() %}
    {% set saleContainsOtherProduct = false %}
    {% set purchasables = [] %}
    {% for id in sale.purchasableIds %}
        {% set purchasable = craft.commerce.purchasables.getPurchasableById(id) %}
        {% if purchasable.product.enabled %}
            {% set purchasables = purchasables | merge([purchasable]) %}
        {% endif %}
    {% endfor %}
    {% for id in sale.categoryIds %}
        {% set category = craft.categories.id(id).one() %}
        {% for product in craft.products().relatedTo(category).all() %}
            {% if product.enabled %}
                {% for purchasable in product.variants %}
                    {% set purchasables = purchasables | merge([purchasable]) %}
                {% endfor %}
            {% endif %}
        {% endfor %}
    {% endfor %}
    {% for purchasable in purchasables if purchasable.product.type.handle not in ignoredProductTypes %}
        {% set saleContainsOtherProduct = true %}
    {% endfor %}
{% endfor %}


Craft 3 - Moving assets between folders causes apache connection to max out

I would remove the overhead of the CMS all together by using an app like Filezilla, Cyberduck or similar app to move files. There are plenty of tutorials out there on how to connect to an S3 bucket using one of these apps (eg. https://stackoverflow.com/questions/45293159/how-to-setup-filezilla-pro-to-access-to-my-s3-bucket)

After you do this you will most likely need to update your asset indexes in the control panel:

Utilities → Asset Indexes (or Settings → Update Asset Indexes if you're on Craft 2)


Contact form: Twig_Error_Runtime error upon submission

The problem was that the redirect page was not setup. Once I threw up a test page there, the error no longer triggers.

What's odd is that the error page gave little clue (at least to me) as to what was happening.


Overriding native CP template (without hacking the core)

Unless I'm mistaken, it looks like you don't actually need to override that whole template. It sounds like you really just want to add a column (or multiple columns) to the assets index view.

The modal that you're showing is using the same logic as the main assets index view. So it's simply a matter of adding your own custom columns to that, and then selecting those columns to be included.

The defineAdditionalAssetTableAttributes hook allows you to create new columns for your assets index. You'll still need to select those columns via the UI in the control panel (which is super easy).

You'll probably also need to use the getAssetTableAttributeHtml hook, which allows you to customize how your column's data is displayed.

Using both of these hooks together will allow you to add whatever additional columns you'd like to the asset index view. And once you've selected your new custom columns, the exact same columns will appear in the modal view (like in your screenshot).


Bumping into max row size of 65k craft_content table in MySQL 5.5

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

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


How to run function after plugin installed?

There's an event you can listen to:

use craft\events\PluginEvent;
use craft\services\Plugins;

        // Handler: EVENT_AFTER_INSTALL_PLUGIN
        Event::on(
            Plugins::class,
            Plugins::EVENT_AFTER_INSTALL_PLUGIN,
            function (PluginEvent $event) {
                if ($event->plugin === $this) {
                    // Do stuff here, we were just installed
                }
            }
        );

If you generate your plugin scaffolding via pluginfactory.io it will generate the above event for you in your base plugin.


Database driver & version after server upgrade

MariaDB is a "drop-in" replacement for MySQL and Craft/PHP/PDO treats them as identical 99.99% of the time.
Craft gets the information about which database/version is being used directly from PDO and since there isn't a specific MariaDB PDO driver, the MySQL is used and that is what is reported back.


How do I get an empty table field type to display on the front-end so a user can update their profile?

As far as I know, I don't think that there is any built-in way to replicate the table fieldtype functionality on the front-end (i.e. with 'add row','remove row', etc.) I think that you would have to create your own buttons and then manipulate the dom using javascript.

In your template you would want something like this:

Provider Credentials

    {% for row in currentUser.providerCredentials %}

            Institution
            <input type="text" class="name-field" name="fields[providerCredentials][{{ loop.index }}][col1]" value="{{ row.accreditingInstitution }}">

    {% endfor %}

Add row

And in your javascript file:

$('.add-row').on('click', function(event){
    $(this).preventDefault();

    var rowCount = $('.js-providerCredentials').children('tr').length,
        newRow = '
Institution	<input type="text" class="name-field" name="fields[providerCredentials][' + (rowCount+1) + '][col1]" value="">
';

    $('.js-providerCredentials').append(newRow);
})

Not sure how your table is set up exactly, but the principle should be the same. For another example of how to format the dom for form submission see the answer to this question,  editing a table field type from the front end.


Check out my plugin Inlin, I made it exactly for this. :)


How to get all users with active Commerce 2 subscription

I solved this by creating a simple plugin.

use craft\db\Query;

class MyPluginVariable
{
      public function allActivelySubscribedUserIds()
      {
           $subscribedUserIds = (new Query())
                ->select('userId')
                ->from(['{{%commerce_subscriptions}}'])
                ->distinct()
                ->all();

            // Create array of just user IDs
            $subscribedUserIds = array_column($subscribedUserIds, 'userId');

            return $subscribedUserIds;
       }
 }

I my case I needed to display all entries authored by users that are currently subscribed. In my template I used the variable like this:

{% set subscribedUserIds = craft.MyPlugin.allActivelySubscribedUserIds %}

{% set entries = craft.entries()
    .authorId(subscribedUserIds)
    .all()
%}


Redirecting certain 404s to a page, handling all others as normal

You could also set up a route for news/{slug} to point to your news template, and have it do the check to see if the entry in segment_2 is valid, and do something based on that.

I did something like this for my "members" pages:

 {% set thisProfile = craft.users.id(craft.request.segment(2))[0] %}

 {% if not thisProfile %}
    {% redirect siteUrl %}
 {% endif %}


Retrieving featured entry from a given category

There’s currently a bug with storing keywords based on related elements, which we’re looking into. Using the search parameter for this isn’t really the right way to go anyway, though.

Instead you should be using the relatedTo param:

{% set entries = craft.entries.find({
    section:   'news',
    limit:     1,
    featured:  1,
    relatedTo: { targetElement: category, field: 'category' },
    order:     'postDate desc'
}) %}

UPDATE

The aforementioned bug was fixed in Craft 2.1.2563.  You’re still better off using the relatedTo param though.

UPDATE 2

Fixed a typo in the above code block.


How to set a button's active state in WYSIWG (Redactor plugin)?

I've done this by adding my button to activeButtons and adding my inline tag to activeButtonsState after adding button in init function.

In below example, cite is the tag and citebtn is the button's name.

init: function()
{
    ...
    if($.inArray("citebtn", this.opts.activeButtons) < 0) {
        this.opts.activeButtons.push("citebtn");
        this.opts.activeButtonsStates.cite = "citebtn";
}


Turns out it was a beginners mistake, thank you to Robin in the comments above for setting me on the right track. All that was required to install was the Yii2 library, once this was done all worked as expected.


Getting this SQL Error: GROUP BY incompatible with sql_mode=only_full_group_by

MySQL 5.7.5+ changed the way GROUP BY behaved in order to be SQL99 compliant (where in previous versions it was not).

There is a good overview of the changes here.

Unfortunately, this affects some core queries that Craft uses when fetching elements.

The good news is that this has been fixed already in Craft 3 since we refactored the way that elements query grabs data and it no longer uses a GROUP BY.

The bad news is that it's going to be pretty impractical to backport that fix into Craft 2.

The workaround for Craft 2, if you're running MySQL 5.7.5+ is to edit your my.cnf file and remove the ONLY_FULL_GROUP_BY option from sql_mode. That will change GROUP BY behavior back to its pre-MySQL 5.7.5 behavior.

Update:

If, for whatever reason (primarily you're on shared hosting), you aren't able to change the sql_mode of your box at the environment level, as of the next Craft release (post 2.6.2945), there is a new initSQLs database config settings you can set in your craft/config/db.php.  It will accept an array of SQL statements to be executed immediately after the database connection has been established.  If you're running into this MySQL 5.7 error, you can do:

'initSQLs' => array("SET SESSION sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';")

Just keep in mind this method will add at least one extra SQL query to every request.


How do you use the Element API plugin to output Matrix blocks for an entry?

Totally possible. Just loop through the blocks and add whatever data you want from them to the response array:

'transformer' => function(EntryModel $entry) {
    // Create an array of all the "Body" Matrix field's blocks
    $bodyBlocks = [];
    foreach ($entry->body as $block) {
        switch ($block->type->handle) {
            case 'text':
                $bodyBlocks[] = [
                    'text' => $block->myRichTextField->getParsedContent(),
                ];
                break;
            case 'image':
                $image = $block->myAssetsField->first();
                $bodyBlocks[] = [
                    'image' => $image ? $image->getUrl(['width' => 500]),
                    'caption' => $block->myPlainTextField,
                ];
                break;
        }
    }

    return [
        'title' => $entry->title,
        'url' => $entry->url,
        'description' => (string) $entry->description,
        'body' => $bodyBlocks
    ];
},

Each of the elements in that sub-array will be MatrixBlockModel objects.


How to add a subTask to an already running Task?

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

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

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


Dynamic URL generated by a custom field dropdown value

In the section settings, you can specify a dynamic entry URI format.
As the docs say, this box is in fact a mini Twig template, and is preloaded with the element being saved (accessible as object) and its custom fields (accessible directly by their handles). Good to know that you can also use a shortcut syntax with single braces instead of double ones here.
So in your case you'd want something like:
{slugPrefixFieldHandle ? slugPrefixFieldHandle ~ '/' ~ slug : slug}


How do I edit a dropdown field in the charge.onCharge hook?

In your current example, you are not actually saving an entry. You are just setting up an onSaveEntry event listener. To save the entry you will need to actually save the entry using the [saveEntry][1] method.

UPDATE: I'm not exactly sure what your setup is — but some variation on the following should work for you.

In the CMS, add a field called 'invoiceID', which you will use to store the invoice entryId to the charge (or 'invoiceEntryId' or whatever you want to call it).
Add the 'invoiceId' field to the charge field layout in charge->settings->fields.
In the charge form, add the 'invoiceId' field to your form (this assumes that you are making the charge from the invoice entry page, otherwise you will need to use a reference to the invoice entry id through whatever relationship you have set up):

<input type="hidden" name="fields[invoiceId]" value="{{ entry.id }}"/>

In your plugin, add the onCharge event to grab the 'invoiceId' from the charge event, then retrieve, update, and save the entry.

craft()->on('charge.onCharge', function(Event $event) {

    // get the charge model
    $charge = $event->params['charge'];

    // retrieve the invoiceId (aka entryId) saved on the charge model
    $entryId = $charge->invoiceId;

    // uncomment to test, if needed
    //LogicPlugin::log('Invoice ID: '.$charge->invoiceId, LogLevel::Info);

    // get the invoice entry from the invoiceId
    $entry = craft()->entries->getEntryById($entryId);

    // update the invoicePaid field (in this case I'm using a switch)
    $entry->getContent()->invoicePaid = '1';

    // save the entry
    $success = craft()->entries->saveEntry($entry);

    // log errors
    if (!$success) {
        LogicPlugin::log('Couldn’t save the entry "'.$entry->title.'"', LogLevel::Error);
    }

});


Check if local image differs from image on Craft

It is related to the linked question since any images uploaded through Craft's AssetsService go through a "cleansing" process to remove any potentially embedded malicious scripts so the file size will inevitably be +/- the original by a small percentage.

What you can do is instead of uploading through the AssetsService, programmatically copy the file to the final destination on the file system in an Asset Source, then trigger Asset indexing like how the ToolsController does for the AssetIndexTool.  That will bypass any cleansing operations.


How Do I show advanced Date filters for Events?

Thanks to Brandon Kelly's help I now have Events being filtered by my custom date field called eventDate by doing the following:

{% set day = date(craft.request.getSegment(2)) %}
{% set nextDay = day|date_modify('+1 day') %}
{% set events = craft.entries.eventDate('and, >= '~day|date('Y-m-d')~', <'~nextDay|date('Y-m-d')) %}

I have some links in my side bar that append the appropriate Date to the URL:

Today
Tomorrow

And finally I just loop that through like so:

{% for block in events %}{% endfor %}

I hope someone else can find this as handy as I did through Brandon's help!


You can do what you're looking for with some caveats from the front-end of a site.

If officers have the editUsers permissions, then they can edit most other things about other users.

The two exceptions are their email address, which requires the changeUserEmails permission and the password, which they can't change at all.  The only person that can change the password is the user it belongs to.


What's the best way to manage a large number of uploaded photos?

Sounds like a feature request is in order. It'd be nice to be able to search subfolders for sure.

Regardless, everyone has their own way to organize but you might create folders based on department or whatever category the news is in—sports, politicians, people, religion, places, etc. and then set up the asset to save automatically in that folder based on the category, for example.

As someone who's on that content editing side as well, whatever system you setup, keep it consistent, make sure everyone uses it, is on board with it, and sticks with it. This is not just a technology problem but a people problem. Technology is only as good as the people who are using it.

When I worked for a local TV station doing over the shoulder graphics years ago, we'd have our goto images that we used and I've found over the years doing web it's the same way—people are creatures of habit.

When the site first launches, you throw tons of content at it but down the road, I've found people tend to reuse a lot of stuff. I mean how many different shots of the grand canyon do you need? I don't think every story, every time is going to have a new image thrown at it, but they will recycle a fair amount, so keep that in mind.

There's also a plugin called Introvert that you can setup so you can see reverse entries. That might be helpful to see which other entries that an asset is using. If it's been used by a lot of other entries, it might be time to say "hey we need another image of this..."


Possible to get content block from another entry?

You can query for that parent page's entry model with a new ElementCriteriaModel.

{% set mainEntry = craft.entries.id(100).first() %}

{% if mainEntry %}
    {% set matrixField = mainEntry.matrixFieldHandle %}
    {% set firstContentBlock = matrixField.type('content').first() %}

    {% if firstContentBlock %}
        {{ firstContentBlock.myRichTextFieldHandle }}
    {% endif %}
{% endif %}

Instead of using the entry's ID as the link to that entry, you can also use other parameters to query for the entry model. Here's an example using slug and section:

{% set mainEntry = craft.entries.section('news').slug('main-news').first() %}


You can do a task resave after elements are entered:

public function resaveElements()
{
    // Queue up a new ResaveElements task
    craft()->tasks->createTask('ResaveElements', null, array(
        'elementType' => ElementType::Entry,
        'criteria'    => array('section' => 'search', 'limit' => null, 'status' => null,'localeEnabled' => null)
    ));

    // Start running tasks
    craft()->tasks->runPendingTasks();
}


Return json formatted entries and include a header for Access-Control-Allow-Origin

You can set the header in Twig with the {% header %} function. Like this:

{% header "Content-Type: application/json; charset=utf-8" %}
{% header "Access-Control-Allow-Origin: *" %}

As to generating the actual json, my favourite is using the prune plugin and do it like this:

{% set myEntries = craft.entries.section('mySection').find() %}

{
    {%- spaceless -%}
    "myEntries": {{ myEntries | prune(['onefield', 'anotherfield']) | json_encode() | raw }},
    {%- endspaceless -%}
}

You could also just loop over all the entries and create the json yourself, but I always get into all sorts of issues with encoding when doing that.

If you're going to do a lot of json requests, you could also look into the Element API plugin from Pixel & Tonic. You'd probably have to set the headers on the webserver level (.htaccess or nginx.conf) though.


How do I check and indicate that a product is already in the cart?

This StackExchange question explains how to set an array of IDs for items in your cart, and then compare those IDs against the IDs of a list of products: Check if cart contains valid products for discount code


Restricting file size for an Assets Volume

There's no way for the moment to limit filesize by Volume, but your can create a custom module with the EVENT_BEFORE_SAVE hooked on Assets.

Here's a related post.


Apply updates automatically when available

It's typically bad practice to allow auto-updates -- at least in a production environment.

That being said, to update Craft, you're required to download the new files (click "Download" on the update page and it gives you a zip file), and then replace them in your codebase. So right now, no you wouldn't be able to do this with a Cron Job.

Craft 3 may be a different story, though.


That happens because the date filter returns the current date for null values / empty strings.

  If the value passed to the date filter is null, it will return the current date by default.

To work around this, you would add a conditional.

{% if entry.myDate %}
    Date: {{ entry.myDate|date('Y-m-d') }}
{% endif %}

Another way to do this is to use a ternary operator.

{{ entry.myDate ? entry.myDate|date('Y-m-d') }}


How does a CMS work ? How to add articles and manage them?

Creating a website in Craft CMS as you outline requires a fair bit of knowledge:

HTML
CSS
Tag language, like Twig (which is what Craft CMS uses)
Maybe a little JavaScript
Basics of file management, FTP (or version control)

Wordpress is a tool that may allow you to create your site with less knowledge of the above - there are pros and cons to each approach.

If you have knowledge of the above skills, I suggest watching some basic Craft tutorials, at Mjingo, for example, installing Craft on a local or remote server, and learning the basics. Then you will know if it is the right tool for you.

Here's a big list of Craft resources.


If you want to check all assets across all sources, it'd be this:

{% set assets = craft.assets.width('> ' ~ 1000).find() %}

If you want all assets from a particular source, it'd be:

{% set assets = craft.assets.source('sourceHandle').width('> ' ~ 1004).find() %}


To list all tags on a particular entry use:

{% for tag in entry.tagField %}
    {{ tag }}
{% endfor %}

If you only want the first tag you can just use:

{{ entry.tagField.first }}


I'm guessing you're using some sort of Google Maps plugin on your site. Google recently started limiting access to their Maps API, and now you need a key to be able to make Maps requests.

Go here to request an API key: https://developers.google.com/maps/documentation/javascript/get-api-key. Then input the key into whatever plugin is using Google Maps. There should be a field in the plugin settings that asks for the key.


How do I get the last uri segment from within a plugin (php)

Have a look at the segments property (shortcut for getSegments() method) of the HttpRequestServices class, which returns an array of uri segments.

craft()->request->segments;

To get the last segment you could use php's end() or array_pop() method.

$segments = craft()->request->segments;
echo end($segments);


Sort merged array by array value in Twig?

The SuperSort Plugin is built for use cases exactly such as this. It allows you to render each object in your array using a Twig object template and sort the array based on the rendered value.

For example, in OP's case, we could sort the combined array by the created_time variable like this:

...
{% set feed = instagram|merge(community) %}
{% set sortedFeed = feed | supersort('sortAs', '{created_time}') %}

(The plugin parses {created_time} — a Craft 'micro-template' — into {{object.created_time}}, which provides the value by which the array is sorted.)

If the property of interest happened to be different between two arrays, we could include a conditional or ternary operator in the micro-template to differentiate them:

{% set sortedFeed = feed | supersort('sortAs', '{{ object.current_time is defined ?: object.someOtherProperty }}') %}


Integrating and Caching Weather Data from Forecast.io API

Looks like there are already several PHP libraries for the forecast.io API.

I'd probably spend a few minutes reviewing those and find one that's to your liking.  Then, it's a simple as writing a Craft plugin that utilizes that library to make calls to their API and deal with the response as appropriate.


Child categories appear as their parent when selected

Do you have a limit of 1 set for the number of categories? Selecting a child category (Pacific Northwest) selects the parent as well, and if there is a limit of 1, then only the parent end up selected.

To work around this, you could model the regions with a structure rather than categories. Picking elements from a structure does not select the parent as well, so with a limit of 1 it would be possible to select Pacific Northwest.


You can see an example of how we're doing this exact scenario in Craft by looking in the database at the craft_users, craft_usergroups and the join table for the two, craft_usergroups_users as well as their related record classes in craft/app/records, UserRecord, UserGroupRecord and UserGroup_UserRecord.

UserRecord defines its relation to UserGroupRecord like so:

$relations['groups']  = array(static::MANY_MANY, 'UserGroupRecord', 'usergroups_users(userId, groupId)');

Essentially, "I'm related to UserGroups, through the usergroups_users table using the columns userId and groupId".

That way, if you're sticking purely with ActiveRecord, you don't have to worry about manually updating the usergropus_users table... Craft/Yii/ActiveRecord will do it for you.


Multiple and or relatedTo in plugin element criteria

Aren't you missing the ->find() on the last bit?

$entries = craft()->elements->getCriteria(ElementType::Entry, [
    'section'           => 'products',
    'relatedTo'         => ['and', $fabric_categories, $color_categories],
])->find();
return $entries;


Deployment of Craft 3 site to the production server

This looks like a well visited question, its easy as something like this with apache2:

<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html/web/

        <Directory /var/www/html/web/>
           Options FollowSymLinks
           AllowOverride None
           Require all granted
        </Directory>
</VirtualHost>

This is just a sample vhost file, but the real important part here is that you have the web folder set as your document root. This of course wont help anyone not using apache.


Let me know if anything in this help document needs clarifying: https://craftcommerce.com/support/sending-an-order-confirmation-email


Can't seem to output fields related to the current category page

Specifically for the image, if I'm correct, you're trying to use imager the wrong way.

It should be

   {% set image = entry.shopImage.first() %}
   {% set shopImageTransform = craft.imager.transformImage(image, { width: 130, height: 170, mode: 'crop', position: 'center-center', jpegQuality: 90 }) %}

Basically, 'shopImageTransform' becomes the new 'image' so you have to call .url on shopImageTransform instead of on image. You can see an example here , in the Imager readme.

As for the problem with the shopUrl, if you just dump it out, what do you receive? Is it holding any value?


How do I handle and/or repopulate checkbox group(s)?

I wanted to follow up with this thread in case someone else came across this. If there is a better solution, let me know and I will update the answer accordingly.

Using the example above, the user filling out the form can choose their favorite color(s).

I should mention that the colors checkbox field was created in the CP, and all values for the checkbox are managed there. That way I can easily loop through the values within my template.

twig/html

    {% for option in craft.fields.getFieldByHandle('colors').getFieldType.options %}

                <input type="checkbox" value="{{ option.value }}" name="fields[colors][]" {% if account is defined and option.value in account.colors %}checked{% endif %}>{{ option.label }}

   {% endfor %}
   {% if account is defined %}
       {{ errorList(account.getErrors('colors')) }}
   {% endif %}


Is it possible to change the amount of time a user stays logged in for?

Yes! The setting is called userSessionDuration, and you can set it in your general.php config file, on a per-environment basis.

Here's an explanation of the values that you can use for the setting—for posterity: integers (in seconds), a PHP duration expression, an initialized DateInterval object, or 0 for "indefinite."

The link above points to the Craft 3 documentation, but the same setting is available in Craft 2.


I guess you could do something like this. I'm assuming the events have eventStart and eventEnd date variables, and I'm here comparing the dates with the built in now variable on the format year-month-hour-minute:

{# When eventStart is bigger than "now", the event is in the future #}
{% if event.eventStart|date('YmdHi') > now|date('YmdHi') %}
  I will attend this event!

{# When eventStart is in the past, and eventEnd is in the future, the event is ongoing #}
{% elseif event.eventStart|date('YmdHi') <= now|date('YmdHi') and event.eventEnd|date('YmdHi') > now|date('YmdHi') %}
  I am at this event RIGHT NOW!

{# When none of the above, the event is in the past #}
{% else %}
  I was at this event
{% endif %}

Depending on your use, you could build on this to create a variable for "past/present/future" or similiar. To be even more sure on your validation, the last endif could also specifically test that the endDate is in the past, instead of just being a catch-all else.


Use the relatedTo method and pass an array using the and parameter.

 {% set venueEventType = craft.request.getParam('catVenueEventType') %}
 {% set venueEventSize = craft.request.getParam('catVenueEventSize') %}

 {% set entries = craft.entries.section('venues').relatedTo(['and', venueEventType, venueEventSize]) %}


You're close! It's slightly counterintuitive but group is a property of a category. So you need to grab the group from an actual category. This would work:

{% set catName  = craft.categories.group('caseStudiesCategories').first.group %}

Basically you're getting the first category in the group and grabbing the group name (you could also use [0] instead of .first).

If your entry has a category field, you can access the group name in a similar fashion:

{% set catName = entry.yourCategoryField.first().group %}


Trigger Update Asset Index from url endpoint

Not natively, but you could easily write a plugin with a controller that exposes the AssetIndexingService.


When you're setting section.links.limit(4), Craft will persist that limit in subsequent calls.
This was a change introduced in Craft 3, which you can read about Changes in Craft 3 | Cloning Element Queries

You have two options to resolve your issue:
Use clone() to create a new version of the ElementCriteriaModel for each time you use section.links
{% for mainLink in clone(section.links).limit(4).all() %}
{% endfor %}

{% for secondaryLink in clone(section.links).offset(4).all() %}
{% endfor %}

Or unset the limit your limit in the second for loop
{% for mainLink in section.links.limit(4).all() %}
{% endfor %}

{% for secondaryLink in section.links.limit(null).offset(4).all() %}
{% endfor %}


I would consider this carefully from a subscriber's perspective. i.e. If I received an email every time something was published, I may consider unsubscribing very quickly.
An alternative which I've found works very well is to send email updates on a regular basis - that way your subscribers have an expectation of the frequency.
We've used Campaign Monitor to automatically pull content from a RSS template and then send an email newsletter as well. You also have the flexibility to curate the entries as you see fit.
Have a look at this page/video: https://www.campaignmonitor.com/blog/new-features/2012/03/one-click-content/

Ability to sign up per channel via email (a form per channel)

You can create separate (subscriber) lists within Campaign Monitor, for each Channel/Section

Confirm email address (double opt-in)
No (site) registration necessary
Ability to unsubscribe

These are all possible.

Auto send email notification when new entry is posted

Automation is also possible.
Hopefully that makes sense - let us know your thoughts?


How to display the title of a category based on its ID?

First you’ll need to grab the category ID from the query string, using craft.request.getQuery():

{% set catId = craft.request.getQuery('catId') %}

Then you can fetch the CategoryModel via craft.categories and its id param:

{% set category = craft.categories.id(catId).first() %}

We can’t be sure that the ID was actually valid, so make sure that category is actually set to something, otherwise return a 404 error:

{% if not category %}
    {% exit 404 %}
{% endif %}

Now, to output the category’s title, just do this:

{{ category.title }}

There are a couple ways you can put this all together, depending on whether the page requires a category ID passed to it, or if it’s optional.

If it’s required, we should verify that the catId query parameter was actually set to something right off the bat:

{% set catId = craft.request.getQuery('catId') %}

{# The catId param is required #}
{% if not catId %}
    {% exit 404 %}
{% endif %}

{% set category = craft.categories.id(catId).first() %}

{% if not category %}
    {% exit 404 %}
{% endif %}

{{ category.title }}

If it’s optional, then we should grab the ID from the query string, and then wrap all of the remaining logic in a conditional, so it only runs if there was an ID:

{% set catId = craft.request.getQuery('catId') %}

{# The catId param is optional #}
{% if catId %}
    {% set category = craft.categories.id(catId).first() %}

    {% if not category %}
        {% exit 404 %}
    {% endif %}

    {{ category.title }}
{% endif %}


Get the category into the url of the product page

It's a bit confusing, but since this product type has variants, using this should work:

shop/{object.categories.first().slug}/{object.slug}

If it didn't have variants, you wouldn't need the object reference in front of it.  The same thing applies if you're referencing a field inside of Matrix as well.

This has been made easier in the upcoming Commerce 2 so you don't have to worry about the differences.


Ajax is probably the easiest way when using something like Fancybox:
<a data-fancybox data-type="ajax" data-src="yoursite.com/houses/house-slug" href="javascript:;">
    House page
</a>

If your house page has content you want to hide when viewed in the modal you can detect whether or not Ajax was used to request the page:
{% if not craft.app.request.isAjax %}
    Your header code
{% endif }

You could also just include the house content on the page, but hidden and use fancybox to reveal it. This is possibly more accessible.


From a template, how can you order entries by one field, and if that field is empty a different field?

There are several ways you could attack this, but probably the easiest is directly from the SQL side with something like this using a SQL CASE statement:

{% set entries = craft.entries.section('news').order('(CASE WHEN field_alphaTitle IS NULL OR field_alphaTitle = "" THEN title ELSE field_AlphaTitle END)').find() %}

    {% for entry in entries %}

TITLE = {{ entry.title }} / ALPHA TITLE = {{ entry.alphaTitle }}

    {% endfor %}

Note that is assuming that alphaTitle is a custom field and title is the standard one available to all entries.


How to get current locale in the controller

craft.locale from a template goes to the locale() method of the CraftVariable class, which just calls craft()->language from PHP, which you could use.


How do I access the checkbox field column value as a PHP array?

MultiOptionsFieldData extends PHP's ArrayObject class.

You could get the values from it by casting it to an array like so:

$results = (array)$mofd;

That would give you an array of OptionData classes.  If you really didn't want to loop through them, you could do something like:

$func = static function($ofd) {
    return $ofd->value;
};

$results = array_map($func, (array)$mofd);


Defining TwigExtension globals in Craft 3

There are two ways to achieve this:

Option 1

Add this in your plugin/module main init function:

      $twig = Craft::$app->view->getTwig(null, ['safe_mode' => false]);
      $twig->addGlobal('foo', 'bar');

That's it. You can call 'foo' in your template like this {{ foo }} // Output 'bar'

Option 2 (best)

In the root of your plugin/module directory, create a folder called 'twigextensions' if you don't already have one. Create a new file where you're going to define your globals. MyGlobals.php for example.

At the very top of your main plugin/module file, you need to add this:

use modules\myawesomemodile\twigextensions\MyGlobals;

... remembering to amend the plugin/module name, and the name of the file you created.

Then add the following to the same file. Only this needs to be inside your main init function:

Craft::$app->view->registerTwigExtension(new MyGlobals());

Lastly, in your new MyGlobals.php file. Add the following. Again changning the plugin/module names where appropriate.

namespace modules\myawesomemodule\twigextensions;

use modules\myawesomemodule\MyAwesomeModule;

use Craft;

class MyGlobals extends \Twig_Extension implements \Twig_Extension_GlobalsInterface
{

    public function getGlobals()
    {
        return array(
            'foo' => 'bar',
        );
    }
}

That's it. Like before, you can call 'foo' in your template like this {{ foo }} // Output 'bar'

Now I don't understand the technical reasons as to why one is better than the other. I prefer Option 2 because it permits me to add multiple globals. However, my old post was answered by Mats Mikkel Rummelhoff; who goes into this in a little more detail.


Why not use:

{% if block.sidebar|length %}

{% else %}

{% endif %}

This way the column will automatically be smaller IF the side bar exists.


It depends. Technically to determine if a variable is not empty (keep in mind '0' or 'false' are not considered empty), you can use Twig's 'is not empty':

{% if entry.myField is not empty %}...{% endif %}

But in most situations where '0' and/or 'false' are not expected values, then  anything that evaluates to '0', 'false' or 'null' will also work. So,

{% if entry.myField %}...{% endif %}

or

{% if entry.myField|length %}...{% endif %}

If the field is not defined in the field layout however, these may also return an error. In which case you might want to use Twig's 'is defined' first, before checking if the field is empty.

`{% if entry.myField is defined %}...{% endif %}`

In most cases, I just use {% if entry.myField %}...{% endif %}.


Solspace Calendar: List only recurring events

The limitation here is that the loadOccurrences: false parameter only checks for "Primary" events (first occurrence) within the specified timeframe. So if the first occurrence is outside of the specified timeframe, the event won't show at all.


How do i get sites by group handle/name?

I would rather suggest you to do that in PHP but the Twig way would be the following

{% set allSites = craft.app.getSites().getAllSites() %}
{% set sitesWithGroup = [] %}
{% for site in allSites %}
    {% if site.getGroup().name == 'my group name' %}
        {% set sitesWithGroup = sitesWithGroup|merge([site]) %}
    {% endif %}
{% endfor %}


Dynamic routing via plugin with special characters

You'll need to update the regex to allow for additional characters.  For example, if you want to allow !, then this will work:

return array(
    'myroute/(?P<myVariable>[-\w\!]+)' => array('action' => 'myPlugin/myAction')
);

Note that \w is essentially the same as writing [A-Za-z0-9_].


Built in validate of title when using EntryModel?

You could hook into the entries.beforeSaveEntry event like this:

craft()->on('entries.beforeSaveEntry', function (Event $e) {

    // Get the entry we're saving, and it's title
    $entry = $e->params['entry'];
    $title = $entry->getContent()->title;

    // Look for existing entries with the same title
    $existingEntry = craft()->elements->getCriteria(ElementType::Entry, [
      'title' => $title,
      'id' => $entry->id ? 'not '.$entry->id : null
    ])->first();

    // If an existing entry is found, prevent saving and pass an error message
    if ($existingEntry) {
      $entry->addErrors([
        'title' => Craft::t("An entry titled $title already exists"),
      ]);
      $e->performAction = false;
    }
});


Neater way to merge this conditional entry query?

You can do this:

{% set query = craft.entries.section(contentSection).isFeatured('not 1') %}

{% if (categorySlug is defined) and (categorySlug != null) %}
   {# GET CONTENT FROM ONE CATEGORY #}
   {% set contentQuery = query.relatedTo(craft.categories.slug(categorySlug)).all() %}
{% else %}
   {# GET ALL CONTENT #}
   {% set contentQuery = query.all() %}
{% endif %}

Or if you want to be fancy ;)

{% set query = craft.entries.section(contentSection).isFeatured('not 1') %}

{% set contentQuery = ((categorySlug is defined) and (categorySlug != null)) ? query.relatedTo(craft.categories.slug(categorySlug)).all() : query.all() %}


How do I get the number of days in the previous month?

I believe: {{ now | date_modify('-1 month') | date('t') }}


Is it possible to override the default session notices?

If you place a PHP file in craft/translations named after a locale ID and returning an array, those values will be used instead.

craft/translations/en.php

<?php

return array(
    'Logged in.' => 'Good to see you.',
);

Craft's own CP translation files can be found in craft/app/translations.

You can read more about it here: http://buildwithcraft.com/help/static-translations


Why does my custom element type error around locale being missing on the element types' model?

That's interesting Luke, I had the exact same issue and spent WAY too long on it.

Even though I used a diff tool to see the difference between working elementType models and the one with the error I just did not catch the silly difference:

protected function defineAttributes()
{
    return array(

vs the working:

protected function defineAttributes()
{
    return array_merge(parent::defineAttributes(), array(

you need to add the parent attributes that includes attributes like locale :)

I knew that all along, but just didn't catch it on multiple re-reviewing of the Model.


How to display entries with a custom date field within month

Solution 1:

The problem with your code is, that you apply the date filter exclusively to the year variable:

  {% set firstDayOfMonth = month ~ "/1/" ~ year|date("U") %}

To get this right you have to first compose your "datetime string" and then apply the filter to the string as a whole:

{% set firstDayOfMonth = (month ~ "/1/" ~ year)|date("U") %}

That's also the reason why it works for you to apply it inside the query.

.

Solution 2:

You don't need to pass a unix datetime formated string to your query, a string in format "Y-m-d" is just fine:

{% set firstDayOfMonth = year ~ "-" ~ month ~ "-01" %}
{% set daysInThisMonth = firstDayOfMonth|date('t') %}

{% set lastDayOfMonth = year ~ "-" ~ month ~ "-" ~ daysInThisMonth %}

{% set thisMonthsEvents = craft.entries.section('events').eventDate('and', '>= ' ~ firstDayOfMonth, '<= ' ~ lastDayOfMonth) %}


Excluding properties from returned ElementModel in plugin

Unfortunately this is one of Crafts disadvantages, you'll always fetch all fields in your craft_content table no matter if you need those or not, thus it's always a bit slow and query heavy.

Craft 3 introduces a way to solve that issue since it loops the field layout and only fetches the values you need and not all of them.

Anyway: you could do this:

// get an array of all fields in craft_content (note: that only works for fields
// with a record in `craft_content` so you won't fetch relations with that
$attributes = $journeys[0]->getContent()->getAttributes();
$this->returnJson([
    'title'                 => $journeys[0]->getTitle(),
    'myCustomField'         => $attributes['myCustomField'],
    'myAwesomeField'        => $attributes['myAwesomeField'],
    'anotherField'          => $attributes['anotherField'],
    'idsOfARelationField'   => $journeys[0]->relationFieldHandle->ids()
]);

That way you can define which values you need and return them in an array. If you don't need all the other values just leave them empty. If you only want to fetch all custom fields you can use

$this->returnJson($attributes);

Not sure if you'll receive the title that way, you need to try. Othewise - if you need the title and if it's not included

$attributes['title'] = $journes[0]->getTitle();
$this->returnJson($attributes);

solves that.

Edit: by the way if you only need the first element you can do $criteria->first() instead of $criteria->find();


Problem uploading JPG in MAMP Pro 4.2 (9213)

I found the answer: in the main window of MAMP Pro there's a sidebar with a sub heading Languages > PHP. When you click that and check the option under Extensions: Imagick / ImageMagick, all my problems disappear and I can upload JPG and PNG.


Is there any way to adjust the width of the custom field in the admin panel?

You can adjust it by following below steps:

First go to Settings > Sections > Select Edit Entrytype of a section.

Then choose your Custom field and then you find four pieces block icon on the right upper corner that are used to set the width of the field in the entry form. So you can adjust width by clicking on that particular block.

For Ex-  If you want to set width 50% then you have to choose 2 blocks. Each block contain 25% of 100% width


Get entries where relation matches or is empty

For anyone that comes across this. Craft CMS has added this as a feature for next release.
https://github.com/craftcms/cms/issues/7256#issuecomment-744644568


Do Remote Assets (ie. S3) have file paths?

This question is really more about S3 than about Craft. What you need for the assets is not the file path, but the url. And yes, S3 assets do have a url. This page describes the format for the host:

<bucket-name>.s3-website-<AWS-region>.amazonaws.com

They give these examples:

  This URL requests the photo.jpg object, which is stored at the root level in the bucket.

http://examplebucket.s3-website-us-east-1.amazonaws.com/photo.jpg

  This URL requests the docs/doc1.html object in your bucket.

http://examplebucket.s3-website-us-east-1.amazonaws.com/docs/doc1.html


Event when a sections' entry type changes layout?

Not right now, and technically Craft actually deletes the old Field Layout and creates a new one each time you save an Entry Type, since it would be more trouble than it’s worth to keep the old one and compare it to the new POST data for changes.

So, we could add a new onSaveEntryType event to SectionsService, which would end up getting called whenever the Field Layout changes. I’ll add that to the 2.3 list.


Entry::find()->startDate('>='. $someTime).endTime('<='.$someOtherTime).all();

Those variables can be timestamps, DateTimes or a correctly formated time string.

Here are some variants of these filters

Entry::find()
    ->variantOne('<=' .  Db::prepareDateForDb(new \DateTime())) <-- DateTime object
    ->variantTwo('<=' . time())  <-- as timestamp
    ->variantThree('<=' . (new \DateTime())->format('U')) <-- timestamp as well
    ->variant(['and', '<=' . time() , '>=' . time() - 3600]) <-- entries within the last hour
    ->validString(['or', '>=' . (new DateTime())->format('Y-m-d H:i:s'), '<= ' . time()])


Enable single line item mode on Commerce Pro

There is no existing config option for this behaviour with Commerce Pro.
You'd need to write a relatively simple custom module to do this.
You'd probably listen to something like this event:
https://craftcms.com/docs/commerce/3.x/events.html#beforeaddlineitemtoorder
...and remove anything else in the cart before the new item is added.
or, thinking about it, you might want to first make sure the new item has been successfully added, and only then remove the other items from the cart, in which case:
https://craftcms.com/docs/commerce/3.x/events.html#afteraddlineitemtoorder


unserialize(): Error at offset 0 of 60695 bytes

Adding a "^" to the craftcms version in the composer.json file and then running composer update, did the trick for me.

for example: "craftcms/cms": "^3.1.22",

I also cleared the cache folder in /storage/runtime/cache


Change author of entry within Craft Client licence

Update the database: author_id column in the craft_entries table.


relation_interview_persons is not an array of elements but an object of type ElementQuery. In order to get the results you need to call one().

Keep in mind chances are high there is no related element if that's the case your code will throw an exception.

{% set person = object.relation_interview_persons.one() %} {{ person? person.firstname : ''}}

If date is not a field of type text but a Date field that will throw an exception as well since it's an object and no string


Getting back after forwarding to another controller function

I have this working in another plugin calling another function:

$forward = $this->forward('commerce/products/saveProduct', false);

and it returns to the original controller fine. So, as Brad comments, the forward is actually working as expected but that particular UsersController->saveUser() function prevents it happening internally.

Within my particular example, I was able to access the original post request and access a userGroupId from the user registration form like so:

    craft()->on('users.onSaveUser', function (Event $event) {
        if ($event->params['isNewUser']) {
            if (isset($_POST['userGroup'])) {

                $userGroupId = $_POST['userGroup'];
                $user = $event->params['user'];

                craft()->userGroup->setUserGroup($user, $userGroupId);

            }
        }
    });


Looks like you have a plugin called core that is not handling console requests properly.

#3 /var/www/examplewebsite.co.uk/vendor/craftcms/cms/src/base/Plugin.php(130): yii\base\Module->__construct('core', Object(craft\console\Application), Array)


No reason at all, that should work perfectly fine.

In fact, at least 90% of my projects keep files, database, and assets all on the same server. For the remaining 10%, I'm usually only moving the assets to Amazon S3. Everything else continues to live on the same server.


Migration: Removing field from GlobalSet/Entry

Did you consider using Craft 3.1 new Project Config File feature?

https://docs.craftcms.com/v3/project-config.html#enabling-the-project-config-file

Any time a field is added, modified ou removed, every environment will be updated to match the primary one. That could be much more easier than handling it manually with migrations.


How Do I group entries by Category and retain fixed Category Order?

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

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

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

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

{{ category.title }}

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

{{ entry.title }}

    {% endfor %}

{% endfor %}

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

This also makes a few other assumptions too...

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

Category A

entry
entry

Category B

entry

(No Categories)

entry

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

Category A

entry 1

Category B

entry 1


Template error: Method "siteUrl" for object "Craft\ConfigVariable" does not exist

Did you configure siteUrl in general.php?

return array(
    // ...
    'siteUrl' => array(
        'en' => 'http://example.com/en/',
        'de' => 'http://example.com/de/',
    ),
);


Is it possible to get another Craft's webApp from within a Craft plugin controller

Indeed... this will do it:

$craft = require '../other/craft/app/bootstrap.php';
$entry = $craft->entries->getEntryById($id);

echo 'Other Craft install entry title:'.$entry->title;


A couple of years later, I ran into the same issue. In case there are others looking, it looks like this line:

{% for page, url in paginate.getPreviousUrls(5) %}

Should be:

{% for page, url in paginate.getPrevUrls(5) %}


Is there a way to define an attribute setter method on a model?

In your model you can override setAttribute(), which covers calling setAttribute('foo', 'bar') directly as well as $model->foo = 'bar'.

public function setAttribute($name, $value)
{
    if ($name == 'foo')
    {
        // Not sure if your value will be a dateTime object, string, etc.
        // But check to see if it's < than today's current date.  If so,
        // set $value = new DateTime();
    }

    parent::setAttribute($name, $value)
}


Yes, it's possible to do. You can do it via Static Translations. Just create translations/en-US/app.php (or whatever your site language is), and do the mapping there as per: https://twitter.com/nystudio107/status/1045963809956012032


Get dropdown / checkbox / multiselect field values on frontend submit

You can get info about your fields using craft.fields.getFieldByHandle(). That will include a settings property, which will be an array of the field type’s settings.

The actual settings available will differ depending on the field type, but Dropdown, Checkboxes, and Multi-select fields all have the same one: options. So in each of their cases, here’s how you would loop through the options:

{% set field = craft.fields.getFieldByHandle('myFieldHandle') %}
{% for opt in field.settings.options %}
    <label>
        <input name="fields[myFieldHandle][]" type="checkbox" value="{{ opt.value }}">
        {{ opt.label }}
    </label>
{% endfor %}


How to add Redactor Image resizing and positioning to the Rich Text field in Craft?

If you're on Craft 2.6.2950 or greater, it includes Redactor II 1.3.1, where they re-introduced image resizing and positioning support.

You'll just need to add:

imageResizable: true,
imagePosition: true

to whatever craft/config/redactor config file your Rich Text field is set to use under its settings.


Search products and entries with pagination

Unfortunately you would need to do 2 element query searches and combine the results on the front end.

Most developers tend to go for https://algolia.com when they want fast advanced search, including searching across elements.

Probably easiest to get started by searching for an Algolia plugin in the plugin store. I only know https://github.com/Rias500/craft-scout for Craft 3 at the moment.


I haven't used locales before so i'm not entirely sure, but when I looked in the craft service that saves a section there is a bit that looks like:

foreach ($sectionLocales as $localeId => $sectionLocale)
...

Which I assume then means your array needs to look like this:

array(
 'en' => // model
)

Whereas yours was looking like this:

array(
 0 => // model
)

So craft was seeing 0 as the locale id and it was failing.

So I managed to get this to work by using the following code:

public function onBeforeInstall()
{
  // Get the current locales ID
  $currentLocale = craft()->locale->getId();

  $section = new SectionModel();
  $section->name = 'Demo';
  $section->handle = 'demo';
  $section->type = 'structure';
  $section->hasUrls = 1;
  $section->template = 'demo/page';
  $section->enableVersioning = 1;

  // Index the locales by their ID e.g en returns array
  $locales = craft()->sections->getSectionLocales(1, 'locale');

  // Target the locale we want by the key in the array
  $locales[$currentLocale]->urlFormat = 'demo/{slug}';
  $locales[$currentLocale]->nestedUrlFormat = '{parent.uri}/{slug}';

  $section->setLocales($locales);

  $response = craft()->sections->saveSection($section);
}

The Demo section was added and I got the 'IT WORKED' response, I hope that helps!

Edit

I suppose if you didn't want all the locales to be saved to a section you could just do something like:

$specificLocales = array();

// After setting the locale attributes
$specificLocales[$currentLocale] = $locales[$currentLocale];

$section->setLocales($specificLocales);


How to eager load user Images (photoUrl)?

Your source is set to :

{{ entry.getPhoto.getUrl('user') }}

When in order to access an image, you need to give the array index (as you have in your set statement):

{{ entry.getPhoto[0].getUrl('user')

or better yet, as you have already set it to a variable

{{ userImage.getUrl('user') }}

In full, while adding in to appropriate code for eager loading your transforms:

{% set entries = craft.users({
    group: 'coWorkers',
    orderBy: 'lastName',
    with: [
       [
           'getPhoto',
           { withTransforms: ['user'] }
       ],
    ]
}) %}

{% for entry in entries %}

    {% set userImage = entry.getPhoto[0] ?? null %}

    {% if userImage %}

    {% endif %}

{% endfor %}

If you need any further information, the Official Documentation does a excellent job of explaining how to implement this on the front end for craft 3


Your dump from outside the loop is being dumped BEFORE the variable is set within the loop. Move it to after the loop and try it again.


Problems with Punctuation in Title using ElementCriteriaModel

I've tested your code with a similar query in a local database and am getting the results you'd expect. So the code seems accurate. Aside from environmental variables that may be at play, the only part of the example code above that I see a potential issue with the line:

$criteria->section = 'entryHandle';

It's unclear what you may mean by entryHandle.  This value should be the sectionHandle. If entryHandle means slug, then the $criteria->section may need to get updated to be $criteria->slug = 'entryHandle';


Plugin files are located outside your web root, thats why you can't access them directly. You should create a controller action and render the template from there.

class DefaultController extends Controller{
  protected $allowAnonymous = ['getTemplate'];

  public function actionGetTemplate(){
    $request = Craft::$app->getRequest();
    $templatevar = $request->getParam('templatevar');

    use craft\web\View;
    $oldMode = \Craft::$app->view->getTemplateMode();
    \Craft::$app->view->setTemplateMode(View::TEMPLATE_MODE_CP);
    $html = \Craft::$app->view->renderTemplate('plugin-handle/path/to/template');
    \Craft::$app->view->setTemplateMode($oldMode);
  }
}

(see https://docs.craftcms.com/v3/extend/updating-plugins.html#rendering-templates)

You can define the route to your controller action in your plugin file

public function init(){
  Event::on(UrlManager::class, UrlManager::EVENT_REGISTER_SITE_URL_RULES,
  function(RegisterUrlRulesEvent $event) {
      $event->rules['gettemplate/<templatevar:\w+>''] = 'myPlugin/getTemplate';
  });
}

and call it via
 $("#modal").load("/gettemplate/"+templatevar);


I believe that when you post data using name='action' from a form that craft automatically uses the actionUrl to route the request properly, so that if your controller is here:

/craft/plugins/broadbean/controllers/Broadbean_JobsController.php

with a method actionNew, then craft will create the action route broadbean/jobs/new automatically:

<input type="hidden" name="action" value="broadbean/jobs/new">

On the other hand if you are linking directly then craft doesn't know to use the action route, so you need to explicitly tell it that this is an action request:

<a href="{{ actionUrl('broadbean/jobs/new', { id: 10 }) }}">

or from javascript:

var url = Craft.getActionUrl('broadbean/jobs/new', { id: 10 });

If you were to call the action externally then you would have to write the full action url without the benefit of using the automatic config routing:

http://mysite.com/actions/broadbean/jobs/new?id=10

or, if the admin had, for example, set up a custom actionUrl in the config file:

http://mysite.com/methods/broadbean/jobs/new?id=10


Creating entries loop with nth loops across unordered lists

I tried a simple solution using javascript, you can translate the code into twig looping. I hope it helps.

const posts = [1,2,3,4,5,6,7,8,9,10,11,12];
const colNum = 3;
const rowNum = posts.length/colNum;

for (i=0 ; i<rowNum ; i++) {
 const row = [];
 for (j=0; j<colNum; j++) {
   row.push(posts[(i*colNum) + j]);
 }
 console.log(row)
 console.log('----')
}

output :

improve solution using twig

@JohnHenryDonovan ah sorry, I didn't notice the batch filter. Why don't you sort the entries first, then batch them?

I assume you use bootstrap as CSS lib, then you can apply d-flex on each row.

{% set projects = craft.entries()
      .section('project')
      .orderBy('postDate desc')
      .all() %}

{% set grouped = projects|batch(3) %}
{% for row in grouped %}

   {% for column in row %}

   {% endfor %}

{% endfor %}

The output of the code above

 ...

 ...

 ...

 ...

 ...

 ...

 ...

 ...

 ...

jsfiddle HTML output http://jsfiddle.net/30k9ndg6/3/


What's the largest number of elements Craft can handle well?

We have a site with (as of right now) 77,613 elements. 9,954 of which are entries.

We found that we had to be careful about using Craft's {% cache %} functionality because clearing the element cache criteria took a long time. Instead we use a Varnish cache and it all works fine.

There are times when it's not as fast as it should be, particular templates that pull in a lot of data from different places struggle if there's a bit of traffic to it at any one time - but Varnish resolves that. There's probably lots in those templates that we could be doing to make them more efficient too, it's just not been a high priority because it works okay.]

Just make sure your hosting is reasonably beefy. Depending on your traffic mysqld might get called upon a lot and that can be a resource hog. I recommend using something like DigitalOcean where you can simply increase the VPS specs if things are struggling and tweaking Craft settings or templates isn't helping.

And with Craft 3's performance boosts coming this year, I think you'll be fine.

Hope that helps!


onBeforeSaveUser validation for existing user but not new user

If you hit the submit button and don't fill out any fields. Then the only errors back are Email and Password (standard and set out by Craft). If you do enter an email and password then my validation code works and it errors again this time with the firstName and lastName errors. But these don't trigger on first submit when all fields are blank.

This is a known issue (specifically with the UserModel when saving a user) because "First Name" and "Last Name" aren't true fields in Craft, but more special case fields.

When saving a user, the UserModel validation runs first and immediately bails when the validation error occurs before the onBeforeSaveUser event fires not giving any plugins a chance to participate.

This will be fixed in the upcoming Craft 3 release.


Craft Commerce: Variable "product" does not exist

product will only be available by default if you're viewing the template set in the CP under that products type settings:

If you want to display your product elsewhere on your site you will need to set it to a variable like so:

{% set myProduct = craft.commerce.products.first() %}

you can then loop through this product's variants

{% for purchasable in myProduct.variants %}

    <option {% if purchasable.stock <= 0 and purchasable.unlimitedStock == false %}disabled {% endif %} value="{{ purchasable.purchasableId }}">{{ purchasable.description }} {{ purchasable.price|currency(cart.currency) }}</option>

{% endfor %}


How can I list all sub-field handles of a Matrix parent field?

You’ll need to start by figuring out the Matrix field’s ID. If you already have a MatrixBlockModel object as you say, you can get that via $matrixBlock->fieldId.

Once you know the Matrix field’s ID, you can get all its block types like this:

$blockTypes = craft()->matrix->getBlockTypesByFieldId($matrixFieldId);

That will give you an array of MatrixBlockTypeModel objects. From there you can loop through each of those and get their fields like this:

foreach ($blockTypes as $blockType)
{
    $fields = $blockType->getFields();

    // ...
}


Importing content from EE with FeedMe leaves some data out

So the answer was that each of my blocks needed to be wrapped by another element, e.g.
<modularContent>
  <block><blockHeading><![CDATA[News 1]]></blockHeading></block>
  <block><blockContent><![CDATA[
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure rerum in tempore sit ducimus doloribus quod commodi eligendi ipsam porro non fugiat nisi eaque delectus harum aspernatur recusandae incidunt quasi.
]]></blockContent></block>
</modularContent>


Snipcart plugin don't recognize the webhook URL

I think it's because your passing "localhost" as your URL, so when the snipcart server tries to get the URL you supplied it's actually tying to fetch it on its own host.

From my experience with these kinda things you need to supply a publicity accessible URL, so if you can find your public ip then maybe try that instead of localhost or upload to a staging server and then test it with a real domain.


Configure path craft uses for composer and php

As I looked at it more and how php does environment variables; I discovered the thing that was different was the system $PATH variable.
In bash on linux; this is what sets the search order for trying to find executables like php and composer.
Run php -i from an command prompt and bash is search for an executable "php" in every folder of PATH. Note it stops when it finds the first match so the order of things in PATH is important.
So my problem is really that when craft runs a shell command; php/composer aren't in PATH.
putenv() does exactly that; allows php to set an environment variable for the duration of scrip execution. The very excellent dotenv library that craft depends on makes use of that.
The scl command line tools (source and scl) change PATH. Once I saw the expected values it was as simple as popping those over into the .env file for my site.
I added a PATH="/opt/rh/rh-php73/root/usr/bin:/opt/rh/rh-mysql56/root/usr/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin"
to the top of my sites .env file. (usually in the SITEROOT/craft/ folder)
and now updates succeed and database backups work too.
If you're using mamp or any other awkward environment where php isn't in the system path; this would likely work for you too.
Take note that variables set in a .env file WILL NOT overwrite an existing variable.
https://github.com/vlucas/phpdotenv/tree/3.6#immutability
a small change to your craft/web/index.php file is needed to change that behavior.
Change
Dotenv\Dotenv::create(CRAFT_BASE_PATH)->load();
to
Dotenv\Dotenv::create(CRAFT_BASE_PATH)->overload();
and then any settings in your .env file will be honored even if they already existing in the environment.


Is there a better way than stacked if else

There is certainly a lot of repeated code here so we can definitely improve on that! There are so many ways you could handle your Twig templates but this is how I would do it:

    {% for block in entry.slideitemtop %}
        {% set Bild = block.ImageSlideTop.first() %}

                {% if block.headlineSlideTop|length %}
                    {{ block.headlineSlideTop }}
                {% endif %}
                {% if block.textASlideTop|length %}
                    {{ block.textASlideTop }}
                {% endif %}
                {% if block.textBSlideTop|length %}
                    {{ block.textBSlideTop }}
                {% endif %}
                {% if block.textCSlideTop|length %}
                    {{ block.textCSlideTop }}
                {% endif %}

    {% endfor %}

All we are doing here is using the same template code for each slide, but for each loop through we are checking if the 4 fields have any content or not.

I also noticed a slide1 class. You can also automatically increment the number at the end of the class for each loop using {{ loop.index }}.


How do I display data from an entry field related to each user in a user listing page?

You already have the right array of Design Entries grouped by your Designer's user IDs with this line:

{% set entriesByAuthor = designs|group('authorId') %}

Now all you have to do is to loop through this entriesByAuthor array. Use this syntax to iterate over Keys and Values:

{% for key, value in entriesByAuthor %}
    {{ key }}: {{ value }}
{% endfor %}

Within the loop key is the authorId you grouped by and value is an array of EntryModels that share the same value for the authorId property. To list the Design entries you have to nest another for-loop and iterate over that array of EntryModels.

To retrieve other Designer data besides the ID you first need to grab the UserModel. Create a new ElementCriteriaModel with the authorId as a parameter and use the first() function to get the model.

{# Grab all the Design Entries #}
{% set allDesigns = craft.entries.section('designs').limit(null).find() %}

{# Group by the authorId #}
{% set allDesignsByAuthor = allDesigns|group('authorId') %}

{# Loop through all Design Entries grouped by the authorId #}
{% for authorId, designsByAuthor in allDesignsByAuthor %}

    {# Grab the Designer's UserModel #}
    {% set designer = craft.users.id(authorId).first() %}

{{ designer.name }}

    {# List the Designer's Design Entries #}
    {% for design in designsByAuthor %}

{{ design.title }}

        {# List the Screenshots #}
        {% for image in design.screenshots %}

        {% endfor %}

    {% endfor %}

{% endfor %}

.

Edit:

Only now I got it, why you did this line to grab the UserModels with an ID of allDesignsByAuthorId|keys. This is in fact a good idea if you want list the users in another sort order than the user ID. Because I don't think you can do that with the approach I posted above.

Here's how you proceed after you fetched the Designers with a sort order of your desire. Loop through the array of Designers and create a new ElementCriteriaModel for each designer to grab the Designs using the Designer's user ID as the value for the authorId property.

{# Grab all the Design Entries #}
{% set allDesigns = craft.entries.section('designs').limit(null).find() %}

{# Group by the authorId #}
{% set allDesignsByAuthorId = allDesigns|group('authorId') %}

{# Grab all of the users with the userIds in allDesignsByAuthorId #}
{% set designers = craft.users.id(allDesignsByAuthorId|keys).order('lastName') %}

{# Loop through the array of Designers #}
{% for designer in designers %}

{{ designer.name }}

    {# Grab all of the Design Entries created by this Designer #}
    {% set designs = craft.entries.section('designs').authorId(designer.id).find() %}

    {# List the entries #}
    {% for design in designs %}

{{ design.title }}

        {# List the Screenshots #}
        {% for image in design.screenshots %}

        {% endfor %}

    {% endfor %}

{% endfor %}

.

2nd Edit:

You only need to show one image for each Designer? Do it like so:

{# Grab all the Design Entries #}
{% set allDesigns = craft.entries.section('designs').limit(null).find() %}

{# Group by the authorId #}
{% set allDesignsByAuthorId = allDesigns|group('authorId') %}

{# Grab all of the users with the userIds in allDesignsByAuthorId #}
{% set designers = craft.users.id(allDesignsByAuthorId|keys).order('lastName') %}

{# Loop through the array of Designers #}
{% for designer in designers %}

    {# Get the total number of Design Entries created by this Designer #}
    {% set totalDesigns = craft.entries.section('designs').authorId(designer.id).total() %}

    {# Grab the latest Design Entry created by this Designer #}
    {% set design = craft.entries.section('designs').authorId(designer.id).first() %}

    {# Grab the first screenshot image of that entry #}
    {% set image = design.screenshots.first() %}

    {# Output #}

{{ designer.name }}

{{ totalDesigns }}

{% endfor %}


I've inherited the Craft website and the developer is long gone. How do I access the templates used to initally build the site?

I suppose you need access via FTP to the templates directory - which by default is craft/templates. Once you have access to that, you'll have access to the site templates. Do you have FTP access?

There's no way in Craft to view your templates through the Control Panel interface.


You don't really need a "search" plugin for that. Craft has a brilliant Query Builder so it can be done really easily. Furthermore there is the Element Api which provides a JSON endpoint.

I suggest you to read the docs about Searching in Craft and about Queries in Templates.

If you wan't to search for entries containing these words, a specific length and a threadSize you could do

{% for entry in craft.entries.threadSize('and, >0, <80).length('and, >10, <100).search({
    query: 'socket head screws',
    subLeft: true,
    subRight: true
}).limit(10).all() %}

{{ entry.title }}

        Continue reading

{% endfor %}

That's basically it.

For advanced searches I would recommend to create a custom plugin. It's totally easy to search things in Craft so the need of a "default" plugins is not really high and it's faster to create a custom plugin than to find one that fits all your specific needs.


Does the default local content show when you toggle another locale/s off?

If you toggle off a locale for an entry, that entry will not show in that locale. So, if you have a section news, toggle off the entry my-entry in your current locale, and use craft.entries.section('news') to get all entries, my-entry will not be in that list.


How can I list Entry Types of a single Section?

You're close – this should work:

{% set blogSection = craft.app.sections.getSectionByHandle('blog') %}
{% set blogSectionEntryTypes = blogSection.getEntryTypes() %}

{% for entryType in blogSectionEntryTypes %}
    <p>{{ entryType.name }}</p>
{% endfor %}

The reason why craft.entries.section('blog').getEntryTypes() didn't work is that craft.entries will actually create an ElementQuery, which is used to query for elements (e.g. entries).

When you use craft.app.sections or craft.app.getSections() (it doesn't really matter which variant you use, although the latter is a micro-optimisation in terms of performance) you're interacting with the Sections service, which is what you need to use to work with sections and their entry types directly, rather than entries.


How to create code blocks with syntax highlighting

There is the Ace Freely plugin, which adds an Ace Editor Field Type that would work well in a Matrix field.


You would need to define them in the Gulp file build uglify task.


Show entry content for other available locales

I think the best way to do this, is by using craft.entries.id().locale() and checking if any entries are returned (not tested):

{% set thisEntryInDifferentLocales = craft.entries.id(thisEntry.id).locale('fr') %}
{% if thisEntryInDifferentLocales | length %}
    {% for localeEntry in thisEntryInDifferentLocales %}
       This entry is also available in {{ localeEntry.locale }}
    {% endfor %}
{% endif %}


Select all entries with asset field attribute criteria

You can do it like explained in this answer, only that you also add your dropdown field parameter to your craft.assets criteria model:

{% set assets = craft.assets.docType('A').limit(null) %}

and then:

{% set entries = craft.entries.section('articles').relatedTo({
    targetElement: assets,
    field: 'documents'
}) %}


I don't know if there is anything natively in Craft to do this, but you could achieve it quite easily with a single file plugin:

public function init()
{
    craft()->on('users.onBeforeSaveUser', function(Event $event) {
        // Only do anything if it is a front end submission
        if(craft()->request->isSiteRequest())
        {
            $username = craft()->request->getPost('username', null);
            if($this->isEmail($username))
            {
                $event->params['user']->addErrors(array('username' => Craft::t('You cannot use an email')));
                $event->performAction = false;
            }
        }
    });
}


Installing other PHP app in sub directory

Yes, possible. You just need to override the URL routing within the subdirectory, so requests to /sub/* get routed to /sub/index.php rather than /index.php.

For example, if you’re using Apache, just place Laravel’s .htaccess file within your subdirectory.


No matter how many levels there are in your structure ancestorOf will fetch level one entry. entry.parent could be used but covers only one level up.

{% set excludeEntry = entry %}
{% if entry.level > 1 %}
    {% set excludeEntry = craft.entries.ancestorOf(entry).level(1).first() %}
{% endif %}

{% for entry in craft.entries.section('Thunder').level(1).id('not '~excludeEntry.id).limit(3).order('RAND()') %}
...
{% endfor %}


Are you sure you didn't push something to craft/app/templates if you did go check out the folder and remove anything that shouldn't belong there. You can check side by side which files shouldnt be in there with a fresh craft environment. Or just replace the app folder with a fresh one.


How to automatically rename image uploads?

Use the assets.onBeforeSaveAsset event
You could write a plugin that listens for when an asset is saved via the assets.onBeforeSaveAsset event and rename the image before it is saved to the database?
So you could have something like this in your plugins init method:
craft()->on('assets.onBeforeSaveAsset', function(Event $event) {

    // Only rename if it’s a new asset being saved
    if($event->params[‘isNewAsset’])
    {
        $asset = $event->params[‘asset’];

        $asset->setAttribute(‘filename’, ‘SOME_RANDOM_STRING’);
    }
}

I haven’t tested this code, but from looking at Craft’s source and the docs this should work.
Documentation about events can be found on the Craft website


How to apply a "without" filter in a plugin

You can use similar logic that Craft uses for the withoutFilter in CraftTwigExtension.

public function withoutFilter($arr, $exclude)
{
    $filteredArray = array();

    if (!is_array($exclude))
    {
        $exclude = array($exclude);
    }

    foreach ($arr as $key => $value)
    {
        if (!in_array($value, $exclude))
        {
            $filteredArray[$key] = $value;
        }
    }

    return $filteredArray;
}


Feed Me: Valid JSON file returning as invalid

I think the Json-file in it self is valid (you can always run it through a linter like JsonLint) but the problem lies with the fields. Some items (such as title) are required. I found a more accurate example in the repo of the plugin. You can find it here

[
  {
  "title":  "JSON",
  "slug": "json",
  "pubDate": "Tue, 24 Feb 2015 09:00:53 +0000",
  "entry_date": "Tue, 16 Jul 2013 17:14:36 +0000",
  "status": "enabled",
  "Assets": {
    "asset": [
      "350x150.png",
      "350x155.png"
    ]
  },
  "Categories": {
    "category": [
      "Category 1",
      "Category 2"
    ]
  },
  "Checkboxes": "option_2",
  "Color": "#ffffff",
  "Date": "Tue, 24 Feb 2015 09:00:53 +0000",
  "Dropdown": "option2",
  "Entries": {
    "Entry": [
      "Sample Event",
      "homepage"
    ]
  },
  "Lightswitch": "Yes",
  "Multi": "Option2",
  "Number": "10",
  "PlainText": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
  "Position": "right",
  "Radio": "Option2",
  "RichText": "
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam lectus nisl, mattis et luctus ut, varius vitae augue. Integer non lacinia urna, nec molestie enim. Aenean ultricies mattis ligula vel consectetur. Etiam ultrices fringilla lectus nec mollis.

Nunc elit magna, semper ac faucibus ut, volutpat eu augue. Vivamus id nibh facilisis, fermentum massa vitae, rhoncus mi. Praesent sit amet efficitur dui.
",
  "Table": {
    "row": [
      {
        "one": "Option1",
        "two": "Option2",
        "three": "6",
        "four": "true"
      },
      {
        "one": "Option3",
        "two": "Option4",
        "three": "7",
        "four": "false"
      },
      {
        "one": "Option5",
        "two": "Option6",
        "three": "9",
        "four": "true"
      }
    ]
  },
  "tag": [
    "Tag 1",
    "Tag 2"
  ]
 }
]


Try this:

{% set year = craft.request.segment(4) %}
{% set month = craft.request.segment(5) %}

{% set entriesInYear = craft.entries.section('bulletinOnline').limit(null).after(year).before(year+1) %}
{% set groupedEntries =  entriesInYear | group("postDate|date('m')") %}

{% for year, entriesInYear in allEntries | group("postDate.year") %}
    {% for month, entries in entriesInYear | group("postDate|date('m')") %}

        {{ month |date((year + 1) ~ '-' ~ month ~ '-01')|date('M') }}&nbsp;({{ entries|length }})
    {% endfor %}
{% endfor %}


Cannot go to site URL while logged in without index in URL

For Documentation out of the comments:
'loginPath' => '/' was present in config/general.php, after removal of this line the website started working again.
Conclusion:
Don't set the Admin Backend or any other type of URL which requires a login (or is special in any way really) to "/" or an empty string, this can and will very likely cause major issues such as a completely non-functioning site unless index.php is in the URL (at all times).
Sidenote
I once faced a similar issue, the cpTrigger in config/general.php to an inexistant .env variable, eg $cpTr1gger, but since that wasn't present in my .env and I used getenv('cpTrigger') which returns empty strings if the requested var isn't found, it completely broke my website, similar to the above mentioned issue, it only worked with index.php in the URL.


Using Craft environment variable for Asset source subfolder

From the docs, environment variables are currently only parsed in 3 places in the control panel.

File System Path (in asset source settings)
URL (in asset source settings)
Site URL (in Settings → General)

So they won't work in the "subfolder" setting.  You can add a feature request if you think that should change.


Allow uploading of asset with same name as existing asset

I haven't tested this but from a brief look into how assets are uploaded you might be able to pass a userResponse value through post, it seems the options you can pass are:

keepBoth, replace, cancel

So I guess you would need to include the field in the form you are using to upload the asset like:

<input type="hidden" name="userResponse" value="keepBoth">

As I said I haven't tried this before and i'm assuming you're hitting the UploadFile action on the assets controller...


It's as simple as passing dateCreated into the order parameter, like so:

{% set downloads = entry.files.order( 'dateCreated desc' ) %}

If you're showing these from multiple entries you'd need to get all assets that relate to those entries and then order them as above. Something like:

{% set downloads = craft.assets.relatedTo( entries ).order( 'dateCreated desc' ) %}


Creating a date filtered archive template

I've used this method for sorting by year and month (it could be expanded to support days).

On the news/index.html template:

{% if month is defined %} {# show an archive of a month #}

    {% set sortDate = year ~ '-' ~ month %}

    Entry Date: {{ sortDate }}

    {% if month != 12 %}
        {% set nextmonth = month+1 %}
        {% set nextyear = year %}
    {% else %}
        {% set nextmonth = 01 %}
        {% set nextyear = year+1 %}
    {% endif %}

    {% set entriesToShow = craft.entries.section('news').limit(null).after(year ~ '-' ~ month).before(nextyear ~ '-' ~ nextmonth) %}

{% elseif year is defined %} {# show an archive of a year #}

    Entry Date: {{ year }}

    {% set entriesToShow = craft.entries.section('news').limit(null).after(year).before(year+1) %}

{% else %} {# assume overview page #}

    {% set entriesToShow = craft.entries.section('news') %}

{% endif %}

Any entries can then be displayed by one loop.

{% for entry in entriesToShow %}

Since this is made to be in on the section's index template you don't need a separate archive template. Just setup a few routes in the CP to send the archive tokens back to the index template.

Set all the token combinations you need like:

news/archive/(month)/(year)

To route to:

news/index.html


Yii already provides translations for those in multiple languages.  Check in the craft/app/framework/messages folder to see a list of locales it supports.

If you want it in a locale they haven't translated, yet, then you can provide your own static translation and Craft will use it.


How to create different template for specific page?

Entry templates are assigned on a per-section basis, and each section can only have a single entry template per site.
The workaround is to create a "proxy" template and use that as your section's entry template. The only responsibility for the proxy template is to {% include %} another template (the actual entry template), based on some conditions.
Here's how that proxy template could look in your case:
{% if entry.slug == 'newsletter' %}

    {# Use a special template for the "Newsletter" entry #}
    {% include 'newsletter/index' %}

{% else %}

    {# All other entries use a default "page" template #}
    {% include 'pages/page' %}

{% endif %}

Note: Using entry.slug (or entry.id, entry.title etc) for something like this is a bit fragile, because your content editor can easily change the slug and at that point the conditional will fail and the wrong template would be loaded.
A better approach is to add multiple entry types to your section (e.g. a "Newsletter" entry type and a "Page" entry type), and change the conditional to use that:
{% if entry.type.handle == 'newsletter' %}

    {% include 'newsletter/index' %}

{% else %}

    ...

Using different entry types also enables you to have different fields for different kinds of entries within the same section (which you'd typically want, when you're loading completely different templates for those entries).


How do I pull out a total of 4 rows from all my matrix blocks?

I am assuming you want four rows from each entry. I would do it like this using {% break %} from the break and continue plugin:

{% for entry in craft.entries.section('sectionName').find() %}
  {# restart our count for the new entry #}
  {% set numberOfRows = 0 %}

  {% for block in entry.matrixField %}
    {% if block.type == "blockType" %}
      {% for row in block.tableField.limit(4) %}

        {# bail if we've done our 4 rows #}
        {% if 4 <= numberOfRows %} {% break %} {% endif %}

        {{ row.title }}
        {# done another row, count it #}
        {% set numberOfRows = numberOfRows + 1 %}

      {% endfor %}
    {% endif %}

    {# bail if we've done our 4 rows #}
    {% if 4 <= numberOfRows %} {% break %} {% endif %}

  {% endfor %}
{% endfor %}

Or, slightly less efficiently (but maybe simpler), like this without that plugin:

{% for entry in craft.entries.section('sectionName').find() %}
  {% set numberOfRows = 0 %}
  {% for block in entry.matrixField %}

    {% if block.type == "blockType" %}
      {% for row in block.tableField.limit(4) %}

        {% if numberOfRows < 4 %}
          {{ row.title }}
          {% set numberOfRows = numberOfRows + 1 %}
        {% endif %}

      {% endfor %}
    {% endif %}

  {% endfor %}
{% endfor %}

I don't think you pull out the four rows from multiple matrix blocks with a single query.


Sprout Forms: Passing Checkbox variable in url parameter

There are a few possible ways to do this right now (Sprout Forms v2.3.4), all likely with a few trade-offs. We do have this situation on our radar to improve on in the future.

You could consider updating how you are storing those checkbox fields to use one or multiple Sprout Fields Hidden Fields. With this method, the first page with your initial options doesn't need to be a part of the Form and you could dynamically populate the hidden field with the value of whatever is selected. The trade-off here may be in how you wish to create reporting around your data, and whether this format makes that easier or harder.
You could manage a multi-page form using a Javascript library on the front-end (something like parsley.js). The trade-off here is that you have to add a javascript library to your setup, if you don't already need it for other things. We do have multi-page form support on our list.
You can also do this by building your Form using Custom HTML. The trade-off here is that things become harder to maintain for a fairly small item.
It might be possible to use Template Overrides and modify how the "value" parameter gets processed to make the value variable for your checkbox field use the initially selected items.  I expect this path would get tricky. The template you'd probably want start with when overriding things is the field.html template and the line that sets the value: {%- set value            = ... %}.


I don't know if this is relevant for the Email Service, but you should use the (new since Craft 2.0) siteUrl config setting (recommended):

'.dev' => array(
    'siteUrl' => 'http://example.dev/',
    'environmentVariables' => array(
        'siteUrl' => 'http://example.dev/',
        'serverPath' => '/Users/foo/'
    ),
),

'mysite.com' => array(
    'siteUrl' => 'http://example.com/',
    'environmentVariables' => array(
        'siteUrl' => 'http://example.com/',
        'serverPath' => '/home/mysite_ftp/www/'
    ),
),

// ...

Or you set the Site URL setting in Settings → General to {siteUrl} (the custom siteUrl variable you set in environmentVariables).


As of this comment, Craft 3 is still in beta but you may want to consider it as your challenge sounds like the new Sites functionality may be a good fit.

Sites, allow you to manage multiple websites and multiple languages in one Craft installation. You can find a longer discussion and some examples here:
Managing Multiple Sites in Craft 3 – Sites and Localization

You could create a Site for each combo of Garage and Language that you need to manage. For example:

Garage 1 - French
Garage 1 - German
Garage 2 - French
Garage 2 - German

The blog and other sections for each of these sites could be managed under one channel. Admin users would be able to switch between each subsite just as they switch between locales when editing an entry. User Groups could be created for each subsite as well as the permissions in Craft 3 will allow you to restrict a users access to a specific subsite.

You can read more about how to configure each site in this Localization Guide in the Craft docs. You'll need to configure a couple of files for each site and make sure your DNS is pointing to the right place for each subdomain. But once you get those items setup, you should be able to use the same templates for all of the different sites and languages.


Relational query get error "Getting unknown property"

Because the property sectionId does not exist in the sections table. All models in Craft have the property id as their primary key not - for example - sectionId


Can I stop the logged-in user from selecting other users in the author dropdown?

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

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

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

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


According to Pixel & Tonic:

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

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


Sprout Forms Notifications to Office 365 address failing

This error could be caused by the relationship between the user used in your SMTP Email settings in Craft and the From Address set in your Form notification. Some Mail Servers don't allow the sender (From Address) to be different from the SMTP user. Can you confirm if your From Address is the same email address in your SMTP settings?

Additionally, you may want to update your SMTP settings to use Mandrill or Mailgun. Those services make it pretty easy to look at your sent mail and see if it's being delivered and can provide more insight into what is happening if it is not being delivered.


Private buckets can be used, but files uploaded to them via the Craft CP will be given public read access. Expiring URLs are not built into Craft because the files being public.


From your example, it is a bit hard to tell how your site is organized, but it sounds like you want to set up content specific to each ministry (which is stored in the top-level of your "site_content" structure?), which will be shared across all of that ministry's sub-pages. Regardless, you will essentially want to retrieve the entry where the slider data is stored, and loop through the matrix data from there.

{% if craft.request.segment(2) == "crosstrainers" %}
    {% set entry = craft.entries.section('site_content').slug('crosstrainers') %}
    {% for block in entry.slider %}
        {# prevent error if no slider image is defined #}
        {% if block.sliderImage|length %}
            {% set image = block.sliderImage.first() %}
            <img class="slider-image" src="{{ image.getUrl }}" alt="{{ entry.title }}" />
            ...
        {% endif %}
    {% endfor %}
{% endif %}


How to set Commerce 2 confirmation email in .env file?

Could you use the testToEmailAddress config setting in your config.php? As this will send all emails to a single address.

'testToEmailAddress' => getenv('TEST_TO_EMAIL_ADDRESS')

Then in your .env set:

TEST_TO_EMAIL_ADDRESS="email@email.com"


There's a plugin called CP Field Links which will display field handles and provide easy access to field (and entry type) settings. Please note that the plugin requires devMode to be enabled.

I'm the plugin author, so just get in touch if you have any questions or spot any issues.


Here's a solution using the group filter.

{% set entriesGrouped = craft.entries.relatedTo(category).order('title')|group('myNewCategoriesField.first().title') %}

{% for group in entriesGrouped %}
    {% for entry in group %}

        {# ... #}

    {% endfor %}
{% endfor %}


Craft Commerce: Adding Number fields to product and cart pages

You will need to make use of lineitem "options" param. You can attach as many options as you like using something like:

<input type="number" name="options[numberDistance]" step="any" placeholder="Add your minimum distance in mm..." id="distanceNum">

And then these will be avaliable on the lineItem once saved using

{{ item.options['numberDistance'] }}

More info can be found on the Craft Commerce docs


can i used craft.entries.section into my Controller

If you want to use ElementCriteria in your controller, this is how to go about it:

$criteria = craft()->elements->getCriteria(ElementType::Entry);
$criteria->section('products');
$criteria->limit = 9;

$products = $criteria->find();

Read this page for more info on the subject.


How do I add a block to a matrix that already has content via a plugin?

You can save Matrix blocks directly, without having to re-save the entry.

Craft 2

Use MatrixService::saveBlock():

$block = new MatrixBlockModel();
$block->fieldId = 5;
$block->ownerId = 100;
$block->ownerLocale = 'en_us';
$block->typeId = 2;
$block->sortOrder = 10;

$block->setContentFromPost(array(
    'fieldHandle' => 'value',
    // ...
));

$success = craft()->matrix->saveBlock($block);

Craft 3

Use craft\services\Elements::saveElement():

use Craft;
use craft\elements\MatrixBlock;

$block = new MatrixBlock();
$block->fieldId = 5;
$block->ownerId = 100;
$block->siteId = 1;
$block->typeId = 2;
$block->sortOrder = 10;

$block->setFieldValues([
    'fieldHandle' => 'value',
    // ...
]);

$success = Craft::$app->elements->saveElement($block);


Getting full native language name in Craft3 language switcher

The site.language attribute is just a string, i.e. the language code or locale ID, e.g. 'en'.

To get the native name you'll need to go through the I18N service to pull the actual Locale object via that locale ID:

{% set locale = craft.app.i18n.getLocaleById(lang.language) %}
{{ locale.nativeName }}

Edit: As @Dr_Codswallop mentions in the comments, locale.nativeName is deprecated in Craft 3, and will be removed completely in Craft 4. locale.displayName should be used instead.


Check out: Removing “index.php” from URLs


Your code to get a user returns a UserModel (as can be seen from the Full Class Reference docs):

$user = craft()->users->getUserById($id);

You can then get the user groups the $user is a member of usinggetGroups()(from the UserModel class):

$user_groups = $user->getGroups();


If you're only trying to find related articles based on elements (ie tags, categories, entries, etc), you can use my Similar plugin.

Here's a basic example, more info in the repo:

{% set similarEntriesByTags = craft.similar.find({ element: entry, context: entry.tags }) %}

    {% for similarEntry in similarEntriesByTags %}

{{ similarEntry.title }} ({{ similarEntry.count }} tags in common)

    {% endfor %}