List Only Available Times/Dates in Solspace Calendar

Edited to provide a cleaner solution:

This code will display different contents for available times and unavailable times in 30 min increments, and makes no assumption on how long your events are.

{% set targetDate = "today" %}

{% set events = craft.calendar.events({
    dateRangeStart: targetDate,
    dateRangeEnd: targetDate
}) %}

{% for hour in craft.calendar.day({date: targetDate}) %}
    {% set dateFirstHalfHour = hour.date.copy.addMinutes(30) %}
    {% set dateSecondHalfHour = hour.date.copy.addMinutes(60) %}

    {% set hasEventsInFirstHalf = false %}
    {% set hasEventsInSecondHalf = false %}
    {% for event in events %}
        {% if hour.date >= event.startDate and hour.date < event.endDate %}
            {% set hasEventsInFirstHalf = true %}
        {% endif %}

        {% if dateFirstHalfHour >= event.startDate and dateFirstHalfHour < event.endDate %}
            {% set hasEventsInSecondHalf = true %}
        {% endif %}
    {% endfor %}

        {{ hour.date.format("H:i") }} - {{ hasEventsInFirstHalf ? "unavailable" : "available" }}

        {{ dateFirstHalfHour.format("H:i") }} - {{ hasEventsInSecondHalf ? "unavailable" : "available" }}

{% endfor %}


So it turns out I needed to have the "Options +FollowSymLinks" block above the craft rewrite rule in my htaccess. See comments above.


At this time, there is no manual for it.

It's an incredibly useful chunk of code, but it's buried pretty deep in the system. I think the belief is that "if you're capable of finding it, you're capable of backwards-engineering it."

I'd actually suggest looking to other parts of Craft (and other plugins) to gain a better understanding of some real-world applications and examples.


Will having large numbers of Fields decrease site performance?

I can't answer your question directly as I never got even close to 300 fields yet. But even with 50 fields I had some serious slowdowns, especially when getting related entries in form of assets and such.

I think you should definitely consider using the built in cache function to get good performance.

In regards to that field name / instructions problem you ran into, I can tell you that this is something I hope that gets changed in the future. I already made @Brandon Kelly aware of this problem and he probably has it on "the list".

.

Edit:

After thinking a bit more about this, I'd go with @Simon Kuran and believe that the number of fields have rather negligible moderate impact on your overall performance.

It's more about the numbers of DB queries and not that much about the amount of data they request.
Be careful with building and inquiring relationships in particular, as they can lead to many (unintentional) DB calls. But first and foremost: use caching. The {% cache %} tag is there for a reason! ;)


Limit characters in redactor wysiwyg field

You have to add the JS with a Craft plugin, either a custom one making use of includeJsResource (see this answer for code example) or with the Control Panel JS plugin.


How to get all available tax rates in a Commerce site?

Commerce 2

{% set allTaxRates = craft.commerce.taxRates.allTaxRates() %}

{% for taxRate in allTaxRates %}
    {{ taxRate.name }}

{% endfor %}

taxRate will be an instance of craft\commerce\models\TaxRate

Commerce 1

If you're looking to get all of the tax rates setup in Commerce from a template, something like this should work:

{% set allTaxRates = craft.commerce.getTaxRates() %}

{% for taxRate in allTaxRates %}
    {{ taxRate.name }}

{% endfor %}

taxRate will be an instance of Commerce_TaxRateModel.


I don't think that syntax is possible, and in any case it could get a bit confusing. Why not simply use a single anonymous function and then call your individual handlers inside that e.g.
Event::on(
    Entry::class,
    Entry::EVENT_AFTER_SAVE, function(Event $event) {
        $this->NotifyWhenCookPostedArticle();
        $this->RunSomethingElse();
        $this->DoSomethingDifferent();
    }
);

public function NotifyWhenCookPostedArticle() {
    return 'woop';
}

(Depending on how separate those things are and/or how large and complex you expect the site to be/become, you would typically abstract them further into your Services layer for reusability and encapsulation).


Craft Commerce uses a conversion factor/rate to figure out how to price the others.

Once you add more than one currency to Commerce, it becomes a bit more obvious as to what's going on:

Once you set the Primary/Base currency, every other price will be derived from the base.

So, if you change the primary base currency, you're really only effectively changing the name and the conversion factor/ratio will also be off.

As noted in the docs, Commerce also doesn't keep that conversion rate up-to-date for you.

How to Change the Base Currency

To change the base currency, you would effectively want to change all your prices. However, that's not too difficult—you'd need to export all of your SKUs with the current pricing, change the base currency, and the conversion factors, then reimport the prices at the new base currency's rate.

You'd also want to update any shipping or tax rates as well if necessary.

One thing to consider is the store's base currency is the value you put into the CMS. However, you can show whatever currency you want to the user on the front end and show it as a "default".

If it were me, I'd choose the primary currency that the store's location uses or whatever you use to manage your books then expand out as necessary.


I asked the same question a couple of months back. I was told that it would require some advanced customization to the plugin. It sounded like a pretty big project.


templatecachequeries entries with of 157.000 characters in query column

turns out it was an error in my TablePlus, it truncated the decoded_query to 221 characters.


Ordering Entries without using entry date

I'd suggest changing the Recipe section to a "Structure" section type.

This lets the client order the entries with a drag and drop from the Entries tab where they can see the whole list of entries during the reordering.


Best approach for building a webshop with more than one URL to the same product (entry)

My two cents:

I wouldn't use different url's for the same product, that's considered bad seo. Instead use something like domain.com/product/slug. That way you can change product categories while keeping the links intact, and it'll be easier to get the url of entries.
If there is no specific reason for using structures, use native categories.
Instead of reverse-relations for seo-information, a simpler solution like Sprout SEO might be better.

tl;dr: keep it simple


How to filter what is showed based on radio button checked

You will want to first create an 'elementCriteriaModel' to retrieve only the 'featured' images from the 'thumbnails' asset group, which will return an array like object (not technically an array) which you can loop through to display.

{% set images = craft.assets.group('thumbnails').featured(1) %}
{% for image in images %}

        {{ image.caption }}

{% endfor %}

Another method that might be easier to manage from a client perspective is to add an assets fieldType to your homepage section (called 'featuredImages' or whatever; limited of course to the 'thumbnails' asset group) which the client can use to add and/or reorder the featured thumbnails to be displayed. In which case the code would look something more like this.

{% if entry.featuredImages|length %}
    {% for image in entry.featuredImages %}

            {{ image.caption }}

    {% endfor %}
{% endif %}


Assets Error: Unknown or bad format (years) at position 0 (y)

In case this effects anyone else, here's what I did to get working:

update craft to latest version (in this case 3.1.24)
flush cache using Blitz cache plugin (clear is not enough)
use Cloudfront and not just S3
update all asset indexes in cms

That seemed to have done the trick.


Smart Map - Output map locations from relationship file in a matrix

At a glance, your code looks perfect... but I think there's a subtle error. The locations parameter can be an array of elements, but you are building an array of Address fields (which is not valid).

https://plugins.doublesecretagency.com/smart-map/render-a-map-in-twig/

You can simplify the middle part of your code to this:
{# add entry to locations array #}
{% set locations = locations|merge([member]) %}

That way, locations will end up being an array of elements.


Redactor adding extra paragraph and br tag when entering and exiting HTML source mode

This appears to be an issue with Redactor itself. Their example allowing you to edit the source code of a field has the same bug.


'cacheDuration' => false, sets cache file expiration date to 1 year

Yeah, it's slightly awkward.

First off it should be '0', instead of false if you want it to cache indefinitely (documentation bug, just fixed).

It's slightly awkward because the cacheDuration config setting is used for multiple things, but when the TemplateCacheService uses it, it requires an expiration date (not optional).

So if it sees 0, it will just pick one reasonably far out (a year), but you can set it to something higher if you want.

What should probably happen is everywhere that uses the cacheDuration config setting should have its own, separate config setting.

Not going to happen for Craft 2, but make a note to look at it once Craft 3 launches.


Comparing date field object with global variable "now" gives unexpected result

now represents the current DateTime so unless you specify exactly the correct time in your field the condition deliveryDate == now will never become true. If the user visits the page one second earlier or one second later the condition will fail.

For example: if your date is 2018-06-13 12:00:00 and now is 2018-06-13 12:00:01 both of your conditions will always fail. now|date_modify("+ 1 day") will result in 2018-06-14 12:00:01 and 12:00:00 is not 12:00:01

you'll need to equalize the time or format it differently

{% if deliveryDate.modify('midnight') == tomorrow.modify('midnight') %}

or

{% if deliveryDate.format('Y.m.d') == tomorrow.format('Y.m.d') %}

You can read more about it in the docs


Why are the email settings fields not showing, and how do I fix this?

Since I was short on time I ended up reinstalling Craft. Not exactly a minimum effort solution, but it fixed the backend > settings > email problem (and the updates page, that was not functioning properly as well). However, new install would not show my plugin in backend > settings > plugins. The solution to this, was to create a bare minimum test plugin (just copy pasted from https://craftcms.com/docs/plugins/setting-things-up), after which both the test plugin and my real plugin showed up in backend. All seem ok now.


You can access a category's fields exactly like you
access an entry's fields.

{{ category.myLightswitch }}

So this should do it for your categories loop:

{% for entry in entries %}
    {% for category in entry.myCategoriesField %}

        {{ category }}

        {% if category.myLightswitch %}
            EXTRA
        {% endif %}

    {% endfor %}
{% endfor %}


Most servers (speaking in generalities) won't send mail by themselves anymore. You'll need to use some sort of SMTP service.

Check out SendGrid to get you going. I believe they have a free plan. You can choose SMTP from the mail options from the settings page.

Choose 'Use Authentication' and from there your username is well, your username and your password is...your password. Use Port 587.

Hope this helps!


You're getting the error because of Twig's operator precedence. Filters take priority over math.
So basically Twig was trying change var2 to a percentage first instead of using the results of the math expression first, ie:
{{ var1 / (var2 | percentage) }}
Generally this behavior is usually what you want but sometimes there's edge cases where it doesn't work out. As you figured out, putting parenthesis around expressions to group them is never a bad idea especially when filters are involved.


It looks like you're trying to access another asset within your assets (asset meta field).

{% set photos = entry.photos %}

{# Loop assets of `entry.photos` as `photo` #}
{% for photo in photos %}

    {# Get first `uploadPhoto` element within `entry.photos[nth]` #}
    {% set image = photo.uploadPhoto.first() %}
    {{ image.getUrl() }}

{% endfor %}

I guess that's not what you want. Check your field handles again, you probably only need to do this.

{% set photos = entry.photos %}

{% for photo in photos %}
    {{ photo.getUrl() }}
{% endfor %}

If 'uploadPhoto' is an asset source and you allow users to upload to multiple sources, but only want to loop assets from 'uploadPhoto' in your template, you would do this like so.

{% set photos = entry.photos.source('uploadPhoto') %}


{% requireLogin %} not returning to original page

I may be missing something here, but you probably just want to remove the postLoginRedirect setting from the config?
You could also try adding {{ redirectInput(craft.app.user.returnUrl) }} to the form.
craft.app.user.returnUrl should return the URL that triggered the login.


Craft's uses the Twig templating language. The official Twig documentation http://twig.sensiolabs.org is really good, highly recommended to read most of it!

For your specific problem have a look at the section about the extends tag. It explains how to define blocks and extend other template files. Another important technique is including partials into a template with the include tag.

For a good and rather simple example I would recommend to read the source code of Pixel and Tonic's On The Rocks Craft demo page.


Upload images bigger than 1MB not working

Nginx's setting client_max_body_size was set to its default value of 1M because it was not specified after provisioning the DO server with Laravel Forge. Weird thing is just that the user doesn't get any response.

Solution: Set client_max_body_size to something higher or 0 in your Nginx config file.


Get all categories from a CategoryGroupModel through API

I've found that it was not the best way to to it.
I used the following code and it cleared my problem.

$criteria = craft()->elements->getCriteria(ElementType::Category);
$criteria->group = 'productEnvironment';
$entries = $criteria->find();

foreach ($entries as $entry) {
    echo $entry->title . '
';
    echo $entry->mountingPreview[0] . '
'; // Dirty get the first assets
}

Hope this helps someone


Enable the user to upload multiple background Images that come from a matirx loop

So I have figured out the answer to my own questions it turns out that I needed to use a {{ counter }} that incremented the class name in both the  tag where the .mid-banner class is defined so that each time the loop runs it add 1 to the class. The stars show the code i have added:

{% for block in entry.homeMatrix %}
    {% if block.type == "homeMatrix" %}
    {% set oddOrEven = cycle(['even', 'odd'], loop.index0) %}

{{ block.txtTitle }}

                {{ block.txt }}

        **{% set counter = ( counter | default(0) ) + 1 %}**
        {% for image in block.image %}

        {% endfor %}

{{ block.imageTitle }}

    {% endif %}
{% endfor %}


Updating Asset indexes is pretty coupled to the tool in the Settings portion of the control panel.

But if you wanted to try and duplicate that functionality in a plugin, you could have it listen for the onLogin event to do your business.


Contact Form Plugin P&T redirect issue with locales

Remove 'usePathInfo' => true, from your /craft/config/general.php

This fixed a similar error on my site.


The answer here is to disable the mod_security2 rule on the admin folder as I was tripping the SQL Injection prevention rule (#300015) upon saving the Entry form.

This is a server setup that uses cPanel and Apache 2.2.

Edit file:

/usr/local/apache/conf/modsec2/whitelist.conf

Add the following rule:

<LocationMatch "/admin/">
  SecRuleRemoveById 300015
</LocationMatch>


How do I find the category an entry belongs to?

If I'm following you, you've got a category group setup with a color field on its field layout.

Then you've got a category field setup with it's source set to that category group and in an entry, you want to get to the color field on the category group.

{% for entry in entries %}

    {# Grab the first category #}
    {% set category = entry.categoryFieldHandle.first() %}

    {#
        Or if there are multiple categories...
        set category = entry.categoryFieldHandle.find()
        And loop through to find the one you want
    #}

    {{ entry.title }}
{% endfor %}


Craft plugin for input fields on the front end to check existing user

If you are creating these as actual users in Craft, it should be possible to do it straight from the template without the need for a plugin, as long as you have Craft PRO (without PRO you anyways wouldn't be able to create more than one "admin" user, and one "client" user anyways):

See the documentation here:
https://craftcms.com/docs/templating/craft.users#email

Basically, you should be able to call craft.users.email('your.email@address.com') to check if it exists. Again, I haven't tested this myself, but it will then return the user if it exists, and otherwise I assume it will return null.


Option and notes fields after cart at checkout for order, not just line items

First, add a custom field to your orders, let's call it orderNotes.

Then, in any updateCart form, you can use an input with name="fields[orderNotes]" to set the value of that field.

(Line items persist on the cart until the end of checkout.  At that point they become a saved snapshot of those line items on the completed order.)

<form method="POST" >
       {{ getCsrfInput() }}
       <input type="hidden" name="action" value="commerce/cart/updateCart">
       <input type="text" name="fields[orderNotes]">
       ...etc


Search Plus: Target different indices from different environments

You could check your config for an environment variable and change the name of the index that's searched depending on what environment you're in.

On my SearchPlus integration the index name is set as a data attribute on the search component, so it's possible to vary the index based on the environment:

{% set indexName = 'myindex_test' %}

{% if craft.config.craftEnv == 'production' %}
    {% set indexName = 'myindex_live' %}
{% endif %}

<div class="searchplus" data-index-name="{{ indexName }}">
...
</div>

The search JavaScript reads in the data attributes on initialisation and sets up the Algolia index based on the value of data-index-name.

Note: I'm using this with Craft 2. I understand that you can access config values in Craft 3 via craft.app.config.general.<value>.


Since it looks like the solution does not exist yet, I ended up creating custom plugin/gateway.

Works same as Manual gateway with the only difference that it only approves free purchases.

https://github.com/intoeetive/freecheckout


Commerce 'Edit Order' page taking 10 seconds or more to render

Just some data for comparison - on our production server, an individual order comes up in a tad less than 2 seconds...(and on local dev it's much the same actually).

Are you up to date with Commerce as there was some work on this I believe: https://github.com/craftcms/commerce/issues/828 (so version 2.1.5 & above should be better).

Or perhaps you have some very expensive custom field stuff attached on your orders??


Sort entries by time part only of DateTime object

For those interested, I found out you can tell Craft to search the database for the time part only with the mySQL command time() (Order entries by custom time field). For example:

{% set shows = craft.entries({
  section: 'shows',
  relatedTo: day.id,
  order: "time(startTime)",
}) %}

However, this sorts based on the absolute DB time (GMT time), so I substituted a conversion command for startTime:

{% set convertedStartTime = 'convert_tz(startTime,"+00:00","-06:00")' %}

{% set shows = craft.entries({
  section: 'shows',
  relatedTo: day.id,
  order: "time(#{convertedStartTime})",
}) %}

To my complete shock, this actually works. I could not find a similar way to search for the current show, so I first filtered entries by day, then ran a for-loop to find the current show (there's only ten shows or so per day):

{% set todaysShows = craft.entries({
  section: 'shows',
  relatedTo: today,
}) %}

{% for show in todaysShows if not done %}
    {% set start = show.startTime | date_modify('now') %}
    {% set end = show.endTime | date_modify('now') %}

    {% if now >= start and now < end %}
        {% set nowPlaying = show %}
        {% set done = true %}
    {% endif %}

  {% endfor %}`


Add product to cart using code in Craft Commerce plugin

I managed to figure this out. Below is the code:
$theOrder = $event->sender;
$myProduct = \craft\commerce\elements\Product::find()->id([$giftProductId])->one();
if($myProduct){
    $myPurchasable = $myProduct->getDefaultVariant();
    $newOrExistingLineItem = \craft\commerce\Plugin::getInstance()->getLineItems()->resolveLineItem($theOrder->id, $myPurchasable->id, []);
    $theOrder->addLineItem($newOrExistingLineItem);
}


Programatically change a lightswitch value on an entry on save

You can set the value and save like so:

craft()->on('entries.onSaveEntry', function(Event $event)
{
    $entry = $event->params['entry'];
    if ($entry->section == 'mySection') {
        if ($entry->getContent()->myLightSwitchField == 1) {
            $entry->getContent()->setAttributes(array(
                'myLightSwitchField' => 0
            ));
            craft()->entries->saveEntry($entry);
        }
    }
});

However, you might consider using onBeforeSaveEntry so that you don't have to save the entry twice (and/or run the risk of creating an endless loop).

craft()->on('entries.onBeforeSaveEntry', function(Event $event)
{
    $entry = $event->params['entry'];
    if ($entry->section == 'mySection') {
        $entry->getContent()->setAttributes(array(
            'myLightSwitchField' => 0
        ));
    }
});


There is a Redactor setting that should do what you’re looking for:

  Stucture
  This settings introduces visual indicators for HTML tags h1-h6 and div, helping users understand the structure of the document.

https://imperavi.com/redactor/docs/settings/special/#setting-structure

Example editor:
https://imperavi.com/redactor/examples/structure/


Base fieldtype validation working with model validation?

Completely untested and this whole pattern feels hacky to me, but something like this should work:

From your field type:

public function validate($value)
{
    if(is_array($value) && $value['type'] != '')
    {
        // Validate the field type.
        $errors = parent::validate($value);

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

        $linkModel = $this->_valuetToModel($value);

        // Validate the model.
        $validated = $linkModel->validate();

        return $validated && empty($errors) ? true : array_merge($linkModel->getAllErrors(), $errors);
    }

    return true;
}

From your model:

public function validate($attributes = null, $clearErrors = true)
{
    switch($this->type)
    {
        case('email'):
            if( !filter_var($this->value, FILTER_VALIDATE_EMAIL) )
            {
                $this->addError('value', Craft::t('Please enter a valid email address.'));
            }
            break;

        ....

    }

    return !$this->hasErrors();
}


Retrieving an entry by ID in ALL locales

I don't think this is possible witout the use of a plugin. The craft.entries tag works on an entry basis. The slug is saved in the table that houses the localized data for an element, craft_elements_i18n. When you request an entry, (in theory) the craft_entries table is joined with the craft_elements table (based on id), which is then joined with the craft_elements_i18n table (based on locale). There's no way you could join in data from several different locales this way.

What you have to do is query the craft_elements_i18n directly, and return all rows based on the entry id (elementId in that table is the entry id), and then you'd get locale, slug, and url. This table isn't exposed in any way to the templates, so you'd need to do it with a small plugin. It will still be one query to do this, though.

I think maybe this is more work than what it's worth, unless you have loads of locales, the difference in performance will be very, very small. Also, you could cache this in your templates, which would make it even less of an issue.


Can entries be returned based on checkbox selection?

You'd better double check for a typo because you actually got the syntax right for the search parameter.

search('myField:myString') filters all entries where a field with handle "myField" contains a string "myString". What you have should totally work to get the entries with a checkbox field handle "zone" and the value of the checkbox option being "pupil".

If you're sure that there's no typo and you actually have entries that match the criteria, I'd try if it helps to rebuild the search indexes (tool in the CP settings). I actually try to avoid using the search parameter if possible, because things can go wrong with the indexes. Unfortunatelly I don't think there's other ways to filter by a checkbox field.

Other posibillity: If you don't want to paginate the entries or use other methods that are not available on custom arrays of entry models, what about filtering them with a simple conditional:

{% set entries = craft.entries %}

{% for entry in entries if entry.zone.contains('pupil') %}
    {{ entry.title }}
{% endfor %}


Try

{% set currDay = now|date('M j, Y H:i:s') %}
{{ currDay }}

Applying the |date() filter to the now object when you set the variable currDay makes currDay a string. When you then try try to reapply |date() a second time, something funny must be happening..?


Pass params to transform function of Transformer class in split Transformer class

Here's how you would do that...

Pass your parameter to the class:

'transformer' => new MyTransformerClassName($user),

Use a constructor to save it as a property:

class MyTransformerClassName extends TransformerAbstract
{
    private $user;

    public function __construct($user)
    {
        $this->user = $user;
    }

    public function transform(Entry $entry) ...
}

Use your property as needed:

class MyTransformerClassName extends TransformerAbstract
{
    private $user;

    public function __construct($user) ...

    public function transform(Entry $entry)
    {
        return [
            'user' => $this->user,
            ...
        ];
    }
}


Element API: PHP Error: Fatal error: Allowed memory size of 33554432 bytes exhausted

Your php.ini file's memory_limit setting is set to 32M.

You'll want to bump that up to something higher like 256M.


I think you're checking correctly with {% if variantImage not in productGalleryArray %} (this should check if variantImage isn't already in the array), but your code doesn't seem to set a productGalleryArray array in the global scope. Variables initially set inside for loops are scoped only to that for loop.

So I think you just need to declare an empty array at the top of your code outside and before the first for loop:

{% set productGalleryArray = [] %}


How to create an advanced route with query strings?

You can do this completely in the template. Have the structure entries resolve to a route like gallery/_router and then inside that template you could use this code to include the template of your choice:

{% switch craft.app.request.getParam('type') %}

    {% case "gallery" %}

        {% include "gallery/_entry" %}

    {% case "anotherParam" %}

        {% include "gallery/_anotherParam" %}

     {% default %}

        {% include "gallery/_default" %}

{% endswitch %}


From your last update it looks like you simply need to get the entry that contains that matrix block, the error Variable "entry" doesn't exist simply means nothing is assigned to entry in your templates. There are a couple of ways you can solve this:

Option 1 - Tell Craft which template to load for this entry

If you go into your section settings, there will be a field called Entry template which if, for example, you put about in this craft would look for either about.html or about/index.html in your craft/templates folder and would automatically assign a variable entry to your template when you visit the /about url.

There is also an option This is for the homepage in the settings which, if checked, will assign the entry to index.html in your templates (but i don't think this will show if there is already a section checked elsewhere)

You can see more about this in the craft docs: http://buildwithcraft.com/docs/templating-overview

Option 2 - Fetch the entry in your template using twig tags

There are numerous ways to do this, but given you are using a single you should just be able to use this:

{% set entry = craft.entries.section('homePageBanner').first() %}

You might need to adjust the homePageBanner part if that isn't the handle of your section, but this will then give you an entry variable to work with in your template and hopefully you'll find you will get the matrix content back :)

If you need some more details on how craft.entries works then the docs are a great place to find out more: http://buildwithcraft.com/docs/templating/craft.entries


There is an entire section here that discusses API integrations, including the ones that come with Freeform.  http://docs.solspace.com/craft/freeform/v2/


Advanced Search with tags and categories

Before I answer your main question, I'm seeing a couple issues with what you’re currently doing that are worth correcting.

First, this code:

{% set supplierCat = craft.categories.group('supplier').slug(supplier).first %}
{% set productCat = craft.categories.group('product').slug(product).first %}
{% set deliveryCat = craft.categories.group('delivery').slug(delivery).first %}

should be replaced with:

{% set supplierCat = supplier ? craft.categories.group('supplier').slug(supplier).first %}
{% set productCat = product ? craft.categories.group('product').slug(product).first %}
{% set deliveryCat = delivery ? craft.categories.group('delivery').slug(delivery).first %}

in case any of the supplier/product/delivery params are blank.

Next, this code:

{% set supplierParam = supplier ? {targetElement: supplierCat} : '' %}
{% set productParam = product ? {targetElement: productCat} : '' %}
{% set deliveryParam = delivery ? {targetElement: deliveryCat} : '' %}

should be replaced with:

{% set supplierParam = supplierCat ? {targetElement: supplierCat} %}
{% set productParam = productCat ? {targetElement: productCat} %}
{% set deliveryParam = deliveryCat ? {targetElement: deliveryCat} %}

That way you will avoid unexpected behavior if a supplier/product/delivery was posted, but it had an invalid slug, and yielded no results. Also, the : ''s at the end are just not really necessary unless your really wanted them to be strings by default (no reason in this case though), as Twig will default the values to null, which is just as good.

Also, you can’t chain multiple relatedTo params together like this:

.relatedTo(productParam).relatedTo(deliveryParam)

When you do that, the second relatedTo param will just override the 1st one.

Instead you’d need to do something like:

{% set relationParams = [supplierParam, productParam, deliveryParam]|filter %}

{% set entries = craft.entries({
    section: 'suppliers',
    relatedTo: relationParams ? ['and']|merge(relationParams) : null,
    search: query,
    homeGrown: homeGrownParam,
    preparedProduce: preparedProduceParam,
    redTractor: redTractorParam
}) %}

(I’m using the {p1: v1, p2: v2} syntax for setting the criteria params here for clarity, but you can use the p1(v1).p2(v2) chaining syntax instead if you prefer it.)

With that out of the way…

To support searching for entries that are related to multiple suppliers/products/deliveries at the same time, the first thing you’ll need to do is update your search form. I know you said you want to go with checkboxes, but for simplicity’s sake I’ll demonstrate with multi-select boxes, since that’s closer to your original code and produces the same request param data.

For each of your <select>s, just append a [] to the input name and add the multiple attribute:

<select name="supplier[]" multiple>
...
<select name="product[]" multiple>
...
<select name="delivery[]" multiple>
...

In your search results template, change .first to .find() when fetching the categories:

{% set supplierCat = supplier ? craft.categories.group('supplier').slug(supplier).find() %}
{% set productCat = product ? craft.categories.group('product').slug(product).find() %}
{% set deliveryCat = delivery ? craft.categories.group('delivery').slug(delivery).find() %}

And assuming you want this to be an inclusive search (where only results with all of the selected suppliers should be included, etc.), you’ll need to prepend 'and' to each of the targetElement arrays:

{% set supplierParam = supplierCat ? {targetElement: ['and']|merge(supplierCat)}l %}
{% set productParam = productCat ? {targetElement: ['and']|merge(productCat)} %}
{% set deliveryParam = deliveryCat ? {targetElement: ['and']|merge(deliveryCat)} %}

That’s it. The rest can stay the same.


Craft 3: Preventing Element from Saving in Plugin

The event fired by element service is not cancellable, as that is a bit too broad to be controlled like that. Instead, you should be listening to the EVENT_BEFORE_SAVE on the User element as that supports the isValid property.

use craft\events\ModelEvent;
use craft\elements\User;
use yii\base\Event;

Event::on(User::class, User::EVENT_BEFORE_SAVE, function(ModelEvent $event) {
    $event->sender->addErrors([
        'password' => 'Passwords do not match.'
    ]);
    $event->isValid = false;
});


Craft Equivelent of EE addon CE Image Bulk Tag?

You can do the same thing using the Retcon plugin for Craft. Have a look at the wiki entry for the transform filter for more details.


Can you delete rows from a table field on the front end?

It can be done, but only by saving the table field's data completely. There's no controller method to remove a table's row(s). Same would apply for a table within a Matrix block, or for a Matrix block itself. All content gets saved by calling the entries controller (saveEntry) with the new content in a POST.

What you could do: Let your users create one or more matrix blocks, create your own plugin, create a controller with an actionDeleteMatrixBlockById() method (for instance) and let that controller call craft()->matrix->deleteBlockById() if one of the blocks has to be deleted.

Bit of a hassle, though. Don't know your use-case, but seems a bit overkill.


How do you eager load or join reverse relationships for entries?

Ok so here's how I ended up doing this. Essentially querying everything and adding a sourceId and targetId property to each result. In order to get this query to work though, we need to add a behavior to the Entry component to support two new properties, sourceId and targetId.
// This basically left-joins the the relationship table to our sections. This allows us
// to essentially "eager-load" in reverse.
$relatedQuery = Entry::find()
  ->section(['healthTopics', 'providers', 'locations'])
  ->addSelect('relations.targetId')
   ->addSelect('relations.sourceId')
   // You can query to get the field ids here, I just decided to look them up in the db.
    ->leftJoin(
               '{{%relations}} relations' ,
                '([[elements.id]] = [[relations.sourceId]]) AND ([[relations.fieldId]] = 2 OR [[relations.fieldId]] = 5)'
            )
    ->groupBy('elements.id')
    ->all();

    // Same thing here, just looked up the section ids instead of querying for them.
    $healthTopics = ArrayHelper::where($relatedQuery, 'sectionId', '1');
    $providers = ArrayHelper::where($relatedQuery, 'sectionId', '3');
    $locations = ArrayHelper::where($relatedQuery, 'sectionId', '2');

Next, I needed to add a behavior to the Entry component so that it could support having the two new properties we added, sourceId and targetId.
<?php

namespace foo\behaviors;

use yii\base\Behavior;

class EntryBehavior extends Behavior
{
    public $targetId;
    public $sourceId;
}

Event::on(Entry::class, Entry::EVENT_DEFINE_BEHAVIORS, static function (DefineBehaviorsEvent $event) {
    $event->behaviors['entryBehavior'] = ['class' => EntryBehavior::class];
});


Craft not Downloading Auto Update - HttpException on OS X PHP56

So the issue appears to be with php56: after uninstalling 56 and installing 55 craft works as expected.


Yes, you can do all the normal commerce actions via ajax.

A basic recipe is this...

HTML:

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

JS:

        $form = ("#addToCartForm");
        var form_data = $form.serializeArray()
        form_data.push({
            name: window.csrfTokenName,
            value: window.csrfTokenValue
        })

        $.ajax({
            type: 'post',
            url: '/',
            data: form_data,
            success: function(response) {
                if (response.success) {
                    alert(response.cart)
                }
            ...etc

....response.cart will have the updated cart in it.


ContactForm – How to make fields required

For form validation I typically use Parsley.js - it's dead easy to use.


How to compare currentUser with entry.author?

Try this:

{% if currentUser.id == entry.author.id %}

When using quotation marks, it means that it's a string in Twig. What you want to do is compare the value of the actual variable.

Also, currentUser is a UserModel, so you need to get the id property to compare it with entry.author.id.


To display a single category you'll need to do something like this:
{% set category = entry.categoryfieldhandle.one() %}
{{category.title}}

To display multiple categories:
{% set categories = entry.categoryfieldhandle.all() %}
{% for category in categories %}
{{category.title}}
{% endfor %}

Replace categoryfieldhandle with the handle you used for your field.
You can find more in depth and alternative ways in the docs:
https://craftcms.com/docs/3.x/relations.html
Since you're new to craft I recommend taking a look at the following course https://craftquest.io/courses/craft-cms-3-tutorials to help get you started.


Rounding down issue with commerceCurrency filter

It looks like there is currently a Github issue/feature request for this that is on the Commerce 3.0 milestone: https://github.com/craftcms/commerce/issues/695


Craft\WebApp and its behaviors do not have a method or closure named "getInfo"

Sounds like some of Craft's files are missing.  Try downloading the latest release from buildwithcraft.com and re-uploading the craft/app folder and see if that solves it.

Update:

Since the OP sent a ticket into support, I'll update that re-uploading the craft/app folder solved the problem.


landscapeMd and portraitMd are variables... they would need to be strings (or array keys) for this to work.

Try something like this:

{# medium 16:9 #}
{% set landscapeMd = {
  width: 439,
  height: 247,
  quality: 80,
} %}

{# medium 9:16 #}
{% set portraitMd = {
  width: 278,
  height: 494,
  quality: 80,
} %}

{% set transforms = {
  'landscapeMd': landscapeMd,
  'portraitMd': portraitMd
} %}

{% for block in entry.productCollage %}
  {% switch block.type %}
    {% case "digitalProduct" %}
      // selected via dropdown field
      {% set transformType = transforms[block.imageAspectRatio.value] %}

        {% for image in block.image %}

        {% endfor %}

  {% endswitch %}
{% endfor %}

This maps the transforms with the transforms object, then references the key in transforms[block.imageAspectRatio.value].


Order Confirmation Email in Craft Commerce

To setup/debug email issues in commerce it's easiest to set up the simplest possible email and work your way up from there.

Check your Craft email settings - can you send & receive the test email
successfully?
In Commerce settings, double check you have created your email correctly and that your template exists at the path you set.  To simplify
things initially, avoid using any variables in the subject and hardcode
an address to which the email will be sent
Check your order status and make sure you have assigned your email to it and that a '1' then appears in the 'Has Emails' column for that
status.  It's easiest to start with an email attached to the default
order status so you can be sure orders coming in will trigger the
email.
Create the simplest possible template for the email and just put in it something like Huzzah, my email sent! as an initial end
to end test that the email is being triggered when you submit an order

At that point, your basic email should really send!

If not, check your commerce.log file for errors.  If you have parsing errors in your email template, they will appear here, or you may get the somewhat obscure [info] [plugin] [Forced] Can't send email if no status or emails exist. which indicates something is wrong with the set up of the status <> email relationship.

Most of the errors typically come from template errors in the actual email - trying to get data not available for example.  commerce.log will help with that, but another handy way of debugging your email templates is to put something like this at the top of them:

{# for debugging! #}
{% if craft.request.getSegment(1)=="order-completed-debug" %}
     {% set order = craft.commerce.orders.id(craft.request.getSegment(2)).first() %}
     {# No order supplied or other issue?  Load latest order by default... #}
     {% if not order %}
         {% set order = craft.commerce.orders.first() %}
     {% endif %}
{% endif %}

Set up a route in Craft settings so that /order-completed-debug/(number) points at your email template and then you will be able to use your browser for much easier testing by going to /order-completed-debug/<someValidOrderID> in your browser rather than having to submit an order each time you change your email template!

Finally, I very strongly recommend you use a transactional email service like mailgun, sparkpost, postmark, mandrill etc. as if you use default phpemail you're very likely to run into email delivery issues.  The logging systems these (often free!) transactional email systems supply are worth their weight in gold as you can see if the email is even being sent or not very simply, which helps with issue diagnosis a LOT.

For completeness, although this is a lot more advanced & less general:

Another gotcha to note is that custom order fields are not necessarily set yet in the order completed email template as it seems this is actually sent out BEFORE the final order save occurs so if you're e.g. setting some data in a plugin method listening to onBeforeOrderComplet=, you'll need to work around this....so to reference those fields you have to use a special approach (currently?)

{% set ISOrderNumber = order.content.ISOrderNumber ?? 'NONE' %}

Not the use of .content there - I need to use this to get at the field that is not yet saved in to the order as such.


_entry.twig isn't reading css while index does

Are you using a relative file path? Try to omit them where you can and see if it resolves?


Front end assets uploading, does not appear to be a an image error

The issue lies if you have a Preparse field in that field layout, see details here: https://github.com/aelvan/Preparse-Field-Craft/issues/23


Possible to Directly access related records (Laravel ORM style)?

Not 100% sure I'm following what you're looking for, but if you have a UserRecord defined with a phone relation, then something like this should do what you want:

$phone = UserRecord::model()->with('phone')->findById(1)->phone;


Is it possible to set a new route for a plug-in CP section in Craft 3?

Of course you can Link

Event::on(UrlManager::class, UrlManager::EVENT_REGISTER_CP_URL_RULES, function(RegisterUrlRulesEvent $event) {
    $event->rules['whateveryoulike'] = ['template' => 'cocktails/_edit'];
    $event->rules['cocktails/<widgetId:\d+>'] = 'cocktails/edit-cocktail';
});

So the url www.example.com/admin/whateveryoulike redirects you to the template cocktails/_edit. You don't need to use the plugin-handle, you can overwrite everything but you have to make sure no other plugin overwrites your routes..


Cannot get file upload/attachment with Sprout Forms working

Figured out what my problem was: I was trying to submit the form via Ajax, that's why the submit button is set to input type="button"
I changed the submit button to input type="submit" & it worked.
Not 100% sure how to make it work with Ajax but pretty sure it has something to do with the way the data is serialized. I don't really need Ajax submission in this instance, so not bothering with it anymore.


Ok, found an answer that made it a bit clearer:
How do I get elements using getCriteria from a specific date?

Basically you can do this:

$criteria = craft()->elements->getCriteria(ElementType::Entry);
$criteria->postDate = '>'. date('Y-m-d', strtotime("-4 weeks"));
$result = $criteria->find();

To get Entries form a month back.


How do I create a custom Twig extension which includes third party code?

Douglas McDonald's answer is correct with one issue though. The import statement is actually case sensitive

  Craft::import('plugins.myplugin.twigextensions.MyTwigExtension');

I also have 2 additional notes:

The getName() method is deprecated so you shouldn't bother with it
The getFilters() method can be written much shorter, for example:

public function getFilters()
{
    return [
        'myfilter' => new \Twig_Filter_Method($this, 'myfilter'),
    ];
}


How can I upgrade to version 3.0 as a user?

Upgrade instructions are found here, although i wouldn't recommend it as an end user. You want to backup your database in case something goes wrong, change file paths/content, etc. Even if you have the access and knowledge to run the scripts, you should have a developer do this for you.


Migrate multiple Craft 2 CMS sites on cPanel

Have you checked the permissions on the sever? As 500 usually comes due to server permissions or due to wrong .htaccess or wrong Rewrite file. Have a look at .htaccess file.
And make sure to check your server error logs, they might provide you some valuable input for the errors.

If you find some specific errors, please share them so the community could help you better.


Passing Multiple Relation Criteria In Plugin

I need someone more experienced with Craft to vet this, but it seems that this is working:

Supplying an array to relatedTo returns results if it matches one OR the other entry.

$projectCriterea = craft()->elements->getCriteria(ElementType::Entry);
$projectCriterea->section = 'projects';
$projectCriterea->relatedTo = [$themeEntry, $yearCat];
$projectResults = $projectCriterea->find();

If you supply "and" as the first entry in the array, it only returns results that are related to BOTH entries.

$projectCriterea = craft()->elements->getCriteria(ElementType::Entry);
$projectCriterea->section = 'projects';
$projectCriterea->relatedTo = ["and", $themeEntry, $yearCat];
$projectResults = $projectCriterea->find();

This was figured out by tinkering and guessing, hence I'm not sure it's the "correct" way to do this. It also doesn't let me search individual custom entries type fields, but this does do what I was after.


Edit multiple entries at once through the front-end

Couldn't you have multiple forms on the page, and submit them via AJAX in sequence when the user clicks on the Submit button?


I'm not 100% clear on exactly what you're looking for, but I'll just throw this out there.  Matrix content is saved in their own tables (table names are dynamically generated on a per-field basis) as opposed to most other fields, which have their content saved in the craft_content table.

You can look in MatrixService for methods needed for managing Matrix fields.


Add settings to plugins cp section instead of settings page

Solution

In my src/template/index file I added this to make the form work

{% extends "_layouts/cp" %}
{% import "_includes/forms" as forms %}

<form action="" method="post">
{{ csrfInput() }}

{{ forms.hidden({
    name: 'action',
    value: 'craft-terms-of-service/default/save-tos'
}) }}

{{ forms.hidden({
    name: 'tosCurrentVersion',
    value: now.timestamp
}) }}

{{ forms.lightswitchField({
    label: 'Enable TOS?'|t,
    id: 'tosEnabled',
    name: 'tosEnabled',
    on: craft.craftTermsOfService.get('tosEnabled'),
    first: true
}) }}

{{ forms.textField({
    label: 'Headline'|t('craft-terms-of-service'),
    instructions: 'Enter the headline of your TOS here.'|t('craft-terms-of-service'),
    id: 'tosHeadline',
    name: 'tosHeadline',
    value: craft.craftTermsOfService.get('tosHeadline')
}) }}

{{ craft.craftTermsOfService.redactorField({
    label: 'Terms of Service'|t('craft-terms-of-service'),
    instructions: 'Enter the TOS every user must accept before using the site below.'|t('craft-terms-of-service'),
    name: 'tosBody',
    rows: 4,
    value: craft.craftTermsOfService.get('tosBody')|raw
})|raw }}

<input type="submit" class="submit btn" value="{{ 'Save'|t }}">

Using the actions/craft-terms-of-service/default/save-tos controller I took the data from the request and updated the data in the plugins table. Also in the form in my index template I used the craft.craftTermsOfService.get variable to fetch the settings from the plugins table and give each form element its appropriate value.

For details, see the controller on github and the variable on github. Note this is the first time I make a plugin, so it's probably a mess, sorry about that.


Unable to retrieve a cookie set by another application on the same domain

Is there any way I can get around this without resorting to my own PHP in the template or a custom plugin?

You can't have PHP is a Twig template, but I think you'd need a real simple plugin for this.

It would just have an init() method that did:

craft()->request->enableCookieValidation = false;

Just be aware that's going to make it much easier for people to potentially tamper with cookie values.


Can anything be done to suppress or limit the clickable area of the checkbox in a Matrix block header?

Not really an answer, but have you considered posting a feature request on the feedback site?

http://feedback.craftcms.com


When using "Title Format", quotes in fields are entitized when saving to title field

I've discovered a solution:
set the title format to {firstName|raw} {lastName|raw}

Should I just proceed that way?


Access pages data with fewer queries by creating an object in Twig

So the only database queries in your example will be generated by:

{% set navigation = craft.entries.section('pages').all() %}

So creating an additional object doesn't serve the stated purpose of saving db queries. You can just access the navigation array directly.


Remove duplicated entries from SuperTable related entries

The simplest way is to create a "filtered" array, containing the unique cables, and then loop through that.

For example:

{# Build the "filtered" array of cables #}
{% set filteredCables = [] %}

{% for row in entry.tests %}
    {% for cable in row.cables %}
        {% if cable.title not in filteredCables %}
            {% set filteredCables = filteredCables|merge([cable.title]) %}
        {% endif %}
    {% endfor %}
{% endfor %}

{# Output the unique cables #}
{% for cable in filteredCables %}
    {{ cable }}<br />
{% endfor %}


How can I programmatically set the value of an Entries field type?

For relationship fields (Entries, Assets, Users, Tags, etc.) you need to pass in an array of element IDs.

Something like this should work.

$entry->setAttribute('companyField', array($companyEntry->id));


You'd need to make a simple Craft plugin that added a Twig filter/function that wrapped PHP's file_get_contents to grab the file contents, but at that point, you might as well just make it a wrapper for craft()->request->sendFile().


how to access to event object propereties

I assume both text and id_str are custom fields?

$event->params['entry']

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

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


Check and remove repeat entries from loop

I'd probably try to filter those out in your initial query, but if you've already got them, something like this should work:

{% set existingIds = [] %}

{% for event in events %}
    {% if event.id not in existingIds %}
        {{ event.title }}

        {% set existingIds = existingIds|merge([event.id]) %}
    {% endif %}
{% endfor %}


Filtering by entries which have unpublished draft versions in the admin

Craft definitely doesn't give you these filtering tools when viewing a list of entries, but the building blocks exist within the framework to allow you to build your own solution. The most straightforward way I can think of would be to create a plugin with its own CP section and show the outstanding drafts there.

You can get a list of all drafts with this little bit of PHP:

EntryDraftRecord::model()->findAll();

If you expose the list of drafts using a Template Variable, you could then display links to each of them by doing this:

{% set drafts = craft.myPlugin.getAllDrafts() %}

{% for draft in drafts %}
    {% set draftEntry = craft.entries.getEntryById(draft.entryId)|first %}

      {{ draftEntry.title }}

{% endfor %}


Is there an easy way to loop through all existing values of an entry field and store them in an array?

I'm not sure about an array of the possible values. But you can get the actual values. You can do this with twig's merge filter. First get all the entries:

{% set allEntries = craft.entries.section('whatever') %}

Then loop over the entries and add them to an array:

{% set allValues = [] %}

{% for oneEntry in allEntries %}
  {% if oneEntry.storeBanner not in allValues %}
    {% set allValues = allValues | merge([oneEntry.storeBanner]) %}
  {% endif %}
{% endfor %}

Now allValues will be an array of the values

Things to notice:

You need to set allValues outside of the for-loop. Otherwise it will only exist in the scope of the for loop, and not afterwards - ouside it.
You need to pass an array as the parameter of merge. In this case an array with one value: [oneEntry.storeBanner]


Is it possible to update multiple cart items?

Not at the moment, you can submit a feature request for the feature here: https://github.com/craftcms/commerce/issues


How to integrate an image haystack replacement technique

This generally isn't necessary in Craft. You can use a Matrix Field and combination of Matrix Blocks to build advanced content with flexible images. This is really the best way to go if it's an option.


Stripe Bitcoin Support for Craft Commerce

Not necessarily Craft Commerce per se, but you could use Charge 2 to integrate with Stripe with Craft. In Charge 2, configuring Stripe Checkout to use Bitcoin is trivial, but could also be made to work with Stripe.js, which is where the deep integration with Craft CMS comes into play.


Are there any alternatives to the deprecated Export plugin?

Assuming you want to export to a CSV, I'd recommend trying the Sprout Reports plugin...

  https://sprout.barrelstrengthdesign.com/craft-plugins/reports


assignUserToGroups has $groupIds parameter (int / array) preset to null. From the docs:

  assignUserToGroups($userId, $groupIds = null)

So calling the function without that parameter set should do it:

craft()->userGroups->assignUserToGroups(1);


Recommended workflow when developing new websites

Essentially the question is "how can I manage changing database content across environments" which has been covered several times here before.  Some leisure reading:

What's the best practice for handling data migration and organization across development environments?

Git Workflow and Multi Environment - how to approach

What's the best practice for upgrading a versioned Craft site?

  Does Craft 3 solve this?

Craft 3.0 will not have a solution for this at launch, but we are planning on something post 3 launch that will help making managing Craft content across environments easier to manage.


Overcoming Rackspace Cloud Files 10,000 object limit

Found the spot to hack this. It was not within the AssetIndexTool as originally theorized, but in the  In RackspaceAssetSourceType in the _getFileList function you can append a marker marker_end and/or limit to the file list.

The marker should just be a URI without the extension. As an example, we change the parameters on $targetUri to look like so:

&format=json&marker=products/BC-174&limit=250';

This will index the items form that marker and effectively ignore all the other assets you have already indexed. Craft will prompt you to delete the items you already have, as they are not found because you have skipped them by hacking the $fileList.

I've found you can safely hit Cancel and your items from the marker range will be imported, and your other indexes will not be affected.

This article is very helpful in finding out what you can do with the marker params.


I have a single form with a Save button and a Delete button.

The action value is set to entries/save-entry by default. However, when the user clicks the Delete button, the action value is changed to entries/delete-entry via JavaScript.

I'm using Vue.js to accomplish this as follows:

<input type="hidden" name="action" id="action" v-bind:value="'entries/' + actionVal">

Delete button:

<button type="submit" value="delete" v-on:click="actionVal = 'delete-entry'">Delete</button>

In my Vue instance:

new Vue({
    el: '#app',
    delimiters: ['${', '}'],
    data: {
        actionVal: 'save-entry'
    },
});


Filter events by owner fields - Calendar plugin

You can find info about how to do this in the docs: https://calendars.docs.topshelfcraft.com/guide/events-variable.html#How-it-Works

The EventCriteriaModel given by craft.calendars.events is used to query the owner elements from which the event instances are generated.

So, in your example above, you can use something like:

{% set params = {
    calendar: 'myAwesomeCalendar',
    dateRangeStart: 'today',
    dateRangeEnd: now|date_modify("+1 month"),
    trainingType: 'webinar',
    trainingLevel: 'expert'
} %}

This tells Calendars:

Find entries where trainingType is "webinar" and trainingLevel is "expert"...
...and if those elements have any event rules registered on the Calendar called myAwesomeCalendar...
...return the instances of those events that occur in the next month.

(In this case, Calendars queries Entry elements, since that is the default. You could specify a different element type, however.)


craft.request.getParam('entryId') returns null on edit page of an entry

craft()->request->getParam() is only going to check for the value as part of the query string in the URI or in POST if it is a POST request, which is why it's returning null on the edit entry page in the control panel (it isn't in either).

But since it looks like you're using a template hook in your plugin, you can get the entry id directly from the context:

$entry = $context['entry'];

if (!$entry->id)
{
    // New entry
}
else
{
    $entryId = $entry->id;
}


Can you override the default sendmail path in Sendmail transport config in Craft 3?

There are some examples of how to override the mailer component and transport settings in the official Craft docs here: https://docs.craftcms.com/v3/config/#mailer-component

For this particular sendmail example, you'd need to do something like this from config/app.php:

'components' => [
    'mailer' => function() {
        // Get the stored email settings
        $settings = Craft::$app->systemSettings->getEmailSettings();

        // Override the transport adapter class
        $settings->transportType = craft\mail\transportadapters\Sendmail::class;

        // Create a Mailer component config with these settings
        $config = craft\helpers\App::mailerConfig($settings);
        $config['transport']['command'] = '/usr/bin/sendmail -customflags';

        // Instantiate and return it
        return Craft::createObject($config);
    },
]


Populating craft database from non-craft data

Brad is absolutely correct. Better off trying for an existing plugin (we have one in the works over here for very robust Wordpress migrating!!!), but here are a few steps to get you started:

Move the non-craft database tables over to a staging server with your craft tables, and rename them with a craft_ prefix (or whatever you have set as your prefix in config).
Query for the entries

$query = craft()->db->createCommand()
->select('*')
->from('your-non-craft-post-table')
->where('any conditions')
->queryAll();

Loop through the query results, creating new Entry Models and assigning columns to your fields.

//Go through each $query result
foreach($query as $old_entry){
    $entry = new EntryModel();
    $entry->sectionId = your_craft_section_id;
    $entry->authorId = your_craft_user_id;
    $entry->postDate = $old_entry['old_post_date_column'];
    $entry->enabled = true;

    //This is the fun part - mapping content to your custom fields
    $entry->getContent()->title = $old_entry['old_title_column'];
    $entry->getContent()->yourCustomFieldHandle = $old_entry['column_to_map_to_custom_field'];

    //Use the Entries service to save the new entry
    $success = craft()->entries->saveEntry($entry);
}

Obviously there is more to it than that...mapping user accounts, categories, tags, assets, etc. But hopefully this will help you get started!


Using craft.entries to return entries with empty entries field

You were on the right track using relatedTo. But as there's no notRelatedTo parameter, you'd first have to get all drinks that are related to any ingredient and those entries can then be removed from a new ElementCriteriaModel, that returns all your drinks, using Craft's without filter. Instead of passing whole element models, you should better use this filter with element IDs (→ Why is the Craft without filter not working correctly and how to debug?). To get them just make use of the ids() method.

{% set ingredients = craft.entries.section('ingredients').limit(null) %}
{% set drinksWithIngredientsIds = craft.entries.section('drinks').relatedTo({targetElement: ingredients}).limit(null).ids() %}

{% set drinksWithNoIngredients = craft.entries.section('drinks')|without(drinksWithIngredientsIds) %}


Commerce 1 find if Discount object is valid based on start/end dates (Twig)

In Commerce 1, craft.commerce.discounts will return an array of Commerce_DiscountModel objects of all available discounts.

public function getAllDiscounts($criteria = [])
{
    $records = Commerce_DiscountRecord::model()->findAll($criteria);

    return Commerce_DiscountModel::populateModels($records);
}

Commerce_DiscountModel objects have a dateFrom and a dateTo property, which is probably what you're looking for.

Completely untested, but something like this:

{% set discount = null %}
{% for d in craft.commerce.discounts %}
    {% if d.id == 1 %}
        {% set discount = d %}
        {% if discount.dateTo > '2018-01-01 00:00:00' and discount.dateFrom < '2018-12-31 23:59:59' %}
            Matches!
        {% endif %}
    {% endif %}
{% endfor %}


They aren't loaded into the twig template global scope but you can access them with:

https://craftcms.com/docs/templating/craft.globals#getSetByHandle


Exchange Content between Local and Production

You may have a look at this article and the scripts introduced there. It basically gives you a console command that pulls the live database or assets into your local environment.

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

The article was written before the project config feature was a thing as far as I know. So watch out for that.


Best way to provide navigation similar to wordpress

I would recommend going with a "Structure". This would be the build in way of doing it. You can setup the Structure to have it's own fields to control different "Pages" OR you can have it only use a related entries field and link to other entries anyway you like.

This topic has been discussed quite a lot and you have some great posts here:

Would you use a Structure as navigation over multiple sections (channel entries, indexes and singles)?
Multi-lingual site navigation made of singles, channels and structure
How do you handle complex navigation in Craft?

There's also "Plugin" solutions out there like https://github.com/am-impact/amnav.


How to make PNGs crisp using Imager + Optipng and Craft 3?

Unfortunately, resizing images always tends to make them a little bit blurry, especially if the size that it's resized from isn't very big. But, here's a few things you can try:

Make sure you're using the Imagick image driver in Craft, that gives you alot more options to play with ('imageDriver' => 'imagick' in your general config).
Try playing around with the resizeFilter config setting. This is the algorithm used to resize the image. Some are good for photos, some are good for illustrations. Some give the resized image a "softer" look, some a "harder" one.
Make sure smartResizeEnabled is set to false (it's the default), as this does a lot of up and down scaling to create a file that has a smaller filesize.
Consider running the sharpen or unsharpmask effects on the transform. It might give undesired results if the image is too blurry, or the sharpen is too heavy, but it could be useful to just add a little bit more sharpness in the end.
AFAIK, optipng shouldn't be doing anything to the image that would impact the visual quality of it. But, just to eliminate that, make sure you try without any post optimization tools also.
Also, make sure that the image is actually displayed in the size that you've intended it to be (150px), and that you don't have any CSS rules on it that would result in it being treated as an GPU accelerated layer (transforms, etc). That blurs things like crazy. But, you can easily test if that's the case by opening the transformed image in a separate browser/application.

Hope this helps.


You know you can do things like this in your root entry  template to load it dynamically based on slug or entry type

{% extends [
  'pages/_custom/' ~ page.slug ~ '.twig',
  'pages/_entrytypes/' ~ page.type ~ '.twig',
  'pages/_generic.twig' ]
%}


Move entry from one structure to another with parenting

That’s a little more complicated, and at that point you’re going to be best off writing your own PHP code to do it.

Craft has a bootstrap file that makes it very easy to write custom PHP code without going to the trouble of writing a plugin, which is great for one-off tasks like this.

Just create a new file alongside your index.php file, called move_entry.php. Here’s what it should look like:

Craft 3

<?php

// ...
// copy contents of index.php here, except for the last `$app->run();` line
// ...

// Start a transaction in case anything goes south
$transaction = $app->db->beginTransaction();
try {
    // Fetch the entry you need to move
    $entry = \craft\elements\Entry::findOne(184);

    // Remove it from its old structure
    $oldSection = $entry->getSection();

    $record = \craft\records\StructureElement::findOne([
        'structureId' => $oldSection->structureId,
        'elementId' => $entry->id
    ]);

    if (!$record->deleteWithChildren()) {
        throw new \Exception('Could not delete the old structure node');
    }

    // Set the new sectionId and typeId on the entry
    $entry->sectionId = 2;
    $entry->typeId = 2;

    // Append it to the end of the new structure
    $newSection = $entry->getSection();

    if (!$app->structures->appendToRoot($newSection->structureId, $entry, 'insert')) {
        throw new \Exception('Could not insert the new structure node');
    }

    // Save the entry
    if (!$app->elements->saveElement($entry)) {
        throw new \Exception('Could not save the entry');
    }

    // Commit the transaction
    $transaction->commit();
} catch (\Exception $e) {
    // Undo whatever changes we already made
    $transaction->rollBack();
    throw $e;
}

echo 'success!';

Craft 2

<?php
namespace Craft;

// Initialize Craft without letting it take over the whole request
$app = require '../craft/app/bootstrap.php';

// Set Craft to Craft Personal so we don't get any errors about Client/Pro-only components not being available
$app->getInfo()->edition = 0;

// Start a transaction in case anything goes south
$transaction = $app->db->beginTransaction();
try
{
    // Fetch the entry you need to move
    $entry = $app->entries->getEntryById(184);

    // Remove it from its old structure
    $oldSection = $entry->getSection();

    $record = StructureElementRecord::model()->findByAttributes(array(
        'structureId' => $oldSection->structureId,
        'elementId'   => $entry->id
    ));

    if (!$record->deleteNode())
    {
        throw new Exception('Could not delete the old structure node');
    }

    // Set the new sectionId and typeId on the entry
    $entry->sectionId = 2;
    $entry->typeId = 2;

    // Append it to the end of the new structure
    $newSection = $entry->getSection();

    if (!$app->structures->appendToRoot($newSection->structureId, $entry, 'insert'))
    {
        throw new Exception('Could not insert the new structure node');
    }

    // Save the entry
    if (!$app->entries->saveEntry($entry))
    {
        throw new Exception('Could not save the entry');
    }

    // Commit the transaction
    $transaction->commit();

    echo 'success!';
}
catch (\Exception $e)
{
    // Undo whatever changes we already made
    $transaction->rollback();

    throw $e;
}

Plug the right entry/section/type IDs in there, point your browser to http://example.com/move_entry.php and you should be all set!

Warning: Make sure you never run this code for an entry that has any children in the structure, as its children will end up getting removed from the hierarchy.


Dynamic postCpLoginRedirect based on user permissions

You don’t need to dynamically set the postCpLoginRedirect template, you can point to a single, unified template. Once the user has been redirected, make all of your dynamic decisions within the Twig template.
If you want to then choose to redirect to yet another template, just use the Twig redirect tag.


Show only top level categories assigned to an entry

You might want the siblings of the selected Category via siblingOf - I think you'll need to do this with two steps.


Dymanic 'active' class using nav tag looping through a structure

My recommendation is to match the slugs as opposed to the ids as this is much easier to debug.

    {% nav menu in craft.entries.section('mainMenu') %}
        DEBUG: Entry.slug={{ entry.slug }}
        DEBUG: menu.slug={{ menu.slug }}

            {{ menu.title }}

    {% endnav %}

Then obviously remove the debug lines once everything is working as intended :)


Figured this out myself.

The 'getDraftsByEntryId' function is only intended for displaying the list of drafts, so there is no need to populate the model (a potentially expensive task). Indeed, there is a line that unsets the 'fields' part of the data in the EntryRevisionsService.php file:

// Don't initialize the content
unset($result['data']['fields']);

Handily, there is another function called 'getDraftById' that I was able to use, which does populate the model. Therefore, my amended (and working) code is:

{% set entry = craft.entries.section('events').type('ofs').status(null).limit(1).first() %}
{% if entry and entry.enabled %}
    {% set drafts = craft.entryRevisions.getDraftsByEntryId(entry.id) %}
    {% if drafts %}
        {% set entry = craft.entryRevisions.getDraftById(drafts[0].draftId) %}
    {% endif %}
{% endif %}

Boom!


Identifying users and site permissions when logged in

I built my site switcher like this:

https://www.thebasement.be/language-switcher-for-craft-3/

You will have to define an array for your site variables in the general.php for each environment:

'siteUrl' => array(
  'default' => 'http://yoururl/',
  'english' => 'http://yoururl/en/',
 ),

You can also extend the user with a language field and let him save his preferred language with a simple form like the user profile form from the Craft 3 docs.


You can run the craft setup/security-key console command after cloning the repo.  That'll generate a security key for that Craft install and put it in the local .env file.

Or for that matter, craft setup will run the whole setup process (database credeitials, security key, etc.).

  Are there other security considerations to take into account?

Keep your craft/config/license.key out of the repo so that a new one is generated for each cloned site.


Get count of new entries since last visit

You can use the cookies Plugin (or for Craft 2)  to store the value of the timestamp when the users has visited the page for the last time. Or you can create your custom code like explained in the question: How to set a cookie

You can get the current timestamp like it's stated in the docs

{% set currentTimestamp = now|date('U') %}

And store the cookie like explained

{# Set the cookie using 'set' variable #}
{% do craft.cookies.set( NAME, VALUE, DURATION, PATH, DOMAIN, SECURE, HTTPONLY) %}
{% set yourTimeStamp = getCookie( NAME ) %}

Then you'll search for entries after the specific date

{% set newEntries = craft.entries.postDate('>= ' ~ yourTimeStamp)|length %}


Why can't users upload files in this asset?

Have you checked the user group permission settings page? There you should be able to select which Asset Sources users in a specific user group are able to view, upload files to, etc. If at least one Asset Source is selected then the Assets navigation item will appear for users in that group, otherwise it will be hidden.


It looks like you need to have php-7.2-cli -d allow_url_fopen=1 in front of your craft commands. When you run craft update all, Craft then tries to run migrations (craft migrate/all) but without your php-7.2-cli... declaration it seems to fails.

If you have access to composer, you could try to update 'manually' instead of running craft update.

run composer update
then php-7.2-cli -d allow_url_fopen=1 craft migrate/all


Check out "Dynamic Content" in the "Advanced Usage" section of the Blitz docs:
https://putyourlightson.com/plugins/blitz#dynamic-content
Thus can be done with:
{{ craft.blitz.getTemplate('/template/name', { elementId: entry.id }) }}


Can't access plugin variable in a twig template?

Reinstalling the plugin after a database update just solved the problem : the database i sync'ed with didn't have the plugin installed (as it is still in development)

Sorry for that one... :)


Can I have a textarea field which isn't rich text?

If what you want is a multi-line plain text field, then check the Allow line breaks checkbox for that field.


Import a large number of assets via feedme

I ended up writing my own command line importer rather than using feedme. This meant I could be much more flexible with my import.

I also had to break up the sub folders into groups given the Assets admin panel cannot deal with 1000's of sub folders. See: https://github.com/craftcms/cms/issues/2547#issuecomment-537934580


Return to specific locale based on cookie?

Storing the cookie

I'd recommend using the LJ Cookies plugin...

{% do craft.lj_cookies.set('locale', craft.locale, '', '/' ) %}

Retrieving the cookie

The LJ Cookies plugin is also capable of reading cookies, so you could simply put a conditional redirect at the top of your layout...

{% set currentLocale = craft.locale %}
{% set goToLocale = craft.lj_cookies.get('locale') %}

{% if goToLocale and (currentLocale != goToLocale %}
    {% redirect '/' ~ goToLocale %}
{% endif %}

If you insist on performing the locale redirect at the .htaccess level, that's also possible. It would provide you a small performance improvement, but may not be worth bypassing the simplicity of using LJ Cookies in your template.

Using .htaccess to perform a redirect based on a cookie value is beyond my expertise, and somewhat beyond the scope of the Craft SE site. But I did some quick Googling around for "cookie" and "htaccess", and found a few helpful links:

https://stackoverflow.com/questions/3978726/how-to-do-htaccess-redirect-based-on-cookie-value
http://www.askapache.com/htaccess/htaccess-fresh.html#Get_Cookie_Value


What if you just use <a href="{{ file.url }}">? So, without the siteUrl part? If your Asset source's URL setting is correct (so, the complete url, preferably using {siteUrl}), that should do the trick ...


Frontend Form - Checkboxes cannot "all" be unchecked

Your code is correct but you need to add another line near the top:

 <input type="hidden" name="fields[volunteerPositions]" value="">

From the documentation:

  If you are including a Checkboxes field on a front-end entry from, make sure to include a hidden input before the checkboxes, so that an empty value is submitted if no checkboxes are checked.


Populate Lightswitch field from Frontend Entry Form

The Lightswitch field is a simple boolean/tinyint column, with a 0/1 value. For this to work, you want to do something like this:

<input type="checkbox" name="fields[gistDraft]" value="1" {% if entry.gistDraft %} checked="checked"{% endif %} />

If you are sending the value some other way than a checkbox (the lightswitch field is a hidden checkbox), make sure that gistDraft has a value of 0 (off) or 1 (on).


Trying to template a post's image on an index page with a default image if it does not exist

Drop the getUrl() from the set and everything works.


how to search for entries where a custom field is either not present or is empty

I don't know if you can do that at query level without adding the field to your other sections but you can do (although it's not very economical):

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

{% for entry in entries %}
{% if entry.text is empty %}
    {{ entry.title }} <br>
{% endif %}
{% endfor %}


Order of draggable entries and assets won't save

From your description, if I had to guess, you're running into a php.ini max_input_vars, post_max_size or some other related environmental limitation.  I'd try bumping those as a starting point for debugging.


Turns out this was a bug introduced in 2.3 and will be fixed in the next release.

Update:

This was fixed in Craft 2.3.2617.


DB and eventually others files are updated in the first request after the Update.


Nope. It isn't possible to set permissions for individual entries (based on a field value, entry type or any other criteria).


Passing variables between sibling blocks

I don't understand what you want to achieve? In your example, the for loop would run 5 times so which entry.id do you want to get out?

The way to use common variables in both your blocks would be to do:

{% extends "main" %}
{% set entries = craft.entries.section('blogPosts').limit(5).all() %}

{% block header %}
    {% for entry in entries %}
        {# access entries in here #}
    {% endfor %}
{% endblock %}

{% block main %}
    {% for entry in entries %}
        {# and also in here #}
    {% endfor %}
{% endblock %}


How to detect the current report in settings.twig

At the time of this post, the only variable available to the settings template that might help you out is the settings object: {{ dump(settings) }}.
As this is the Twig Template report, you might be able to use the settings.resultsTemplate value to identify the active report in a shared settings file.

I've opened a ticket for adding improved support for this scenario and will look into making the dataSource object available to the settings template in a coming release.


Caching variables for use elsewhere in a template?

Update: This doesn't work. Leaving it here temporarily in case it helps generate more ideas.

Haven't tried this myself, but you might try returning all testimonials and then use twigs random method to select one after the fact.

{% cache %}

    {% set myField = entry.myMatrixField %}

    {% for block in myField %}
        {% if block.type == "someType" %}
            {% set presentationCode %}
                ...Presentation code
            {% endset %}
        {% elseif block.type == "someType" %}
            {% set presentationCode %}
                ...Presentation code
            {% endset %}
        {% elseif block.type == "someType" %}
            {% set randomEntry = craft.entries.section("testimonials").find() %}
        {% endif %}
    {% endfor %}

{% endcache %}

{% if randomEntry %}
    {% set randomEntry = random(randomEntry) %}
    {% set presentationCode %}
        ...Presentiaon code
    {% endset %}
{% endif %}

{{ presentationCode }}

Note: I suspect that you will need the .find() on the end of the ElementCriteriaModel statement so that it gets converted to an array.

Update: To do this you will also probably need to place all your presentation code in a variable and then display later in the template.


User Profile page - one user can only access one page

Absolutely.

From the template side you'd do something like this to ensure they're editing their own page:

{# assuming the URL structure for the profile page looks something like http://mydomain.com/users?id=5 %}

{% set editUserId = craft.request.getParam('id') %}

{% if editUserId and currentUser.id == editUserId %}
    You're in!
{$ else %}
    {% exit 403 %}
{% endif %}

Where currentUser is a global variable that's a UserModel object.


How to output only the first instance of a Matrix block type field

You can either use external bool variable

{% set firstNbContentDisplayed = false %}
{% for block in entry.newsBlock %}
    {% switch block.type %}
        {% case 'nbTitle' %}
            ...
        {% case 'nbContent' %}
            {% if not firstNbContentDisplayed %}
                {% set firstNbContentDisplayed = true %}
                ...
            {% endif %}
    {% endswitch %}
{% endfor %}

or if possible in your case separate nbContent and limit it to 1

{% for block in entry.newsBlock %}
    {% switch block.type %}
        {% case 'nbTitle' %}
            ...
    {% endswitch %}
{% endfor %}

{% for block in entry.newsBlock.type('nbContent').limit(1) %}
    ...
{% endfor %}


Ah ok, two issues;

the image field is an array so you need to just select the first
you need an 'img' html tag as the twig code will only output the url

{% for entry in craft.entries.section('blog').level(1) %}

{{ entry.title }}

  {{ entry.getLink() }}
  {{ entry.previewText |raw }}
  {% for row in entry.textImages.all() %}

    {{ row.textImageWitdh }}
  {% endfor %}

{% endfor %}


Something like this should do it:

{% set heroImage = entry.heroImage.one().getUrl() %}

Although this probably works as well:

{% set heroImage = entry.heroImage.one().url %}

In Craft 3, .first() has been replaced with .one().  https://docs.craftcms.com/v3/changes-in-craft-3.html#query-methods


Does allowUpdates and allowAdminChanges affect whether or not content will be updated on the site?

Nope.

  Thought it might be a cache issue but why would it work on dev and not prod?

Caching is my first thought. Is production behind a CDN, Varnish or some other caching solution that dev is not?

Maybe the enableTemplateCaching config setting is set to false for non-production environments?


How can I only get the entries that are related to an active category

You would first query for all active categories and then get the Product entries that are related to these categories.

{% set allCategories = craft.categories.group('Categorie') %}
{% set entriesWithActiveCategories = craft.entries.section('Products').relatedTo(allCategories) %}


The documentation is out of date.  The cache tools now live under the Utilities section.  Presumably you need admin privileges to see/access/use these tools.


The above setting that I wrote is good until I forgot to change the limit number of selectable categories from 1 to 2 which solve my problem.  I think that was the problem for not showing the children due to limit to one select category. Now I can add two categories (The parent and child).


Restrict Permissions Per Entry Rather Than Per Section

There is a way - it's actually quite easy but you need to dig deep into Craft 3 to do it. In general: there is only one single Javascript function that fetches all elements for all index pages

updateElements: function() {
    // Ignore if we're not fully initialized yet
    if (!this.initialized) {
        return;
    }

    this.setIndexBusy();

    var params = this.getViewParams();

    Craft.postActionRequest(this.settings.updateElementsAction, params, $.proxy(function(response, textStatus) {
        this.setIndexAvailable();

        if (textStatus === 'success') {
            this._updateView(params, response);
        }
        else {
            Craft.cp.displayError(Craft.t('app', 'An unknown error occurred.'));
        }

    }, this));
},

As you can see: the route is a variable in the defaults

updateElementsAction: 'element-indexes/get-elements'

In order to change this route you'll have to overwrite it in a JS file

Craft.BaseElementIndex.defaults.updateElementsAction = 'your-awesome-plugin-route';

Not let's take a look at the controller: After certain other functions the final call that searches for all elements is the following ElementIndexController line 379

$responseData['html'] = $elementType::indexHtml(
    $this->_elementQuery,  // <-- this is the important part
    $disabledElementIds,
    $this->_viewState,
    $this->_sourceKey,
    $this->_context,
    $includeContainer,
    $showCheckboxes
);

All you have to do is to extend this Controller, build a custom one, link the route to your custom controller and change the $this->_elementQuery. You can include your custom search parameters, include hidden content fields, create custom relation fields for groups and search for elements related to this user group or whatever you want.

It seems a little bit tricky at first but it's actually pretty easy. I've done it several times


How does a plugin output JS that can be used within a cache tag?

That’s a tricky one, because right now the {% cache %} tag is only focussed on the actual HTML that gets output between its tags, but when you include Javascript using TemplatesService::includeJs, etc., that’s actually queuing up the Javascript to be output later on.

So, the trick here will be to make sure any JS that is included within the {% cache %} tag is also output within the {% cache %} tag:

{% cache %}
    {% for entry in craft.entries.section('news') %}

        {{ craft.googleMaps.data('map', entry.map) }}

        {# Output any queued-up JS #}
        {{ getFootHtml() }}

    {% endfor %}
{% endcache %}

This isn’t a perfect solution because that tag will also output any Javascript that was already queued up before the {% cache %} tag. If there is any, then it will end up getting output twice on requests where the {% cache %} tag already has cached HTML to return. Might be something we can address in a future update though.


Error while accessing an associative array

There's not a pretty way to do it in Twig other than what you've done in the if part of your conditional.  Something like this should work:

{% if attribute(data, entry_name) is not defined and entry_total > 0 %}
    {% set data = data|merge({ (entry_name) : entry_total }) %}
{% else %}
    {% set data = data|merge({ (entry_name): 10 }) %}
{% endif %}


For Craft 3:

Craft::$app->config->general->{var name}


RegisterUrlRulesEvent rule to display site page

Well I have managed to achieve what I needed, I'm not sure if this is a very good way to do it though.

I've done it by getting the element of the page I needed and passing that to the route along with the template to use.

It all seems to work though.

Event::on(
        UrlManager::class,
        UrlManager::EVENT_REGISTER_SITE_URL_RULES,
        static function (RegisterUrlRulesEvent $event) {
            $element = Craft::$app->getElements()->getElementByUri(
                'site-start-your-quote',
                Craft::$app->getSites()->getCurrentSite()->id,
                true);
            $event->rules['POST start-your-quote'] = 'craft-lp-api-helper/lpapi';
            $event->rules['GET start-your-quote'] = [
                'template' => '_layouts/forms/start-your-quote.twig',
                'variables' => [
                    'entry' => $element,
                ],
            ];
        }
    );


How many simultaneous visitors Craft CMS can handle?

Is CraftCMS (v3) realistically capable of handling around 10.000 logged in visitors simultaneously?

Generally speaking, yes. Depending on the specifics of the site and what the users are doing, you might have to make some environmental accommodations.

As always with stuff like this, so much of it depends on things like the hosting architecture (load balancers, web servers, hardware specs, session/cache storage, caching) as well as Craft's information architecture, template logic, plugins, caching, etc.


By setting the regenerateSitemapsAutomatically to false, SEOMatic won't regenerate a sitemap for every entry saved.
At the end of the job, I set it back to true and save the first element inside of the same section.

Changes to the original code:

Seomatic::$settings->regenerateSitemapsAutomatically=false; // Disable it

while (($csv = fgetcsv($handle)) !== false) {
    $entry = Entry::find()->siteId($siteId)->section('products')->where(['content.field_productId' => $csv[0]])->one();

    if (!$entry) {
        $entry = new Entry();
        $entry->sectionId = Craft::$app->sections->getSectionByHandle('products')->id;
        $entry->typeId = 1;
        $entry->siteId = $siteId;
    }

    ...
    ...
    ...

    try {
        Craft::$app->elements->saveElement($entry);
    } catch (Throwable $e) {
        throw new RuntimeException($e);
    }
}

try {
    Seomatic::$settings->regenerateSitemapsAutomatically=true; // Enable it again
    $firstElement = Entry::find()->siteId($siteId)->section('products')->one();
    Craft::$app->elements->saveElement($firstEntry); // Save first entry again
} catch (Throwable $e) {
    throw new RuntimeException($e);
}

Thanks to Oli for the suggestion.


Add Checked Attribute to Custom User Fields on Frontend User Form

Solved!

{% for letter in currentUser.newsletters.options %}
    <input type="checkbox" value="{{ letter.value }}" name="{{ letter.value }}" id="{{ letter.value }}"
        {% if letter.selected == true %}checked="checked" {% endif %}/>
    <label for ="{{ letter.value }}">{{ letter.label }}</label>
{% endfor %}


It seems all you miss is the define setting and the value attribute in your template, Craft manages the settings for your plugins without any need to edit many things. It stores and loads them automatically. You can handle the entire process on your own and overwrite craft functions but out of the box you have to do nearly nothing.

As a great boilerplate you could create a plugin with Pluginfaktory it has many examples how to manage things like routing, templating and all that kind of stuff.

Just turn the "Settings" lightswitch to on and don't change the "Comments" button.

Anyway here is some example code to store settings
In your Plugin.php you need

 /**
 * Defines the attributes that model your plugin’s available settings.
 *
 * @return array
 */
protected function defineSettings()
{
    // this is an array with all the settings the user may change.
    // Open the `AttributeType` file to see a full list. Eg. Integer,
    // String, JSON, Enum.... there are many ready to use data types, and of
    // course you could define validation rules like min length, max length,
    // in range and such
    return array(
        'apiKey' => array(AttributeType::String, 'label' => 'Your Api Key', 'default' => 'XXXX'),
        'listId' => array(AttributeType::String),
    );
}

/**
 * Returns the HTML that displays your plugin’s settings.
 *
 * @return mixed
 */
public function getSettingsHtml()
{
   return craft()->templates->render('mailchimped/settings', array(
       'settings' => $this->getSettings()
   ));
}

And your template

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

{{ forms.textField({
    label: 'Some Setting',
    instructions: 'Enter some setting here.',
    id: 'apiKey',
    name: 'apiKey',
    value: settings['apiKey']})
}}

{{ forms.textField({
    label: 'Some Setting',
    instructions: 'Enter some setting here.',
    id: 'listId',
    name: 'listId',
    value: settings['listId']})
}}

Yeah, thats finally it... you can access those with from everywhere

MailchimpedPlugin::getSettings()['listId']

Or

$settings = MailchimpedPlugin::getSettings();
$data = $settings->getAttributes();


You'll need to double escape those backslashes in the regex.

  {% set ig = user.instagram|raw|replace('/(?:(?:http|https):\\/\\/)?(?:www.)?(?:instagram.com|instagr.am)\\/([A-Za-z0-9-_\\.]+)/im') %}


Using modifyElementsQuery to get plugin's custom table data

I found out I was not able to accomplish what I needed by using modifyElementsQuery.  So I created my own ElementCriteriaModel & buildElementsQuery for my plugin. This allows the criteria to be built from my table directly instead of elements table.


Link to a front-end upload in email notification using the Sprout Forms plugin

I was adding {slug} in the upload location. This worked for the final file but seems to trigger the behaviour where it links to the temp file.


Flat pricing for different currencies with sales

Setting the saleAmount in addition to setting the price prevents Craft from applying the sale amount later.


Translated entry page can not be found (404)

The issue appeared to be the nginx config. I updated it according to an example from here (Locales sub directories on Nginx) and it started working.


Check out the Imager Pre-transform plugin, or I can recommend a service like https://www.imgix.com where you can perform transforms using url parameters.


How can I get a user to choose in which group he registers using the User Registration Form

As far as I know there is no way to do this without a plugin. However, developing a plugin for this is not difficult. In your form you would want to add an additional drop-down, multi-select, or checkbox field with your groups listed. Then in your plugin, create a listener in your plugin's init method that listens for the users.saveUser event, and dynamically assigns the user to the selected groups based on the user's selection. For an example see this post explaining how to respond to an onSaveUser event, and this post on assigning groups dynamically.


Uploaded assets using ftp, asset not displaying

Looks like you're getting an nginx gateway timeout error.  Here is some info on how you can increase the time limit.


entries related To category not working with getNext function

The code you currently have (after fixing the arrowsParams typo) will only work on entries that happen to have the very first category in the Seasons category group selected, because this title parameter is actually not getting any value right now:

.title(entry.season.title)

Why? Because entry.season is not going to return the first category you have selected in your Season categories field; it’s going to return an ElementCriteriaModel that is prepped to return the category(s) selected in your Season categories field, once one of its output functions have been called.

Since entry.season is an ElementCriteriaModel, entry.season.title is actually just going to return its current title parameter value (which is null by default). So this:

{% set category = craft.categories.group('seasons').title(entry.season.title).first() %}

is really the same as this:

{% set category = craft.categories.group('seasons').title(null).first() %}

which is the same as not including the parameter at all, so it’s also the same as this:

{% set category = craft.categories.group('seasons').first() %}

So category is always going to be set to the first category in the group, and arrowsParams is going to be set to all of the Blog entries that are related to that first category.

If the entry you’re viewing doesn’t have that first category selected, then its getNext() and getPrev() functions won’t return anything. (If they can’t determine where the current entry fits into the parameters that were passed in, they can’t determine what the next and previous entries would be.)

Anyway, to fix this, you would need to put a .first() call inside that title param when setting the current category:

{% set category = craft.categories.group('seasons').title(entry.season.first().title).first() %}

But here’s the thing: entry.season.first() is already the category you’re trying to get. So there’s no point in fetching it through a second craft.categories query in the first place. This will do just fine:

{% set category = entry.season.first() %}