Getting products with Craft 3 and Craft Commerce 2

I figured out the problem. It should be

{% set silentItems = craft.products.type('silentAuctionItems').all() %}

You don't put .commerce between craft and .products.

Thanks!


I don't get a chance to specify password, seems its is auto generated but I don't get any email sent to the user I just created.

From the CP, you can't create a password for a user.  They'll receive an email, in which they can click on an activation link and they can set their own password by following the workflow.

There is extra logic in registering a new user from the CP that will detect if Craft can create the user, but not send the email, and the CP will notify you if that is the case.

It sounds like maybe the email is being sent, but caught up in a SPAM filter somewhere.

You can also check through your craft/storage/runtime/logs files to see if any [error] or [warning] entries are getting logged.


Query for blocks across Block Types using the new field parameter?

Unfortunately this is a limitation of that feature. In this case, both of your Lightswitch fields will be tweaking the DB query with their own WHERE [field_column_name] = 1, without knowledge of each other.

To avoid this, just give each of your Lightswitch fields their own unique handles.

If you want to get all the blocks where either one of your Lightswitch fields are checked, you could do this:

{% set blockIds = entry.matrixField.type('type1').typeOneLightswitchField(1).ids()
    |merge(entry.matrixField.type('type2').typeTwoLightswitchField(1).ids())
%}

{% for block in entry.matrixField.id(blockIds) %}
    ...
{% endfor %}

Not exactly a clean solution, but it’ll get the job done.


Check if title field has a string in ElementAPI

I got it.

'criteria' => [ 'title' => '*'.Craft::$app->request->getParam("key").'*' ]


Can I use GraphicsMagick with Craft CMS?

No, Craft only supports GD and Imagick, not Gmagick (which would be the PHP extension that interfaces with GraphicsMagick). The underlying PHP library, Imagine, actually does, so I guess it would be feasible to add support for it, but I suspect that there's not that huge a demand in the community. You could try submitting a feature request for it.


Craft pieces accessed by people on domain only

The back end of craft (admin log in section or Control Panel) can only be accessed by admins and users that an admin has added. The front end will always be visible to everyone while the backend will be password protected.

If you want separate front end displays for people who have usernames and passwords and those who dont, you could add a front end log in form:

http://buildwithcraft.com/docs/templating/login-form

And display one set of templates for those who are logged in and another for those who arent logged in via conditional statements e.g.

{% if currentUser %}
  Protected info
{% else %}
  public Info
{% endif %}

If this isn't quite the answer you're looking for could you be slightly more specific with what you mean by "on the domain". Describe exactly what you're looking to achieve.


Action URLs from CP to a Craft 3 plugin controller

I think you should use {{ actionUrl('myplugin/products/get-products') }}.

But in a form, it's maybe even better/easier to use:

<input type="hidden" name="action" value="myplugin/products/get-products" />


Building Results From Advanced Search Form

You can set multiple conditions on a single ElementCriteriaModel parameter. Pass it either a comma-separated list as a string or an array of conditions.

{% set entries = craft.entries.id('84, 62, < 7, 29') %}
{% set entries = craft.entries.id([84, 62, < 7, 29]) %}

In this example, each entry with any of these IDs is returned (→ or logic).
To return only those entries that match all criteria of your list (→ and logic), set the first value to and:

{% set entries = craft.entries.id('and, > 100, < 200, not 110') %}

In your case I'd set the "year" and "price" parameters as an array and combine it with all other craft.entries parameters using the object syntax like so:

{% set entries = craft.entries({

    section: 'usedCars',
    type: 'entry',
    manufacturer: manufacturer,
    model: model,
    bodyStyle: bodyStyle,
    price: [
        'and',
        '>= ' ~ minPrice,
        '<= ' ~ maxPrice,
    ],
    year: [
        'and',
        '>= ' ~ startYear,
        '<= ' ~ endYear,
    ],

}) %}

Make sure that your "year" and "price" variables are not empty by setting default values:

{% set startYear = craft.request.getParam('startYear') %}
{% set startYear = startYear is not empty ? startYear : '1900' %}


Routing within a single page app integration

To pull this off, first you’ll have to make sure all of your Element API endpoints begin with something consistent, like api/ or data/, etc.

Then create a route in craft/config/routes.php that will match everything besides those Element API endpoints:

<?php

return array(
    '(?!api\/).*' => 'index'
);

'index' is the template path the requests should be routed to, so tweak that if needed.

If you have any other routes defined in there, make sure they go before this one.

  I should add I have user registration and aspects that vue can't handle because Craft doesn't have a full crud api.

You can use the same controller actions the Control Panel uses. There are a few examples, including user registration at the bottom of the templating docs.

If you want to keep these handled by custom pages, you’ll need to add routes for them in routes.php, or else they will stop working due to that new catchall route. Craft only attempts its default behavior of matching the URI to a public template as a last resort; if a route matches the URI, that route will take precedence.


How to query entries and take into account the timezone offset? - ChartHelper

I'm not sure what kind of server you are running, but you should be able to set the server timezone in your control panel. You may need to then restart your database in order for you database's settings to be updated.


Is there a way to change what happens after you save a new entry?

You can, and it's easy!

The "Save" button contains a dropdown arrow, with alternative options for saving:

You'll notice that "Save and continue editing" is the top option. You may also notice that there's a keyboard shortcut for it... cmd + s on Mac, ctrl + s on PC.


How to use Super Table to create an Image Carousel?

Welcome to Craft!

Is it essential that you use SuperTable for this? The behavior you are describing is exactly what Matrix fields are designed to do, so you could quite easily achieve this without using SuperTable.

Take a look at this screenshot; this is how I would set up my matrix field to allow me to content manage a slider (using the field names in your example):

Hopefully that screenshot is easy to follow. This also means the markup is much easier:

{# Check if the "Rotator" matrix field has any content #}
{% if entry.rotator %}

    {# For each slide, do this #}
    {% for slide in entry.rotator %}

{{ slide.rotatorTitle }}

{{ slide.rotatorDescription }}

    {% endfor %}

{% endif %}

Just a quick markup example to get you started. Take a look through the Craft Docs for using matrix fiels as well.

But to answer your question, I'd recommend checking out BXSlider. The markup is very simple and easy to integrate with Craft/Twig. It's what I use myself and I love it. It will just build a simple next/previous slider for you.


Search results by closest match to query

Lots going on here, but I'll take a stab at it (in the future, it's helpful if you have multiple questions/issues to make separate posts for them).

Your questions of "why isn't this search term matching" probably comes down to the fact that by default, Craft doesn't do fuzzy matching.  You can use wildcards (*) to change that behavior on a per-search basis.  You can see that syntax here along with all of the other search syntax that Craft supports: https://craftcms.com/docs/searching

Also of note from that page is the defaultSearchTerms config setting, where you can change that behavior.

  Then my search component is this:

{% set query = craft.request.getParam('q') %}

{% paginate craft.entries.section('Organizations').search('title:' ~ query).order('score').limit(10) as entries %}
    {% if entries|length < 1 %}
        {% paginate craft.entries.section('Organizations').search('organizationSummary:' ~ query).order('score').limit(10) as entries %}

That's probably not working as expected because not only can you not nest paginate tags, you can technically only have one paginate tag per request.


Is it possible to filter with hasDescendants?

What you could do is to get all the descendants and loop them to check if at least one has that lightswitch not set.

{% set showDropdown = 0 %}
{% for subPage in page.getDescendants() if subPage.genericHideFromNavigation == 0 %}
    {% set showDropdown = 1 %}
{% endif %}


How to use multiple different instances Element API "Load More" button?

You could add a new param to the request called skip and use that on your homepage, and default it to zero to allow you to reuse the endpoint elsewhere.
$skipEntries = Craft::$app->request->getParam('skip') ?? 0;
$criteria = [
    'section' => $settings['section'],
    'limit' =>  $settings['limit'],
    'offset' =>  ($settings['limit'] * Craft::$app->request->getParam('offset')) + $skipEntries,
    'order' => $settings['orderBy'],
];

You'll need to add the skip parameter to the data object in the jQuery $.ajax request options object for your homepage implementation:
$.ajax({
    // some params here
    data: {
        skip: 6,
        offset: lazy_offset,
        settings: lazy_settings,
    },
    // some more params here
}

Other pages would omit the skip parameter. That's one way of solving the problem.


How to detect the model type of an item in an array of query results

Twig doesn't have a native "instanceof" check, but it'd be pretty trivial to create a simple plugin that added a Twig Extension where you can add an instanceof test.

public function getTests()
{
    return array(
        'instanceof' =>  new \Twig_Function_Method($this, 'isInstanceof')
    );
}

public function isInstanceof($var, $instance)
{
    return  $var instanceof $instance;
}

Then from your template, you'd do something like:

{% if value is instanceof('Commerce_ProductModel') %}


Maybe you already solved your issue but I wanted to explain what I did the last time... You can make use of the craft_content table and it's implementation in Craft 2 that fetches and includes all columns no matter of the field layout.

Make use of the light switch field, if you already have one that you are not going to use in your specific entry type you can abuse that, otherwise create a new one. You don't want to include this field into your field layout, you'll only work with it in your php code. Instead of looking if your entry is a new entry you are going to check if that field is set to true or false. You can change the field however you like, it is saved correctly and populated correctly, but your clients won't be able to change it manually (so they can't resend the mail by mistake.

Below is the code I used, my requirement was to send the mail as soon as the entry was activated (they were saved as disabled from a frontend form). Since you asked in a comment how to check when an entry goes from disabled to enabled I thought it might be helpful.

craft()->on('entries.onBeforeSaveEntry', function(Event $event) {
        if(!$event->params['isNewEntry']){
            /* @var $entry EntryModel */
            $entry = $event->params['entry'];
            if($entry->section->handle === "projects"){
                $oldEntry = craft()->entries->getEntryById($entry->id);
                // check if the entry was disabled and is now enabled and if no mail was already send
                if($oldEntry->enabled === false && $entry->enabled === true && $entry->getContent()->getAttribute('mailSended') === 0){
                    $originalPath = craft()->templates->getTemplatesPath();
                    craft()->templates->setTemplatesPath(CRAFT_TEMPLATES_PATH);

                    $html = craft()->templates->render('email/type/activateProject.twig', array(
                        'entry' => $entry,
                        'userFullName'  => $entry->getContent()->getAttribute('firstName') . " " . $entry->getContent()->getAttribute('lastName')
                    ));

                    if($html){
                        craft()->rodach->sendMail($html, Craft::t('email_subject_activate_entry'), $entry->eMail);
                        $entry->getContent()->setAttribute('mailSended', 1);
                    }

                    craft()->templates->setTemplatesPath($originalPath);
                }
            }
        }
    });


Saving Form Data to Plugin Record via Javascript

Assuming you've got a controller endpoint in your plugin that has an action, the pseudocode for a simple solution could be something like:

Grab the JSON data from post.
json_decode it.
Loop through the JSON data.
Instantiate a new record and assign the properties to it inside the loop.

i.e.

$record = new GeocodeFile_LocationsRecord();
$record->id = $jsonData['id];
$record->type = $jsonData['type'];
...
$record->save();


Multi-site - Setup remote asset volume to store assets on a per site/folder basis

You do this by adding {site.handle} to the fields upload location.

This will create the subfolders like you mentioned. It will also create a default subfolder for the default site, but that's ok.

Note: Make sure to rebuild your Asset Indexes in Utilities > Asset Indexes after you add the subfolder path.

That should ensure that they point to the subfolder next time you go to upload an image. I had trouble with it still pointing to the root volume directory, but that fixed it.

Also, all your current images will still work, but they will no longer show when adding/editing assets (As they are still in the root folder) You will need to copy these to the appropriate subfolder and rebuild your asset indexes (or upload again) if you want them to appear. Don't delete them from the root folder until you have updated the entries that access them.

I haven't been able to find a way to dynamically change the volumes. As far as I know it is not possible, but using subfolders works well.


Craft's tasks are meant for long-running PHP requests and don't have to execute immediately.  By default when you create a new task, it is queued in the database in the craft_tasks table and it takes a control panel request to trigger it to run, so with that method, there's no guaranteed way to have it run every 15 minutes.

However, if you set the runTasksAutomatically config setting to false, then you can setup an cron job that runs at any interval you wish.  You'd point it to a controller action on your plugin and manually trigger the task that way.


It looks like the Entry Count plugin could potentially serve your needs, though you'd need to make a few changes for it to behave the way you want. Natively, it looks like the counts are just lumped together for each entry.

Upvote is perfect for checking recent votes! (Disclaimer: I'm the author of Upvote.)

With Upvote, you can see if an entry was voted on in the past 24 hours, simply by checking the craft_upvote_elementtallies.dateUpdated value in the database.

If that's not detailed enough, you can enable the option to "Keep a detailed record of all votes". This gives you a vote-by-vote report of every single upvote/downvote ever cast. The detailed log is stored separately in the craft_upvote_votelog table.

  Warning: An unchecked craft_upvote_votelog table can grow rapidly, and quickly swell the size of your database. If you only need it to check up on recent votes, feel free to set a cron job to frequently delete old rows.

The craft_upvote_votelog table is not critical for the day-to-day operations of Upvote. It's more of a "nice to have" for rare situations which could benefit from it (like in your scenario).


How to find logged IP address from SproutForms sent email

The ipAddress of the user submitting the form is stored in the sproutforms_entries.ipAddress column.

Right now, you'd have to look in the database or create a custom report to view the data. I've opened an issue to add that data to the default report so it can be seen more easily:
https://github.com/barrelstrength/craft-sprout-forms/issues/275

You can use Sprout Reports to create a custom report integration using Twig, PHP, or MySQL.


Does Craft parse requests inside a conditional if it is false?

Yes, Twig will parse it all down to PHP before running it. It stores the rendered PHP in a /storage/runtime/compiled_templates/ file.

No, Craft will not run anything inside the conditional if it's false. At that point, it's simply processing exactly as normal PHP would.

So no, you shouldn't be notably penalized for anything inside a falsey if statement.


In Commerce, can I apply a discount only on a specific number of one product?

As far as the release notes from Commerce 1.2:
https://craftcommerce.com/changelog#build1323

It can only be given a minimum quantity of items now.


How can I get blog categories and blog entry urls to play nice together?

I think the problem here could be to do with the path to your Category Template.

Make sure that in your category settings, the path to your Category Template file includes the folder it is nested within.

So instead of _category.html, you should put blog/_category.html (if that file is inside the Blog template folder)

There is also some docs on the Craft site that tells you how to template this file if you haven't seen it already.


Focal Point - Changes don't take effect when Saved a second, or third time

If you're using Chrome, make sure you open up the URL to the image itself (you can do this by clicking on the variant in the OptimizedImages field) and do a Shift-reload. Chrome will locally cache images so you won't see the changes unless you force it to reload the image from the source.


How to set CRAFT_PLUGINS_PATH when invoking a console plugin action

Nope, you've done it the best way in Craft 2.

The upcoming Craft 3 treats console requests as more first class citizens like requests so it's not nearly as awkward using them.


Plugin license key is lost every time I update Craft CMS

@Dalton I would say that's indeed the issue (using the project.yaml file), at least at first glance.

Every time you're pushing the project.yaml file to your server, it'll overwrite your server's project.yaml file. Because the plugin isn't licensed locally, you're basically removing the license each deploy.

Can you register the license locally, then push your project.yaml file? You'll notice locally, as soon as you enter a license key, the file will change to store this license key. Things should stay in sync from then on.


Using multiple 'search' parameter values to filter entries

Just looked at the docs (https://docs.craftcms.com/v3/searching.html#supported-syntaxes) and it looks like the accepted syntax for this would be:

title::M* OR title:sach

As a result, modifying your code like so should achieve this:

{% set keywordParam = craft.request.param('keyword') %}
{% set characterParam = craft.request.param('filterByCharacter') %}

{% set entriesParams = {
   section: 'people',
   level: 1
} %}

{% set searchArray = [] %}

{% if characterParam|length %}
   {% set searchArray = searchArray|merge(['title::' ~ characterParam ~ '*']) %}
{% endif %}

{% if keywordParam|length %}
   {% set searchArray = searchArray|merge(['title:' ~ keywordParam]) %}
{% endif %}

{% if searchArray|length %}
   {% set searchParam = searchArray|join(' OR ') %}
   {% set entriesParams = entriesParams|merge({ search: searchParam }) %}
{% endif %}

{% set peopleEntries = craft.entries(entriesParams) %}

Hope that resolves it for you.


Combine two almost identical sidebar templates, used for blog index and category index pages

You could pass the content to the sidebar include, as follows:

{% include 'sidebar-template' with {
    content: entry.sidebarContent
} only %}

The sidebar template would then use content, rather than entry.sidebarContent.

It's also worth taking a look at Twig embeds, which can be very useful in situations such as this.


Sprout Reports plugin - How to output a Matrix field into a row

I got it to work with this code:

{% for entry in entries %}

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

    {% for block in entry.myMatrixField %}

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

    {% endfor %}

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

{% endfor %}


How to initiate a date picker when template is loaded remotely from controller action

Since your controller returns json you'll probably have a Javascript function that calls this controller so you can initialize it at the moment you receive the html.

Besides that you can as well include Javascript in your Craft::$app->getView()->registerJs class.


{% set newsSlug = craft.entries().section('news').select('elements_sites.slug').one().slug ?? null %}

news - handle your section news;
select('elements_sites.slug') - for get only slug your section;
?? null - in case if there is no such section;


How do you sort elements queried from multiple channels?

The order param sets the ORDER BY part of the MySQL query. You can also pass MySQL functions in it.

In your case GREATEST() should do the job:

{% set allEntries = craft.entries
    .section(['publication','text', 'exhibition'])
    .order('GREATEST(releaseDate, publicationReleaseDate, exhibitionOpeningDate) desc')
    .limit(null) %}


How to add year and month to Entry URL Format

You're close! For the month part you need postDate|date("m") (this page has the php date formats).

news/{postDate|date("Y")}/{postDate|date("m")}/{slug}


Method for creating Category Group landing pages

2nd Revision:

The category group field layout is for categories within that group. Categories groups do not have fields assigned to them, only to the categories within a group.

1st Revision:

To get the fields of a category group, set the category like so:

{% set group = craft.categories.group('suitability').one() %}

And use fields:

{{ group.someFieldHandle }}

Original Answer:

To retrieve the category:

{% set slug = craft.app.request.segment(1) %}
{% set category = craft.categories.group('suitability').slug(slug).one() %}

Then use its fields or related:

{{ category.title }}
{{ category.somePlainTextField }}
{% set entries = craft.entries.relatedTo(category).all() %}

It would be better to set the template for the category on the category group settings page.

Set the URI to /suitability/{{ slug }} and the template to /shop/category.twig
Then you can just use the category in the template without having to set it by getting slug and pulling the category from the group. Also, this allows you to point multiple category groups to the same template if their template will be similar.


Relating a Category Entry to a Categories Field Type

Turns out I was overthinking it, I was able to connect it with the following piece of code.

{% set levelOne = category.topLevelConnection %}
{% for subCat in craft.categories.group('levelTwo').relatedTo(levelOne) %}


send e-mails via smtp without authentification

My guess is that protection.outlook.com simply doesn't allow un-authenticated connections, because well... I'm sure they relay enough SPAM with authenticated connections, much less unauthenticated ones.


You could try to fight that ampersand with the htmlEntityDecode filter that is included in my Craft Helpers plugin https://github.com/carlcs/craft-helpers


Setting up Route for Category-based RSS Feeds

Okay, I think that I have figured it out. Posting here for posterity. Based on the requirement above, I put these in my routes.php file.

'shows\/(?P<parentSlug>[a-zA-Z0-9\-\.]+)\/(?P<childSlug>[a-zA-Z0-9\-\.]+)\/feed' => 'categories/_shows.rss',

and

'shows\/(?P<parentSlug>[a-zA-Z0-9\-\.]+)\/feed' => 'categories/_shows.rss',

This gives me two variables. parentSlug and childSlug


How to get the previous or next two entries

In a channel this would be the next entries where the post date is before and after the current entry’s post date. The element queries for it would look like so:

{% set query = craft.entries
    .section('blog')
    .id('not ' ~ entry.id)
    .limit(2) %}

{% set prevEntries = clone(query)
    .postDate('<= ' ~ entry.postDate.timestamp)
    .order('postDate desc')
    .all() %}

{% set nextEntries = clone(query)
    .postDate('>= ' ~ entry.postDate.timestamp)
    .order('postDate asc')
    .all() %}

If your sort the entries by title, something like this should work:

{% set prevEntries = clone(query)
    .title('<= ' ~ entry.title)
    .order('title desc')
    .all() %}

{% set nextEntries = clone(query)
    .title('>= ' ~ entry.title)
    .order('title asc')
    .all() %}


Updating Array Variable In Extending Template

You can only access the parent's variable, not modify it. You could however simply add another block specifically for the body class, like so:

Layout template:

    {{ block('pageBody') }}

Template that extends it:

{% extends 'layout' %}

{% block body_class %}{{ parent() }} myclass{% endblock %}

{% block pageBody %}

Hello World

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab, consequuntur!

{% endblock %}

Note the call to parent() that includes the default classes defined in the parent template.


How to enforce capitalisation on users First Name and Last Name

You could easily add client side (JS) validation before the user registration form is submitted. How to do that depends on your JS architecture, I'd use something like vee-validate with a regex validation.

However it would probably be more user friendly to just automatically do the title casing in a custom module, adding something like the following inside the module's init() function:

Event::on(\craft\services\Elements::class, \craft\services\Elements::EVENT_BEFORE_SAVE_ELEMENT, function(Event $event) {
    if ($event->element instanceof \craft\elements\User) {
        $event->element->firstName = \craft\helpers\StringHelper::titleize($event->element->firstName);
        $event->element->lastName = \craft\helpers\StringHelper::titleize($event->element->lastName);
    }
});

Just beware if you have international users. Who knows what this will do to their names. See Falsehoods programmers believe about names


If you have a favicon.ico at the base level of your public site I think that should do it. All I can tell you is that this is what works for me.


See here for how you can download previous versions of Craft.

All you need to do is replace the existing app folder with the one you just downloaded and restore a database backup that has the same build/version numbers in its craft_info table.


How do I print a value from Craft/Twig into a Javascript function?

That is the correct way of doing it but you need to be sure that entry is a variable and set to an entry model at that point.  And that you're in an appropriate part of your template in general for outputting the code.

E.g. this works for analytics for example, placed at the end of my main structure block.

{# ANALYTICS GOOGLE #}
{% set js %}

{% endset %}

{% includejs js %}


Note: I've never used amforms nor mPDF, so I'm on a bit thin ice with this answer – hopefully it'll prove semi-useful, though.

  How do I add the mPDF library to Craft?

To include any third-party PHP library in Craft, you'll need to build a custom plugin, since that's the only real way to write (or include) PHP inside a Craft CMS app.

Craft plugins are just plain ol' PHP, so to actually include the library, you can use a regular require statement:

public function init()
{
    ...
    require_once('/path/to/mpdf.php');
}

...however, the recommended way to include a third party package is to use Composer (which mPDF supports) and autoload your dependencies from your plugin's main class' init method:

public function init()
{
    ...
    require_once(__DIR__ . '/vendor/autoload.php');
}

One thing to pay attention to when using third party libraries inside a Craft plugin, is that Craft has it's \Craft namespace for the core and all plugins, and your third party library's code won't be found under that namespace. To account for this, you can use the use statement (add it to the top of any file where you want to use the mPDF library:

use \Mpdf\Mpdf as Mpdf;

...
$mpdf = new Mpdf();

...or you can skip the use statement, in which case you'll have to type out the namespace path for the third party library every time you use it:

$mpdf = new \Mpdf\Mpdf();

  After creating a nice pdf template design, how can I populate a 2 column table in the pdf with form names/values submission data from all the fields?

In order to generate a PDF based on the fields submitted via amforms, you'll probably need to hook into the onEmailSubmission event (as you mention), and render a Twig template to HTML before using mPDF to generate a PDF from that HTML output.

Here's a very basic example – this would also go into your plugin's main class' init method:

public function init()
{
    // Require your Composer dependencies (mPDF, possibly others)
    require_once(__DIR__ . '/vendor/autoload.php');

    // Hook into amforms' onEmailSubmission event
    craft()->on('amForms_submissions.onEmailSubmission', function (Event $event) {

        $params = $event->params();

        // Use whatever's in $params to generate a PDF via mPDF
        // One way to do it is to compile a Twig template from your site's /templates folder via Craft's [TemplatesService][5], and then feed the HTML output to mPDF:
        $html = craft()->templates->render('/path/to/template', $params);

        // Create a mPDF instance, and generate a PDF file from the HTML
        $mpdf = new Mpdf();
        $mpdf->WriteHTML($html);

        // Have mPDF save the PDF file to some location
        $mpdf->Output('/path/to/your/pdf.pdf');

        // Some code that will attach the PDF to the email amforms will send
        ...
    });
}

Note: As I've never used amforms, I'm not totally sure about the syntax for the actual event listener here – the plugin's documentation is lacking in terms of its custom events; briefly looking at the source code makes me believe that amForms_submissions is the correct prefix for the event, but a minor disclaimer here.

Beyond the simple example above, for details on how to generate the actual PDF, I'll have to refer to the official mPDF documentation: https://mpdf.github.io/.

  And then finally attach that pdf to the user confirmation email?

I've no idea how to attach the PDF to the actual confirmation email amforms sends, and the documentation doesn't mention a use case like that – hopefully someone familiar with amforms can help you out with that part.

Finally – this is probably not helpful to your specific use case, but still – here's how you could send the PDF using Craft's EmailService:

$email = new EmailModel();
$email->toEmail = 'hello@example.com';
$email->subject = 'Your PDF is ready, boss';
$email->body    = 'How you doin, {{ user.name }}?';
$email->attachments = [[
   'path' => '/path/to/your/pdf.pdf',
   'name' => 'An awesome PDF',
   'encoding' => 'UTF-8',
   'type' => 'application/pdf',
]];

craft()->email->sendEmail($email);

(If amforms doesn't offer a way to include the PDF attachment, you might be able to solve it by a) using the onBeforeEmailSubmission event instead and setting $event->performAction to false inside the event handler, to prevent amforms from actually sending the email confirmation; then compile an EmailModel yourself (like in the example above), and sending that instead – just an idea)


Craft\EntryModel and its behaviors do not have a method or closure named "siteUrl"

Environment variables are only available in specific settings, and Entry URL Formats are not one of them.

There’s no need to include your Site URL in there anyway, though. The field’s label might be a little misleading – it’s really more of a URI format than a URL format.

If you want your entries to get URLs like http://example.com/entry-slug, then all you need to put in your section’s Entry URL Format setting is:

{slug}


To answer your title question... macros in Craft 3 work exactly the same as they do in Craft 2. :)

The problem you are hitting is here:

{{ macros sizedImage...

Seems like a straightforward typo. I'm assuming you meant to write it like this:

{{ macros.sizedImage...

For that reason (among others), I would recommend not naming your imported macros as "macros". It just invites confusion, and leads to silly typos like this one.

Personally, I often name them "render" (though you can truly name them anything) because it's more obvious what's happening.

{% import 'macros/global' as render %}
{{ render.sizedImage... }}


Nope, the UtilitiesController is hard-coded to use .zip:

        $zip = new ZipArchive();

        if ($zip->open($zipPath, ZipArchive::CREATE) !== true) {
            throw new Exception('Cannot create zip at ' . $zipPath);
        }

        $filename = pathinfo($backupPath, PATHINFO_BASENAME);
        $zip->addFile($backupPath, $filename);
        $zip->close();

        return Craft::$app->getResponse()->sendFile($zipPath, null, [
            'mimeType' => 'application/zip',
        ]);


What is the best practice in Craft 3 to sync schema between environments?

With the release of Craft 3.1 you can now keep fields (and other things) in sync between multiple environments.

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


Landing Page with Same URL Structure as Category

You've hit on most of the options — all of which should work fine.

Assuming you have a structure called 'pages', with the 'uri' set to {slug}, 'parent uri' set to {parent.uri}/{slug}, and template set to 'pages/_entry'; create a new entry 'resources' which should route to your template at 'pages/_entry.html', or
If you do not have a 'pages' structure you can also just create a template at 'templates/resources.html', or 'templates/resources/index.html', or
Create a route 'resources' => 'pages/_entry'

If those aren't working, then you might check that the template itself isn't creating any restrictions, and/or that you don't have any other routes defined (i.e. in your config file) that might be creating conflicts.


Craft CMS 3 - Always load "en" translation file

In Craft 3 the setup works a little bit different from the Craft 2 setup. You don't actually have to make changes to your index.php to switch the languages.

The languages are defined on a Site base. The translation folder now lives in the root of your projects: projectFolder/translations/fr/site.php.

As of Craft 3.1, you can set the Base Url of each site to a variable in your .env file and use that variable in the admin panel with the site setup. @web as your Base URL doesn't work to properly detect what site you are on.

So in your case, make two sites in the admin panel. Make two variables in your .env file:

SITE_URL_FR = '...'fr/'
SITE_URL_EN = '.../en/'

Use those variables to set your Base Url in the sites config. You can target them with $SITE_URL_FR. That should do the trick.


I was just confronted with this too. You most likely need to specify the unixSocket attribute for the MAMP Pro database. Take a look at my problem and solution at Craft CLI RC1 Connectivity Issues with MAMP Pro. Though if you're not able to get it working at all even manually I would definitely suggest resetting your root password in MAMP Pro as well.


Override admin template with own template

For that path, Craft would look for the following template files, and use the first one that exists:

craft/app/templates/users/_edit
craft/app/templates/users/_edit.html
craft/app/templates/users/_edit.twig
craft/app/templates/users/_edit/index.html
craft/app/templates/users/_edit/index.twig
craft/plugins/users/templates/_edit
craft/plugins/users/templates/_edit.html
craft/plugins/users/templates/_edit.twig
craft/plugins/users/templates/_edit/index.html
craft/plugins/users/templates/_edit/index.twig

[source]

As the users/_edit.html template in craft/app/templates will always exist, it will always find that first and use it.


Developers or experts for Craft CMS V3 in Costa Rica

The best places to look for this are workwithcraft.com and the Craft CMS Discord #jobs channel


You will need to add a custom route for the path for which you want to show the profile from a list of all users.

Per my example of /profile/{{ username }}:

In your profile/index template, you would run a loop on the user set of your choice:

{% set users = craft.users %}
{% for user in users %}
    {{ user }}
{% endfor %}

Craft Admin › Settings › Routes
New Route
If the URI looks like this: profile/* (Use the * token provided)
Load this template: profile/_profile

Then, in your profile/_profile template,

{% set user = craft.users.username( craft.request.segment(2) ).first() %}

Once user is defined, you can use the UserModel to return any data from that user (i.e. {{ user.email }} ).


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

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


What are the cache options available to a Craft installation?

There are many different caching levels on a web server, some of them are Craft-specific, and some have nothing to do with Craft, but they often get confused.  In addition to that, some of them you have control over, and some of them you get for free.

PHP Accelerators

These are web server extensions installed to provide byte-level PHP caching so that PHP doesn't have to "re-compile" an entire PHP script the next time it is requested.  If you are on PHP 5.5+, most *nix distributions have OpCache enabled by default.  The settings to control how these extensions behave (TTL, cache busting, etc.) are extension specific.
These extensions are a frequent cause of "I've changed my PHP file, but it appears to be using old code" headaches.

Memoization

Craft (and probably many Craft plugins) employ a technique called memoization where the results of an expensive method call get cached so that, on that same request, future calls to that method can read from the cache instead of executing the same expensive code over again.

Native Twig caching

Twig, the templating language Craft uses, will take a given Twig template and "compile" it down to PHP code so that subsequent requests to that template will execute the (much faster) PHP directly instead of parsing the Twig template.  Craft stores the compiled templates in the Craft storage/runtime/compiled_templates folder by default.  If devMode is off, a compiled template will be busted when its source Twig template file's date modified date has changed.  If devMode is enabled, the Twig will compile the template on every request.

Craft template {% cache %} tags

Craft provides its own (not native to Twig) {% cache %} tags for templates.  The template cache tags store its data to wherever Craft is configured to store its general-purpose data caches. By default, that is the file system, but that can be overwritten to other data stores like the database, redis, etc.
Since using this tag involves database queries, you want to be smart about using it.  It can be detrimental to cache template code that doesn't generate any database queries.  The {% cache %} tag will only cache HTML output, so it also makes no sense to cache Twig variables.
The {% cache %} tag will keep track of any Craft elements (entries, assets, users, tags, etc.) inside of it so that if any of them change, it knows to bust their caches automatically.

General purpose data caching

Craft takes advantage of Yii's supplied caching techniques and exposes them via the Cache service class at Craft::$app->getCache() so that Craft and any plugins can have a place to store arbitrary cached data.  By default, Craft::$app->getCache() uses [file based caching][14], which gets saved to Craft's storage/runtime/cache folder, but Craft::$app->getCache() can be configured to save to many external sources.
These cache durations are controlled by the cacheDuration config setting.

External HTML caching services

You can configure applications like Varnish (and similar cloud-based services like CloudFlare) to provide static/partial page HTML caching to specific URLs with their cache-busting logic.
No doubt missing some other caching methods, but probably worth noting that it's a good general rule of thumb to not double up on caching strategies.  For example, the complexity of debugging caching grows exponentially when using Varnish with byte-level caching and the {% cache %} tag and you quickly get diminishing returns performance-wise.
There are many plugins in the Plugin Store that interact with Craft across the different caching levels in Craft to modifying existing or add new caching functionality.


Nesting level too deep when looping through matrix blocks

element.type is not a simple string (add {{dump(element.type)}} to your loop to see this). What you should use is element.type.handle. So the assignment is:

{% set prevElementType = element.type.handle %}

And the comparison (now of two strings, so no recursion) is:

element.type.handle == prevElementType


Namespace issues with binding Javascript

It’s not enough to simply define $namespacedId – you need to actually use it in your Javascript code.

If you’re defining the javascript code in your template, you’ll need to pass the namespaced ID to your template, along with name, id, and value:

return craft()->templates->render("myplugin/my_input_template", array(
    'name'         => $name,
    'id'           => $id,
    'namespacedId' => $namespacedId,
    'value'        => $value
));

Then in your template, use the id variable within id= attributes, and the namespacedId variable within Javascript code:

<input type="text" id="{{ id }}-output" name="{{ name }}" value="{{ value }}">

<input id="{{ id }}-input" type="range" value="{{ value }}" min="0" max="1000" step="0">

{% set js %}
    $("#{{ namespacedId }}-input")[0].oninput = function () {
        $('#{{ namespacedId }}-value').html(this.value);
    };
{% endset %}

{% includeJs js %}

(I’ve cleaned up your HTML a little, besides the formatting – I added a missing quote after min="0, and removed the entire name= attribute from the 3rd input, since the first input seems like it will already take care of that.)


How to save entry to the current site from the front end?

The parameter is called siteId

<input type="hidden" name="siteId" value="{{ currentSite.id }}">


Dynamic Subfolders leaving empty folders behind

When Assets moves files around because of dynamic Assets folder changes, it does not remove empty folders.

On the surface it seems like a no-brainer - just check if the folder is empty and if so, then nuke it! But if you go deeper, it gets complicated.

Should the physical folder be removed as well? If not, then the next time you index Assets, the folder will be reinstated. If yes, then what to do if there are unindexed files in there? Remove anyway? That's destructive. Don't remove? Then that makes Craft behave differently based on something that is out of its scope. What would users want in this case? Who knows!

You see, it's a bit tricky especially in terms of what the users would expect out of that functionality, so we just instead decided to go with leaving empty folder, as the folder path changing should not be that often of an occurrence and does not set us up for complex support tickets down the road.


Is it possible to tell if a user was registered through the front end or CP?

You already answered your own question, but I thought I would post an example. In the plugin's class definition file create an init method with the following:

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

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

        if ($isNewUser && !$currentUser) {

            // do your thing, whatever it is

        }
    });
}

This should only target 'new user registrations' by users who are 'not already logged in' (i.e. public registrations through the front-end). By the time the Users Service has raised the event, it should have already passed all the other checks, regarding whether to allowPublicRegistration, etc.


saveEntry will always require an authenticated user with the correct permissions to post the entry, but you can use the guest entries plugin from Pixel & Tonic to allow for guest submissions :)

https://github.com/pixelandtonic/GuestEntries


Is there any plugin for Blog in Craft 3?

Nope. Craft works very differently to WordPress. You won't need a plugin for this, but will need to learn Craft. This looks like it might be helpful: https://www.youtube.com/watch?v=lfDZ6v23KcE


This is not really specific to Craft, but you should import Craft at the beginning of your class file like this:

<?php

use Craft;

...

I suggest you take a look at that documentation for more details about how to import PHP classes: https://www.php.net/manual/en/language.namespaces.importing.php


How do I configure multiple environments for console commands?

Alternatively, you could write your own yiic shell wrapper for each environment that defined CRAFT_ENVIRONMENT.

Something like yiicstaging:

#!/usr/bin/env php
<?php

define('CRAFT_ENVIRONMENT', 'staging')
require_once('path/to/craft/app/etc/console/yiic.php');


Frontend Form Search Users based on Tags

In order to get at the tag relationships, I think you'll need to use the relatedTo parameter instead of search. You'll still use search for the full-name search. This should solve both your problems.

The tricky part is fetching the appropriate elements to pipe into relatedTo() - you can't just send through the raw title string from the post data - you'll need to fetch the actual element ids.

Here's a very rough example. You'll need to replace 'facetFieldHandle_n` with the field handle names of your tag selector fields held against the users.

{% set facet1 = craft.tags.title(searchSkills).ids() %}
{% set facet2 = craft.tags.title(searchSchool).ids() %}

{% set params = ['and',
    { targetElement: facet1, field: 'facetFieldHandle_1' },
    { targetElement: facet2, field: 'facetFieldHandle_2' }
] %}

{% set users = craft.users.relatedTo(params).search(searchName).orderBy('score').all() %}

    {% for user in users %}

{{ user.fullName }}

    {% endfor %}


What is the correct syntax for using merge to create an array of field values from an element query?

Just put the field names in parentheses:

{% set options = [] %}
{% for event in events %}
  {% set options = options|merge({ (event.slug):(event.eventTitle) }) %}
{% endfor %}

And now I can output them in the format Craft wants for a form field:

{{ forms.selectField({
  label: "Choose event"|t,
  name: "eventSlug",
  options: options,
}) }}


Customizing front-end login/logout redirects

How to redirect directly to dashboard after logging in?

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

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

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

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

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


Creating HTML and Text version of entry via different templates

The issue may have to do with the extensions on the files in your template folder. By default, Craft only renders .html and .txt files. If you want Craft to also render .txt files, you could update the defaultTemplateExtensions config variable.  Adding something like this to your general.php would get .txt files rendering:

'defaultTemplateExtensions' => array('html', 'twig', 'txt')

If you want to access a .txt file without enabling it as a defaultTemplateExtension, you would have to access the template URL with the full file extension.

This URL would work out of the box:

/newsletter/entry.txt

This would only render .html or .twig:

/newsletter/entry

These defaults makes it a little harder to use a hidden template file such as newsletter/_entry for non-standard extensions. One work around would be to pass your ID as a parameter in the URL and manually grab it in your template code to determine what to do on the page.

This is an option:

/newsletter/entry.txt?id=123

As an alternative method, the plugin Sprout Email helps manage a lot of components of HTML and Text versions of email templates, and ships with a Copy/Paste Mailer which allows a user to copy and paste the HTML and Text versions of an email directly from a modal in the the Control Panel.


A user changing sensitive fields like passwords and email addresses requires a "elevated session" to do so, which requires them to enter their current password.

You can see the template code to do that here for both Craft 2 and 3: https://craftcms.stackexchange.com/a/4715/57

You can configure the duration of the elevated session with the elevatedSessionDuration config setting.


Why do I get 'Could not resolve the subpath “{slug}” after trying to add a category select to a Neo field?

i removed {slug} altogether from an Asset field definition.


There are a variety of ways you can solve this depending on your needs.

One possible way would be to assign users to groups and then use simple twig code to limit the shown payment options at the template level depending on which user (i.e which user of which group) is viewing the page.

In addition, some validation logic in a custom plugin should probably be used to prevent accidents in case a user does somehow submit a payment of a type you don't want them to be using.  However I don't necessarily see an ideal event to listen to for that - I'd check with Luke Holder but perhaps onBeforeSaveOrder would work - see https://craftcommerce.com/docs/events-reference#commerce_orders.onbeforesaveorder

Basically it comes down to how you'll be differentiating these users - without more info it's hard to provide a more substantial answer.


I'm not aware of any existing plugins that would do this, and it seems pretty use-case specific.

You can do this with a custom plugin and a cron job, though.

The cron job would run every 1/5/x minutes, hit an action in your plugin's controller and that action could get the entries in the section you're interested in, check the post date and decide what to do from there.


Access POST data to conditionally display form

I think you want this:

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

Pass a string to getPost()


All fields disappearing except 'Title' after saving

I had a similar problem with disappearing fields in the admin interface, and found it seemed to be something to do with the xdebug PHP extension. Disabling that fixed the problem and the fields reappeared:

sudo php5dismod xdebug
sudo service apache2 restart

The problem in this case is actually to do with reaching a nesting limit, so if you do want to use xdebug, an alternate fix is to bump up the max nesting limit in xdebug's ini file (or php.ini), eg:

xdebug.max_nesting_level=200


What is CDbException Error: SQLSTATE[42000]: Syntax error or access violation while moving a site to remote?

Brad was correct in the comments above. The answer is the sql_mode. This is a duplicate of Getting this SQL Error: GROUP BY incompatible with sql_mode=only_full_group_by


What is the best way to deploy a Craft CMS 3 site?

At the risk of offering a "link answer", the Setting up a New Craft CMS 3 Project has a section on DEPLOYING CRAFT CMS that should be useful to you.

I've never heard of Rocketeer, but popular ways to handle deployments are via buddy.works, Laravel Forge and the like. We talk a lot about this on the Website Deployment without Tears episode of devMode.fm


Ajax request returns code instead of result of the query (solved)

The path to the ajax file was wrong. I had it as:
$.ajax("templates/ajax?search=" + value, {

when it should have been
$.ajax("ajax?search=" + value, {


Saving Asset field in FEEF ("Front-end entry form") using Plugin

Here's the issue:

// Add dynamic fields
$entry->setContentFromPost(craft()->request->getParam('fields'));

setContentFromPost requires that if you pass any uploaded files in, you need to pass the field name as a string, instead of the actual posted values.

Changing it to this and it should work:

$entry->setContentFromPost('fields');


Does Craft commerce support multiple delivery addresses / shipments on same order?

Commerce does not currently support this out of the box (March 2016) - but (just spitballing here, you'll have to try it all out for yourself of course) - you can add arbitrary custom fields to orders.

So you could rig something up by using e.g. a matrix of address field types like this one - https://github.com/elivz/VzAddress-Craft - to store the delivery addresses.  But I am guessing you'd want the address data per line Item, so you could instead perhaps use the line items options system described at the bottom here:
https://craftcommerce.com/docs/add-to-cart

...to add data for the address to each lineitem.

The order itself would have the purchaser's main address associated with it, but you could definitely store addresses either as options with lineitems, or in custom fields on the order, so it would be possible with some effort I'd say.

Also, you'd need to write a custom shipping solution or adjuster plugin that was capable of using the address data stored to calculate the shipping for each of the 'sub orders' and return the total, I suppose.

It's not going to be super simple but Commerce is very flexible and easy to work with when it comes to plugins etc.


Frontend Profile - Listing out Radio Buttons

You can access the field using currentUser.fieldHandle; and the 'labels' and 'values' of the field by looping through the options attribute. You can also set the selected state by checking each option for the option.selected property.

<select id="radioButtons" name="fields[myRadioButton]">
    {% for option in currentUser.myRadioButton.options %}
        <option value="{{ option.value }}" {% if option.selected %}checked{% endif %}>{{ option.label }}</option>
    {% endfor %}
</select>


Have you created a new SEOMatic Meta fieldType?

I don't know whether there is another/better way of doing it, but what I do is create a new field of type SEOMatic Meta, then assign this field to the entry types of the pages you want the title to be made available to SEOMatic. There are all sorts of options within this field, but one of them allows you to select which field the title is pulled from.

More info on the SEOMatic Meta field can be found in the docs.


Sort entries by custom date in Matrix field / Super Table

I did something like this as a workaround:
Loop over entries, fetching all data you need and adding it to an array. Sorting that array with SuperSort and than displaying all info by looping over the array.

{% set tourDates = [] %}
{% set artists = craft.entries.section('artists') %}
{% for artist in artists %}

    {% if artist.tourDates %}
        {% for row in artist.tourDates %}
            {% set tourDates = tourDates|merge([ {
                'tourDate' : row.tourDate|date("d/m/Y")
            } ]) %}
        {% endfor %}
    {% endif %}

{% endfor %}

{% set tourDates = tourDates | supersort('sortAs', '{{ object.tourDate }}') %}

{% for tourDate in tourDates %}
    {{ tourDate.tourDate }}
{% endfor %}


Group entries by Category and then in each category by related entry field

I figured this out in part with @syversen answer, but it need some tweaking

Here's the simplified working code. This

{% set countries = craft.entries.section('countries') %}
{% set publications = craft.entries.section('publicationsChannel') %}
{% set categories = craft.categories.group('documentCategory') %}

{% for category in categories %}
{# list categories #}

{{ category.title }}

    {# inside categories list countries #}
    {% for country in countries %}

      {{ country.title }}

          {# finally output entries that are in the category and country #}
          {% set relatedEntries = publications.relatedTo([
          'and',
          {targetElement: category},
          {targetElement: country, field: 'regionCountry'}
          ]) %}

            {% for entry in relatedEntries %}

 {{ entry.title }}

            {% endfor %}

    {% endfor %}

{% endfor %}{# end categories #}


Default Upload Location needs matrix field and entry info... How?

If your desired URL is:

http://sitename.com/uploads/towns/town-slug/album-name/filename.jpg

The the "Upload Location" for the setup you described would be something like:

towns/{owner.slug}/{albumName}/

I'm assuming towns is just hard-coded since you're referencing town-slug in the next segment.


Getting environmental variable via plugin

Solution:

return craft()->config->get('environmentVariables')['baseUrl'];


Creating and using custom content tables

Okie doke. After bashing my head against the wall THIS is how you create your very own super deluxe content table. Allow me to explain...

In your element class you will need to specify the following:

  public function hasContent()
  {
    return true; // You definitely will need this
  }

  public function hasTitles()
  {
    return true; // This is optional
  }

  public function isLocalized()
  {

    return false; // This is optional

  }

  public function getContentTableForElementsQuery(ElementCriteriaModel $criteria){

    return "custom_content_table_name"; // You definitely will need this

  }

  public function getFieldsForElementsQuery(ElementCriteriaModel $criteria)
  {

      // NOTE: I do not have any custom fields set to this table. If you have custom fields you should return them here so that they are included in the criteria query. If you also do not have custom fields just do what I'm doing here and return an empty array.

       $fields = array();

       return $fields;

  }

In your element's model class you'll need to do the following:

  public function getContentTable(){

    return "custom_content_table_name"; // you will need this

  }

  public function getFieldContext()
  {

    return 'custom_content_table_name'; // I have NO idea what this is and the Craft documentation is not clear about it.

  }

Finally, your record for the content table will have to make the following columns:

elementId
title
locale

That's basically it. If you run into any errors make sure you're not including extra non-existent fields in the criteria queries when querying content. Check the Craft logs to see exactly what's happening if you encounter any problems.


How do I hide notifications about running tasks?

Those are running tasks that Craft (and plugins) use to perform long running maintenance operations and an Import task got stuck causing the ones to come after it not to run.

Since you don't care about the Import task anymore, you can open the craft_tasks table in the database and delete the one for the Import task (probably the top row).  The next time you load the control panel, the remaining tasks should complete.


Translation files on load balanced multiple instance site

Why not just check your site into a git or subversion repository, and when the translation files are updated, push them to the repo, and have the other servers pull the changes down?

You could even automate it with the various git hooks.


{{ post.postImage.first().getUrl('thumbImage')}}

Whatever entry post is referencing for whatever search term you're using when you get the error, doesn't have any postImage assets selected.

So when you call post.postImage.first(), that returns null and you can't call getUrl on null.

You can either make postImage required and make sure that all existing entries have at least one asset selected, or guard against it in Twig via:

{% set image = post.postImage.first() %}

{% if image|length %}
    {{ image.getUrl('thumbImage') }}
{% endif %}


The {% cache %}, by default will cache it's contents on a per URL and per locale basis.

A lot of times when we see the behavior you're seeing, that's not the desired behavior and you should be using the {% cache globally %} parameter, where Craft stores the cached segment only on a per locale basis and drastically reduces the number of rows in the database table.

I'd inspect everywhere you're using the tag and if it makes sense to use globally parameter, swap to that.

You can then clear the contents of your template cache tables (under Settings->Tools->Clear Caches Tool) and the database tables shouldn't grow anywhere near as large, letting the delete stale template caches task run faster.


So your Case Study has a field called services which is an entry relation. You show the services on that Case Study page using

// entry is the current Case Study
{% set related_services = craft.entries.section( 'services' ).relatedTo( entry ) %}

To show all Case Studies that are related to a Service you can use the same entries query.

// entry is the current Service
{% set related_case_studies = craft.entries.section( 'caseStudies' ).relatedTo( entry ) %}


Adding additional attributes to modifyEntryTableAttributes()

See this question:

  Possible to add category field to modifyEntryTableAttributes?

Basically, you need to use the getEntryTableAttributeHtml hook to get the actual content to the table cells in addition to the modifyEntryTableAttributes. You can do queries here if you need to get the data if you can not access it from the entry.

public function modifyEntryTableAttributes(&$attributes, $source)
{
    if ($source == 'index')
    {
        // This will be the header name of the column, the <th>
        $attributes['myCustomField'] = Craft::t('My Label');
    }
}

public function getEntryTableAttributeHtml(EntryModel $entry, $attribute)
{
    if ($attribute == 'myCustomField')
    {
        // Fetch the related data from your plugin. This will be placed in the <td>'s
        $fieldData = craft()->myPlugin->getFieldData($entry);
        // OR $entry->myCustomField->first(); if myCustomField is an ElementCriteriaModel.
        return $fieldData;
    }
}

EDIT: Think of it this way: when craft is loading up the entries (or any of the element types) to display on the index page, it has to know what fields are going to show. These fields are defined in the EntryElementType::defineTableAttributes. This method returns an array of attributes, where the key is whatever you want, and the value is what is displayed in the tables <th> tags. In this function, the entry type is defining some standard fields to show (title, uri, postdate etc), but Craft is nice enough to let plugins modify this array before it is returned.

Where does the array of attributes go after? The function for populating the <td> tags of the table, the EntryElementType::getTableAttributeHtml($entry, $attribute). The first thing this function does it to let plugins decide what to do, so it calls the getEntryTableAttributeHtml which is the function you should implement. The $attribute parameter is the key you defined. Here you have a chance to tell Craft how the data is displayed. If you in the first function defined $attributes['id'] and did nothing in the second function, the default way Craft is getting this data is doing $entry->$attribute (or $entry->id in this case), which would display the entry's id in the column. If $entry->$attribute is an array, or an object without a __toString, this will not work, so you will have to tell Craft explicitly how to represent this field, e.g.

if ($attribute = 'myArrayOfSpecialFields'){
  return $entry->myArrayOfSpecialFields['indexOfStringToDisplay'];
}

There are tons of useful information on this in the EntryElementType, you can just follow the flow in the code (perhaps start in the ElementIndexController)

Hope that makes things more clear


Security test generated large compiled_templates directory, site outage

I don't have specific answers to your questions, but that's mainly because I feel there are some clarifications and observations that I think might be more helpful.

The thread you linked to is referring to template caching using the Craft {% cache %} tag in a template.  All of its cached data is stored in the database in the craft_templatecache* tables, not on the file system.  See here for an explanation of the different caching methods Craft uses.

The compiled files in craft/storage/runtime/compiled_templates are what happens when Twig needs to render a template in the craft/templates folder. The first time a template is requested, Twig will take that uncompiled template and compile it down to PHP and save it in the compiled_templates folder.  If another request comes in for that same template, it will check the  file's last modified date and if it hasn't changed, it will execute the compiled template directly.

Given that an actual 404 request wouldn't create new files in the compiled_templates folder (other than the 404 template that it might need to render), I'd guess that the assumption that the 404 requests caused the compiled_templates folder to fill up enough to run out of disk space is incorrect.  It could be that enough log files or some other by-product of the testing caused more disk space to be used, but it's hard to tell without looking at the server.

You also mentioned that the database went down.  Given that the {% cache %} tag stores its data in the database, my first hunch would be to look at the strategy for using the template cache tag on your templates.  Here is a good article that weighs the in-and-outs of using it: https://nystudio107.com/blog/the-craft-cache-tag-in-depth

Two other things worth thinking about. A responsible security pen-tester is going to know better than to test on a live site by hammering it to the ground. But it's possible that maybe they were being responsible and the server is under-powered to handle any spike in load.


Display an entry page if entry is disabled

Out of the box, Craft won't even load your _entry.html file for a disabled entry – it'll just throw a 404.

To work around that, you can create a dynamic route which matches the entry type URL format 1:1, and point that route to the same template (i.e. _entry.html).

For instance, if your entry type's URL format is news/{postDate.year}/{slug}, you'd create a dynamic route using the "year" and "slug" tokens (i.e. news/(year)/(slug)). Then, Craft will automatically match your dynamic route whenever an entry URL doesn't (e.g. when the entry is disabled).

You're not home free yet, though – as you're probably aware, Craft automatically populates a template with an entry variable whenever the current URL request matches an entry type's URL format, and an enabled entry is found at that URL. This won't be the case for any entries matched by your dynamic route, so put this at the top of your template (replacing the line in your question!):

{% set entry = entry ?? slug ? craft.entries.section('yourSectionHandle').slug(slug).status(null).first() %}
{% if not entry %}
    {% exit 404 %}
{% endif %}

What the above does, is to test for the entry variable Craft would set if the entry was enabled. If that evaluates to false, then it checks to see if there's a slug variable set – which there will be if the URL was matched by the dynamic route. If there is a slug, it'll then attempt to pull the entry using craft.entries, similar to your initial code. Finally, if an entry is not found, it'll throw a 404 error, as it should.

In your template, you can easily test for the entry's status:

{% if not entry.enabled %}

Danger danger! I am disabled!

{% endif %}


You probably just confused the entry model and the asset model, see if the code below works for you.
I guess the entries.onBeforeSaveEntry event is a better match in this case, and I also added some conditionals to
only do something for a specific entry section and type, and if there's exactly one asset selected. I hope this helps (code is untested)!

craft()->on('entries.beforeSaveEntry', function(Event $event)
{
    $entry = $event->params['entry'];

    if (($entry->section['handle'] == 'friends') && ($entry->type['handle'] == 'friends'))
    {
        $title = $entry->slug;
        $assets = $entry->imgdir;

        if (count($assets) != 1)
        {
            $event->params['entry']->addError('imgdir', Craft::t('Exactly 1 asset has to be selected.'));
            $event->performAction = false;
        }
        else
        {
            $filename = $title.'.'.$assets[0]->getExtension();

            craft()->assets->renameFile($assets[0], $filename);
            craft()->assets->storeFile($assets[0]);
        }
    }
});


How do I pass a URL segment to a search parameter?

You'd need to use Twig's string concatenation in order to do this with the ~ operator.

{% set entries = craft.entries.section('calendar').search('eventstart:' ~ year ~ '-' ~ month) %}


Plugin FieldType giving error on live server - fine locally

I think you're on the right track with the case-sensitivity check.

Make sure that not only the class names match up case-wise, but the file names on the file system match case-wise as well.


Allow user to mark entry as favorite, starred, or saved for later

This definitely sounds like plugin territory. I'd recommend Curate, by Lori Goldberg.

* Disclaimer: I haven't personally tried it.


Search results home page title not showing properly but other pages do?

Could the Google account holder for the domain have set the listing to use a different value than what's in the title element?

Craft doesn't do anything like this out of the box and the SEO plugins that would change the title value you'd see that in the DOM. Is there a meta tag in the head maybe that Google reads to override the title element?

There's no default front-end templating in Craft CMS so whatever is doing this is most likely either whatever the developer's added to the homepage or layout template or Google itself.


I can't think of a clean way to do this.

The Element API plugin currently will set JSON headers on the response and return the data JSON encoded, so it's not easy to directly embed in a template.

A few options I can think of would be to fork the plugin and add the ability to return JSON in the format a template can directly utilize.  Or you could have a wrapper plugin that made an AJAX call to the Element API endpoint, grabbed the response and massaged the data into a format your template could directly utilize.


I'm not sure this is possible, but another approach would be to create a new extendable block in your parent template:
// layout.twig

{% block scripts %}

{% endblock %}

// component.twig

{% extends 'layout.twig' %}

{% block scripts %}
    <script type="module">
        // script here
    </script>
{% endblock %}


CDbException: The DB query must contain the "from" portion

Traced the error back to the from function in Yii's craft/app/framework/db/CDbCommand.php:

$tables=preg_split('/\s*,\s*/u',trim($tables),-1,PREG_SPLIT_NO_EMPTY);

The preg_split documentation states "if matching fails, an array with a single element containing the input string will be returned" but I was just getting an empty array.

This made me suspicious of what the PREG_SPLIT_NO_EMPTY flag was hiding, sure enough without it I got an array with one empty string in it, as if there was a match.

Some trial and error later and adding the PCRE_UTF8 modifier u to the preg_split patterns seemed to solve the problem.

Unfortunately can't explain what's causing the encoding issues yet.


Deleting a user's profile photo via frontend in Craft3

The input name has changed from "deleteUserPhoto" to "deletePhoto" in Craft 3.

Here is my updated working Twig code if anyone needs it :

<form method="post" enctype="multipart/form-data" accept-charset="UTF-8">
    {{ csrfInput() }}
    <input type="hidden" name="action" value="users/save-user">
    {{ redirectInput('profil/'~currentUser.id) }}
    <input type="hidden" name="userId" value="{{ currentUser.id }}">

    <input type="hidden" name="deletePhoto" id="deleteUserPhotoInput" value="">

    <input id="profilePhotoInput" type="file" name="photo" accept="image/*">
</form>

And my Javascript code :

$('.delete-profile-photo-btn').on('click', function () {
    var deleteUserPhotoInput = $("#deleteUserPhotoInput");
    deleteUserPhotoInput.val('1');
    deleteUserPhotoInput.parents("form").submit();
});


Is it possible to access users' search query data?

You could use tracking tools like Google Analytics for this? Otherwise create a plugin that creates entries that keep track of whatever query were used.

https://craftcms.com/docs/plugins/working-with-elements.


You can cycle your loop.index0 property if you really need to add a class

{{ cycle(['first', 'second', 'last'], loop.index0) }}

If the other elements don't need a class insert an empty value ''

You can as well check for a specific value of your loop.index0

However if you just want to add certain style attributes you can use the nth selector


In an Asset field, how to use a dynamic subfolder field value that is dependent on the element type?

It seems that the ?? operator or the is defined operator do not work at that level, for a reason unkown to me.

I found a workaround: testing against a property which I know will always be there. In our case, we know that the field will only be assigned to a category or an entry. Thus, we can check if the element type is a category and use the group handle as subfolder or the entry's section handle if it is an entry:

{% if object.elementType == 'Category' %}{group.handle}{% else %}{section.handle}{% endif %}

I don't know if it is the best solution, but it works.


I always write migrations to do this.

Here's and example for changing the label of a field.

You could, of course, do whatever you want - modify fieldlayouts, add/modify/remove fields, etc.

UPDATE

Nowadays I use the Schematic Plugin to transfer all kinds of settings (fields, fieldlayouts, settings etc.) over different setups.


Redactor II Craft 2.5 Prevent Paragraphs

I just found the following in the updated docs for the enterKey setting:

  enterKey — This setting allows to prevent use of Return key.
  With this set to 'false' and pastePlainText is set to true, line breaks will be replaced by spaces.

So make sure you are on Craft 2.5.2757, as it includes Redactor II 1.2 which has got the new paste settings and try this Redactor config:

"enterKey": false,
"pastePlainText": true,

Redactor II deprecated the paragraphize setting, but as noted in the comments, it's easy to remove HTML tags with the striptags filter:

{{ asset.caption|striptags('<em><strong>')|raw }}

Every tag listed in the param string is whitelisted and won't get removed.


Installation Error "1046 No database selected"

While it may be an unsatisfying answer, for the sake of completion, this question was resolved by completely destroying and rebuilding the exact same VM.

Short discussion on Twitter about it here:

https://twitter.com/monooso/status/487831027327696896

I have a warm affection for the on/off technique.  I've even seen it fix elevators!


No. Keep craft/app in your repo.

  Disclaimer: This is my own personal opinion. The topic comes up with some frequency on Craft Slack, and you will find advocates of both approaches. I fully expect to see an opposing position posted by someone else.

Benefits to keeping app in your repo...

You can properly vet an update, and make sure it does not create any problems in your site before pushing that update to production.
You have a guarantee that every environment (dev, staging, production) all contain the exact same version of Craft. This means that you can take advantage of specific features with confidence, and similarly, rule out bugs which may have been fixed between Craft versions.
You can prevent your client from "accidentally" upgrading, and potentially making a mess. Though it is rare, some breaking changes (or new bugs) are occasionally introduced when updating.


My plugin's custom fields don't show values when entry saved as draft

When you save a draft, all of the fields’ POST data is saved in the craft_entrydrafts table, exactly as it showed up in POST. When the draft is loaded, it’s that raw POST data that is passed to your field type’s getInputHtml() method - not whatever the field type would have returned in prepValueFromPost().

So your getInputHtml() method just needs to be aware that there’s a chance that the $value passed to it may be raw POST data, and react accordingly in that case.

If your field type is storing dates and you’re using Craft’s built-in date/time templates (_includes/forms/date.html and _includes/forms/time.html, which are rendered by that dateTimeField() macro in _includes/forms.html), then the POST data will look like this, for whatever input name you passed in.

array(
    'date' => '[localized date string]',
    'time' => '[localized time string]'
)

That looks like it would be tricky to deal with. Thankfully, Craft’s DateTime class has a handy-yet-awkwardly-named createFromString() static method which will check to see if a passed-in value follows that array format, and normalize it into an actual DateTime object for you, taking the localized date/time formats and timezones into account for you.

So all you need to do, from your get field type’s getInputHtml() and prepValueFromPost() methods, is check to see if $value['startDate'] and $value['endDate'] are arrays, and if so, run them through DateTime::createFromString().

We happen to have an existing field type that does the same thing: Store Hours. Rather than dealing with just two dates per field, it's actually dealing with with 14 (an Open and Close time for each day of the week), but it should be easy enough to adapt its code for your needs. Here’s its field type file: https://github.com/pixelandtonic/StoreHours/blob/master/storehours/fieldtypes/StoreHoursFieldType.php


Charge Model "amount" and "userId" not always populated

I'm pretty sure this issue is caused because the model is being passed to the event without being populated first (it only has the EXACT details that are manually populated when the record is created, not the additional functions).

I was able to use $chargeModel->planAmount just fine, and I was actually able to re-look up the model based on the passed model id, which properly populated the model before passing it back.


It’s possible to do this by making the entire CSS file a Twig template.

Create a new file in your templates folder, such as templates/css/styles.css, with all the dynamic styles you want.

To prevent the browser from reloading the file on each request, make sure you set cache headers in the template.

{# Tell the browser to cache this page for 30 days #}
{% set expiry = now|date_modify('+30 days') %}

{% header "Cache-Control: max-age=" ~ (expiry.timestamp - now.timestamp) %}
{% header "Pragma: cache" %}
{% header "Expires: " ~ expiry|date('D, d M Y H:i:s', 'GMT') ~ " GMT" %}

Then load the CSS file just like any other from your webpage templates.

<link rel="stylesheet" type="text/css" href="/css/styles.css">


Create Plugin to generate PDF files from content

Just in case anyone was wondering, it looks like I'll be going with mPDF, it seems to have better HTML/CSS support than either TCPDF or domPDF (which Printmaker seems to be based on).


How to save Matrix data programmatically in Craft 3

Saving Matrix fields programmatically got a lot easier in Craft 3 thanks to all the content refactoring.

use craft\elements\Entry;
use craft\elements\MatrixBlock;

// Figure out the section & entry type
$section = Craft::$app->sections->getSectionByHandle('news');
$entryTypes = $section->getEntryTypes();
$entryType = reset($entryTypes);

// Create an entry
$entry = new Entry([
    'sectionId' => $section->id,
    'typeId' => $entryType->id,
    'fieldLayoutId' => $entryType->fieldLayoutId,
    'authorId' => 1,
    'title' => 'My Entry',
    'slug' => 'my-entry',
    'postDate' => new DateTime(),
]);

// Set the custom field values (including Matrix)
$entry->setFieldValues([
    'summary' => 'Some "summary" custom field value...',
    'matrixField' => [
        'new1' => [
            'type' => 'blockTypeHandle',
            'fields' => [
                // the block's custom field values...
            ],
        ],
        'new2' => [
            'type' => 'blockTypeHandle',
            'fields' => [
                // the block's custom field values...
            ],
        ],
    ],
]);

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


How does the Structure section type work?

I don't know if its possible to be much clearer than the official docs on this matter, but basically a Structure is needed if your entries needs to be in a specific order (and you want to manage that order w/ an easy to use, drag-n-drop interface within the Control Panel), or if they need to be nested (i.e. hierarchical, with parent/child entries).

The alternative to a Structure is a Channel. A Channel doesn't have the ability to nest entries – in other words, it's a flat stream of content – nor can entries be sorted in a specific order; you're stuck with sorting by published date, title, ID or other "standard" meta data. The best example of a good use case for a Channel I can think of is a blog.

If you create a Channel and later realize that it should've been a Structure, you can convert it by visiting that Section's settings and choosing "Structure" for its type. You can also convert a Structure to a Channel, although if you later convert it back to a Structure your ordering/nesting data will be lost.

Some good use cases for a Structure could be:

A "Documentation" type section, with "main" entries (e.g. "Javascript") and sub entries (e.g. "Javascript / jQuery"). The official Craft docs are built using a Structure, where child entries (e.g. "Requirements") are nested under parent entries (e.g. "Installing and updating"). See this answer from Brad Bell for a bit more information on how P&T built the docs.
A "Navigation" type section – some people like to build their site's navigation using a Structure, which makes it easy to edit the order of the nav items, create dropdowns/sub menus etc. Here's a thread with some information more information on this approach.
A "Recipes" section, where you could easily sort the different recipes after course types (meat/vegetarian)

As for using Structures, I'm assuming you're talking about how to display the entries in a template – as the usage within the Control Panel should be fairly self-explanatory. Basically, outputting entries from a Structure is no different from the other section types:

{% for entry in craft.entries.section('myStructureSectionHandle') %}
    ...
{% endfor %}

However, if your Structure's entries are nested, using the nav tag instead of the basic for loop can be helpful in displaying the hierarchical content, because it can recursively output child entries:

{% nav entry in craft.entries.section('myStructureSectionHandle') %}

        {{ entry.title }}
        {% ifchildren %}

                {% children %}

        {% endifchildren %}

{% endnav %}

Beyond this, I think your question is a bit too open-ended to answer in detail, and you should probably create separate questions for any specific issues or problems you encounter working with Structures.


This is somewhat of a guess, but is based on what I could find. It might not answer everything but it might be a start :)

From what I can work out the grid work is worked out around the values you provide yourself, if you look at app/resources/js/craft.js on line 10244 this seems to be where the grid starts.

On line 10339 is the refreshCols function which seems to be responsible of figuring out how wide items are are where they should be placed.

It looks like Craft will take the values you supply data-max-cols="3" data-min-colspan="2" etc and try to work out the best possible layout (This is where data-position gets dealt with aswell) ...

line 10466
// Figure out all of the possible colspans for each item,
// as well as all the possible positions for each item at each of its colspans
...

line 10532
// Now find the layout that looks the best.
// First find the layouts with the highest number of used columns
....

etc etc, so it looks like there aren't really any set defaults, you just gotta play around with the numbers and see what works best for the layout you are trying to achieve.

Lastly, on line 10775 is:

defaults: {
    itemSelector: '.item',
    cols: null,
    maxCols: null,
    minColWidth: 320,
    mode: 'pct',
    fillMode: 'top',
    colClass: 'col',
    snapToGrid: null,
    onRefreshCols: $.noop
}

I realise I could be looking in the wrong direction and apologies if this doesn't completely answer your question, but hopefully it will provide an insight.


Empty matrix object after checking for a block type

So there are some changes to how .type() works in Craft 3 which you can read about here. What's happening is the type() you're setting here in your doNotCache is also getting applied later on in your template when you start actually looping over the blocks in entry.mainBody. There are two ways to solve this:

Reset the type() in your matrix block loop

{% for block in entry.mainBody.type(null).all() %}

Clone the mainBody field before you manipulate it

{% set doNotCache = clone(entry.mainBody).type('form').all()|length or craft.retour.getHttpStatus != 200 ? true : false %}


Image Optimize: How do I access specific colors?

Yep, using your above example, optimizedImages.colorPalette is an array, so you could do:

// Output the most dominant color
{{ optimizedImages.colorPalette[0] }}

// Output the second-most dominant color
{{ optimizedImages.colorPalette[1] }}


Internal server error in Admin after migration

After some debugging I found the answer:

Problem is caused by craft_searchindex using MyISAM as the table engine, while the rest are using InnoDB, and the server having enforce_gtid_consistency ON. This caused issues on transactions that included queries to MyISAM tables.

Seems that the reason for this is supporting full text searchess in old MySQL versions (as InnoDB gained full text search support around 5.6.4)

I'm now experimenting on switching the engine for that table and seems to work nicely.


Shipping for other category than what's set as default is not applied to total

Upon further investigation, it seems that no shipping is being applied after updating to the latest Commerce 2. Will report back here.


Assuming you have an entry to work with, something like this should work:
{% for block in entry.myMatrixFieldHandle if block.type == "employment" %}
    <select>
        {% for option in block.myDropDownFieldHandle.options %}
            <option value="{{ option.value }}">{{ option.label }}</option>
        {% endfor %}
    </select>
{% endfor %}

Otherwise you may need to get the field through the fieldLayout or by it's handle.
Update
craft.matrix is not exposed to twig like it is in php. To get the dropdown field options through the matrix field directly you'll have to go the long way around (matrix > blocktypes > blocktype > fields > field > options)
{% set matrixField = craft.fields.getFieldByHandle('employmentMatrix') %}
{% set blockTypes = matrixField.getFieldType.getSettings.getBlockTypes %}
{% for blockType in blockTypes if blockType.handle == "myBlockTypeHandle" %}
    {% for field in blockType.getFields() %}
        {% if field.handle == "myDropDownFieldHandle" %}
            <select>
                {% for option in field.settings.options %}
                    <option value="{{ option.value }}">{{ option.label }}</option>
                {% endfor %}
            </select>
        {% endif %}
    {% endfor %}
{% endfor %}

UPDATE: This is for craft 2. For craft 3 see Nathan S answer below.


Content from two sections but one of which is related to a specific category

You would do such things by first getting the entries IDs and then do a query to get all entries with these IDs:

{% set entryIdsA = craft.entries.section('SectionA').ids() %}
{% set entryIdsB = craft.entries.section('SectionB').relatedTo('CategoryC').ids() %}

{% set allEntryIds = entryIdsA|merge(entryIdsB) %}

{% set allEntries = craft.entries.id(allEntryIds).order('mySortByField desc') %}


In the CP, How to make images bigger when the users select images?

If you're running Craft 3, you can click an asset and then hit SHIFT + SPACE to open a Lightbox with the image.


Ok so I figured out the issue. I had the category field setup to have a limit of 1, which I assumed would be ok. My thinking was that you're only choosing 1 state. But because state is a sub category of country I need to allow for country and state AKA a limit of 2. Once I did this I was able to structure my template accordingly:

{% if user.addressMatrix | length %}

    {% for addressInfo in user.addressMatrix %}

         {% if addressInfo.type == "address" %}

            {% for item in addressInfo.region %}

                {% if item.level == 2 %}

                {{ item.title }}

                {% endif %}

            {% endfor %}

        {% endif %}

   {% endfor %}

{% endif %}

I think that future releases of Craft ought to have more options for category fields, like: Restricting selections to a sub category, limiting the number of sub categories.


Using modifyElementsQuery() to build a Radius Search?

So it turned out that the distance column error was sending us down the wrong path.

The issue was caused by 2 things:

1) As the original Craft entries query was using ids() any select string added via addSelect was being disregarded, the answer here was to move this logic into the having clause.

2) The second issue that was preventing the having clause from working was a missing groupBy clause.

The modifyRadiusQuery code in full:

private function modifyRadiusQuery(DbCommand $query, $value)
{
    $settings = $this->getSettings();
    $measurementUnit = $settings->unit == 'mi' ? 3959 : 6371;

    $geo = craft()->logic->stringToGeo($value['location']);

    if($geo)
    {
        $haversine = $this->haversine($geo['lat'], $geo['lng']);

        // ids()
        $query->join(Logic_GeoRecord::TABLE_NAME.' geo', 'elements.id = geo.elementId');
        $query->having($haversine.' < '.$value['radius']);
        $query->group('geo.lat, geo.lng');

        // find()
        // $haversine = $this->haversine($geo['lat'], $geo['lng']);
        // $query->addSelect($haversine.' AS distance');
        // $query->join(Logic_GeoRecord::TABLE_NAME.' geo', 'elements.id = geo.elementId');
        // $query->having('distance < '.$value['radius']);
        // $query->group('geo.lat, geo.lng');
    }
}

The DBCommand query that was fixed:

        $query->join(Logic_GeoRecord::TABLE_NAME.' geo', 'elements.id = geo.elementId');
        $query->having($haversine.' < '.$value['radius']);
        $query->group('geo.lat, geo.lng');


Update Asset Indexes not working for large number of assets

While Craft appears to give you a success message when the Update Asset Index modal displays a pretty checkbox, when working with a large number of assets, if you don't see a loading bar appear or see the indexed assets afterwards, it's possible you are running into a memory issue, and that pretty checkbox is lying.

Likely, if you look at your craft/storage/logs/phperrors.log you will find a memory error. Try increasing the memory available to your Craft install or increasing the memory_limit in your php.ini settings and trying again.


Asset Volume using Environment Variable on File System Path as literal string on upload

If you use environment variables, you have to be aware that you can't add anything to it in your fields. What this means is that $ASSET_ADHOC_PATH/website in your CP will not be parsed. If you use environment variables, the only thing you should have in the field is the variable, nothing else.

To do what you are trying to do, you might want to consider Aliases. These are great for the Control Panel because you can add to them so @aliasName/website will be parsed
and work the way you expect.

So in your case (and to get you going) with this ASSET_ADHOC_PATH variable set in your .env file, add the below in your config/general.php:

'aliases' => [
    '@assetAdHocPath' => getenv('ASSET_ADHOC_PATH')
],

Then in your volume settings use @assetAdHocPath/website and this should now work for you.

For the second part of the question, I'm guessing you may be trying to access an ENV in your template in which case you would use {{ getenv('ASSET_ADHOC_PATH') }} OR if you go the aliases way, {{ alias('@assetAdHocPath') }}.


You should be able to just compare the two dates directly.

{% if entry.promoEndDate >= now %}

Price valid until {{ entry.promoEndDate|date('d M Y') }}

{% endif %}


Show Matrix Assets from German language in other locales

@carlcs helped me in Craft Slack. Many thx to him. The solution at the end was to pull out the asset field from the main matrix field and to put them in a separate without localisation enabled.


Craft Request Filter Query Matching Drop Down Fields and Checkbox Fields

I'm probably late to answer this, but I've recentry encountered same problem and here's the solution I came to:

use params for dropdown fields and search for checkbox fields

So my code looks similar to this:

{% set orderParams = {} %}

{% for key, val in craft.request.query %}
    {% if val is not empty %}
        {% if key=='orderFinance' %}
            {% set orderParams = orderParams|merge({orderFinance:val}) %}
        {% elseif key=='orderStatus' %}
            {% set orderParams = orderParams|merge({orderStatus:val}) %}
        {% endif %}
    {% endif %}
{% endfor %}

{% set flagSearchQuery = [] %}
{% for flag in craft.request.query.orderFlag %}
    {% if flag is not empty %}
        {% set flagSearchQuery = flagSearchQuery|merge({query: 'orderFlag:'~flag}) %}
    {% endif %}
{% endfor %}

{% set orders = craft.commerce.orders(orderParams).search(flagSearchQuery).limit(100) %}


This should do it:

{# Get all of the entries in the 'volunteerPosition' section #}
{% set entries = craft.entries.section('volunteerPosition').find() %}

{# Do we have any %}
{% if entries|length %}

    {# Loop through them #}
    <ul>
        {% for entry in entries %}
            <li>{{ entry.volunteerShortDescription }}
        {% endfor %}
    </ul>

{% else %}
    {# Nothing to see here #}
    Sorry, nothing to show.
{% endif %}


Imagick installation passed with warnings

Click on the "i" graphic and it will probably tell you that GD is installed, but Imagick isn't and it is recommended.

You can verify that Imagick is installed and available to PHP/Craft by going to yoursite.com/admin/utils/phpinfo and searching for "imagick".  If it's not there, then it has not been installed properly.


How do I cycle a class on a Matrix block?

This is mostly likely a scoping issue inside the switch statement.  Try something like this:

{% for block in entry.asideNavigation %}

    {% set index0 = loop.index0 %}

    {% switch block.type %}

        {% case 'textBlock' %}
            <li class="aside__nav__item {{ cycle(['cs-a','cs-b'], index0) }}">
                ...
            </li>

        {% case 'imageBlock' %}
            ...

    {% endswitch %}

{% endfor %}


It's not obvious, but you need to select the email field in the form settings, then select a notification from the pane on the right to send to the value in the field.


You're close! This should work:

 {% set $fifth_listing = craft.entries.section('listing').level('1').nth(5) %}


Remove trailing comma from an output loop?

There is a special tag inside for loops you can use for this

{% for category in entry.mediaType %}
    {{ category.title }},
    {% if loop.last %}
        {{ category.title }}
    {% endif %}
{% endfor %}

Full list here


Can a user photo support a remote image?

The answer to that is currently "no", in Craft 2.x.  However in the upcoming Craft 3.x, user profile photos are proper "assets" and can be saved to any asset source.

  I'm looking to do a remote image (from plugin) as the user profile image. I've got the path saving to the column, but the image is not rendering. Anything special I need to do to get that to render?

I assume you're just ignoring Craft's default user profile "photo" field and adding your own custom one?  Or are you trying to replace the profile field that Craft uses to display profile photos in the CP with your own custom one.  I'm having a hard time seeing how you'd pull off the later in the current version of Craft 2.x.


Yes, absolutely. Craft have some case studies which illustrate that top brands trust them to handle large amounts of content while making it easy to publish more: https://craftcms.com/news/case-studies

My second point is a huge selling point for a good CMS. If your publishing process is difficult or confusing then you as an admin/client become frustrated. Craft is fast and easy to digest from a publishers point of view.

(Wes mentioned relationships)
By design, you should only need to add a piece of content to your CMS once - and then 'relate' different entries together as new ones are published. e.g. A new 'Service' (entry) is related to an 'office location' (entry) where that service is provided.  Then, when a visitor is viewing that office location they are able to see any services which may be available there. (Just a simplified example)

Planning and designing what your content-types consist of and how different types of content can work together to tell a story to a visitor - will mitigate any major shifts in direction which often happen on-the-fly (the most expensive way to build a website).

Coming back to your question.
Craft is very good at storing your content efficiently.

Craft uses Twig as a template language, which requests content from Craft. The trick is to only tell Twig to get what you need for any given page. This isn't hard once you understand the approach.

Images are also uploaded once and then re-saved (image transforms) into different sizes as they are used differently through your site.

The effect is that instead of slowly trying to load an image which is large in size, a small image is loaded quickly.

Hope that helps. I'm sure you'll get more answers too...