Passing data to includes - overrides & defaults

There is no reason why your code should work, because any variable declared outside of your include file in the with {...} block will be immediately overwritten by your variable definition (#set) in the beginning of your included file.

What you need to do in your include is to check, if the variable was passed in from the outside, and if not, set it to a default value.

So I guess the best way could be this in your includes/social.twig file:

{% set padding, size, color, hover = padding ?? '2', size ?? '4', color ?? 'pink', hover ?? 'black' %}

The ?? used here is called the null-coalescing operator. It will check if the variable before the ?? is defined (which it is if provided from the outside) and in case it's not not, fall back to the value after it. Have a look here, if you do not know it: https://straightupcraft.com/events/twigs-null-coalescing-operator


How to make a code/settings for accessing the one database from 2 different html files with {slug}

This makes more sense :)

So basically, you want to have info from one entry on multiple pages and your problem is that in the section settings, you can only define 1 template for an entry.

One way to go about this is to create your own urls when clicking on an entry where you add the {slug} of your entry to the url, something like this: {siteUrl}/episode-guide/recap/{entry.slug}

You can create a dynamic route for this url that takes you to (for example) the recap.html template. Here you just get the last segment (being the slug) and retrieve the correct entry from your database and show only the recap info.

{% set entrySlug = craft.request.lastSegment() %}
{% set entry = craft.entries.section("sectionName").slug(entrySlug) %}


Logging in to Craft via Vue/Javascript apps

And just like that I stumble over this wonderful blog post https://digitalevangelist.net/blog/vuejs-craft-cms-single-page-app-logging-in-to-craft


Class '...SiteModuleService' not found when used inside scout.php

Worked when I added a use-statement to the top of scout.php:
<?php
use modules\sitemodule\services\SitemoduleService as SitemoduleService;

And then:
'indices'       => (new SitemoduleService)->getIndicies()


CP form submissions occasionally reaching PHP's 300 second timeout

I can think of a couple things why this is happening:
1) Custom code doing a save operation.
If you're hooking into onSaveEntry for example,  Craft also lets other plugins have a chance at calling their own save code as well.
So when you do a saveEntry (or other element), Craft is going to repeat that call when you do it from your own code, basically putting you into an infinite loop because it keeps getting called until the server times out.
The fix is to make sure  you only call saveEntry once. There's a couple ways to do this depending on what you're trying to do.
One way to debug this would be to a create super simple plugin, using Business Logic or PluginFactory that listens for the saveEntry event and logs it.
If you see the plugin's log fill up, then some plugin is putting itself into a loop more than once.
2) runTasksAutomatically is not being called
Over time, Craft generates a lot of cache files, sessions, etc. Craft will automatically do some housekeeping for you and clean this up, however, the runTasksAutomatically config doesn't run on some server setups, forcing you to do the maintenance yourself. It's like a stuffed up drain, if it doesn't run for awhile, it takes longer to purge.
If your server doesn't support cron, you could use an uptime monitoring service like Uptime Robot or Pingdom to trigger the task call for you periodically.


Pagination: Next/Previous related to author

You are trying to merge an object of type ElementQuery with an array so your object will be transformed as an array and merged with the new array. Of course you'll end up having an array instead of a query so you can't execute it in order to fetch the entries.

Instead of merging it, why not setting the parameter directly?

{% do param.authorId(author) %}

Furthermore authors are not related to entries  (except you set them in an additional field)


How do I set up a section for pages with very flexible content?

I would use a matrix field with multiple types.


In your code you are only caching until the dateOrdered of the latest order. That means that viewing the page will always be ahead of the cache time.

You could look to do the following:

{% set latestOrder = craft.commerce.orders.order('dateOrdered DESC').first() %}
{% set cacheKey = 'orders-' ~ latestOrder.dateOrdered|date('U') %}

{% cache using key cacheKey %}
  {% set orders = craft.commerce.orders.order('dateOrdered DESC').find() %}

    {% for order in orders %}

{{ order.id }}

    {% endfor %}

{% endcache %}

This creates a cache key based on the date of the latest order. Therefore, when there is a new order this key will change.


Craft 3 Module Working but Throwing Errors in web.log

You'll get that error in PHP when you try to iterate over a variable that isn't an array.

My guess is you'd be able to guard against it with something like:

if (is_array($variants)) {
    foreach($variants as $variant) {
    ...
    }
}


Access Element API JSON in another environment

Brandon answered this in a github issue https://github.com/pixelandtonic/ElementAPI/issues/4

You can do that by setting your endpoint config to an anonymous function:

'my/endpoint/pattern' => function() {
    HeaderHelper::setHeader([
        'Access-Control-Allow-Origin' => 'http://example.com'
    ]);

    return [
        // ...
    ];
}


Paul's suggestion of using order fields worked perfectly.


If you want a rich text field on a front end - this question has been answered in detail here:
How do I enable redactor rich text editor in a front-end form?

In short technically possible but not recommended.

If you want a rich text field for a back end, i.e. plugin, form:

The craft macros for form fields live in craft/app/templates/forms - however I do not believe there is a macro for a rich text field.  There are text and textarea macros you can use.

However, I think it is possible in a plugin - this apparently creates a rich text field widget in your craft dashboard, so you should be able to pinch the relevant code from: https://github.com/gilleard/RichTextWidget/blob/master/richtextwidget/widgets/RichTextWidget_DashboardWidget.php

(Specifically look at public function getSettingsHtml() I think)


It may be that you need to select the redactor config on your field's settings...

Example - say you edited config/redactor/Standard.json

Go into your admin panel, then go to Settings, then Fields.

Open one of your redactor, and scroll down to where you select the field type. When you select Redactor, you get a new option underneath.

And you then select which Redactor Config you want to use.

If you're not seeing it, maybe try clearing your caches. And then double-check that you've saved your redactor config in the right place, and it's got the right file permissions.


Those should not be logged in web.log when running Craft 3.x, but rather in the web404s.log -- assuming you don't have devMode on (which it shouldn't be on for production...)

Vide: Zen and the Art of Craft CMS Log File Reading

Also should you really want to customize things, it's not hard to do with Craft CMS, check out: Creating a Custom Logger for Craft CMS


It doesn't appear there is an easy way to do this by extending that template. If you take a look at the template templates/entries/_edit.html you will see how the create/edit entry screen creates this view. It is extending _layouts/cp, but it's overriding the main Twig block to do some custom stuff. You can include the tabs in your main block like so:

{% block main %}

        {% include "_includes/tabs" %}

{% endblock %}


Show posts related to entry AND all posts not related to any entry

Building on this answer, and this question, here is what I would try:

Get the posts from the current city:

{% set currentCityPostIds = craft.entries.section('news').relatedTo(currentCityFilter).ids() %}

Get the posts with no city (uses search):

{% set noCityPostIds = craft.entries.section('news').search('-city:*').ids %}

Make one list of all the ids (twig merge filter):

{% set postIds = currentCityPostIds|merge(noCityPostIds) %}

Get all the posts with those ids:

{% set postsToPaginate = craft.entries.id(postIds) %}

Now you can paginate them:

{% paginate postsToPaginate.order("featured desc").limit(10) as pageInfo, pagePosts %}


Related to entries in categories in a plugin

Ok worked this one out eventually myself. If anyone else finds this helpful.

$userinterests = craft()->users->getUserById($userid)->getContent()->getAttributes();
$criteria = craft()->elements->getCriteria(ElementType::Entry);
$criteria->relatedTo = array(
        'targetElement' => $userinterests['relevantFieldToCheckAgainst'],
        'field' => 'EntryFieldToCheckIn'
);
$relatedEntries = craft()->elements->findElements($criteria);


Sure, I've had experience with two different types of sorting with SuperTable (check the link for associated JS).

If you're modelling the fieldtype after a table, you might like to use the Craft.DataTableSorter method. Its pretty restrictive to a table layout, and you'll need to give each tr element a data-id.

Craft.FieldType = Garnish.Base.extend({
    sorter: null,

    init: function() {
        var $table = $container.children('.table');

        this.sorter = new Craft.DataTableSorter($table, {
            helperClass: 'editabletablesorthelper',
            copyDraggeeInputValuesToHelper: true
        });
    },

    addRow: function() {
        var $tr = $('<tr/>');
        this.sorter.addItems($tr);
    }
});

Or, for more abstract sorting, you can have more control using Garnish.DragSort - essentially a general drag and sort function. This is what Matrix uses.

Craft.FieldType = Garnish.Base.extend({
    sorter: null,

    init: function() {
        var $rows = $container.children('.table-rows');

        this.sorter = new Garnish.DragSort($rows, {
            handle: 'tfoot .move',
            axis: 'y',
            collapseDraggees: true,
            magnetStrength: 4,
            helperLagBase: 1.5,
            helperOpacity: 0.9,
        });
    },

    addRow: function() {
        var $tr = $('<tr/>');
        this.sorter.addItems($tr);
    }
});


redirect to url and set variable in template

If you want to reload the form, you don't need to (indeed, shouldn't) redirect to the posted URL. That's why the form's action attribute is empty.

This should work:

public function actionTest() {
    craft()->urlManager->setRouteVariables(array(
        'someVar' => 23
    ));
}


Search form - Passing only field params that are not empty or selected

That's just the way forms work in html. If you don't want to use a POST method, (because that would make the results not URL-addressable at all), I'd recommend using an intermediary Twig template to perform a redirect based on what parameters exist - i.e., set your form action to search/process and in that template write a load of conditional statements to build up a query string to pass into a {% redirect %} tag which loads search/results.
If you don't want two templates, you could instead set your form method to POST and then in your search/results template you could conditionally perform a redirect to the same template appended with your custom query string, and use craft.app.request.method to distinguish between the request types to avoid an inifinte redirect loop.


How to remove category link from redactor links but leave assets and entry link

At the moment, your are overriding $event->linkOptions which contains an array with all options to an empty array with $event->linkOptions = [].
First, add the below to your module and refresh any page on your site so you see what you are working with:
Event::on(
  RedactorField::class,
  RedactorField::EVENT_REGISTER_LINK_OPTIONS,
  function(RegisterLinkOptionsEvent $event) {

    Craft::dd($event->linkOptions);
  }
);

In the array you saw above, you want to remove the object containing a 'elementType' => 'craft\\elements\\Category'.
You can do this by searching $event->linkOptions for craft\\elements\\Category, remove it but still returning the rest of the options.
Here's one way of doing so:
Event::on(
    \craft\redactor\Field::class,
    \craft\redactor\Field::EVENT_REGISTER_LINK_OPTIONS,
    function(\craft\Redactor\events\RegisterLinkOptionsEvent $event) {
        $defaultOptions = $event->linkOptions;

        // Search for category element
        $categoryLink = \craft\helpers\ArrayHelper::where($defaultOptions, 'elementType', 'craft\\elements\\Category');

        // If present, remove the option and return the rest
        $event->linkOptions = \craft\helpers\ArrayHelper::without($defaultOptions, key($categoryLink));
    }
);


You can query for the same entry in another locale by explicitly setting the locale parameter.

{% set de = craft.entries.id(entry.id).locale('de').first() %}
{% set en = craft.entries.id(entry.id).locale('en').first() %}

German:  {{ de ? 'OK' : 'nope' }}
English: {{ en ? 'OK' : 'nope' }}


Inserting Relationship Into Entries Field - Plugin Not Saving Relation

Figured it out, trying to use the Entry as the source was wrong as the 'stores' relationship field actually belongs to the matrix field.

So by setting the matrix field as the source this is now working just fine!

craft()->relations->saveRelations($field , $matrixBlock, $relations);


Where should I make an HTTP REQUEST using AJAX?

You should try to keep your controllers as "thin" as possible. That is, they should call other classes, which do the actual work.

The Craft approach is to keep most of your code in service classes, and if you're just starting out with plugin development, I recommend you follow this pattern.

Bear in mind, though, that your service classes define your plugin's API.

In other words, if you add a public method to one of your plugin service classes, you're essentially telling everyone "hey, you can use this method if you like".

If you're interested, I wrote a blog post about this a while back.

In summary, keeping your code in services is much better than keeping it in controllers, but don't treat your service classes as a dumping ground for everything.


You can grab the content of a field for an element with

$myTableField = $entry->getContent()->getAttribute('fieldHandle');

You can modify the variable and send it back with

$entry->getContent()->setAttribute('fieldHandle', $myTableField);

Since you are probably in an event you should make sure your entry has the correct type and the correct section

$entry->getSection()->handle === 'mySectionHandle' && $entry->getType()->handle === 'typeHandle'

If you want to change every table field and not just a certain one you can do

foreach($entry->getFieldLayout()->getFields() as $field){
    if($field::class === 'insert the class of the field here'){
        $table = $entry->getContent()->getAttribute($field->handle);
   }
}


What would it take to make Craft composer based?

I'm not 100% sure what you're looking for, but Craft does use Composer to manage its own dependencies.

If you're referring to using Composer in your plugin, it's as simple as creating your composer.json file in your plugin's root folder and running composer update.


I think you might be going about this the wrong way. Personally, I'd create a single Matrix or Super Table field and attach that to your home page single. This is far easier for your editors to maintain and doesn't require the entry type's field layout every time you want to rearrange content.
However, to answer your question:
What you're looking for is the field layout definition for your entry type (which is effectively what you're looking at in the screen capture you've provided) and iterate over the fields ($entry->fieldLayout->fields) as necessary, either using a switch statement using the field name for conditional processing or by pulling in an include based on the field's name.
If you decide that the latter is really what you want to do, I'll help with some suggested logic but I'd encourage you to look at the first option before digging into the Craft class reference!


The code below ended up solving the issue for me.

{% for row in 0..rows %}


Displaying content defined by radio button in admin panel

Close! You can get the selected radio button by its label (what the user sees) or the value you setup in the admin. I'm assuming you're using the value.

{% if entry.column == "two" %}
    {# show 2 column content #}
    2 columns
{% elseif entry.column == "three" %}
    {# show 3 column content #}
    3 columns
{%endif%}

You could also try a switch statement. That gives you a way to fall back to a default option, which might be useful, and a cleaner way to check for more than a couple options (say the client wants a 3 column option with some a special sidebar that doesn't really fit):

{% switch entry.column %}

    {% case "two" %}

       {# show 2 column content #}
       {% include "layouts/_2columns.html" %}

    {% case "three" %}

       {# show 3 column content #}
       {% include "layouts/_3columns.html" %}

    {% case "threespecialsidebar" %}

       {# show 3 column content #}
       {% include "layouts/_3column_sidebar.html" %}

   {% case "default" %}

      {# default to a 1 column layout #}
      {% include "layouts/_default.html" %}

{% endswitch %}

To keep yourself sane, in the switch example, also consider using a include which will bring in a corresponding layout file, depending on which layout you want.  (A stray div for example will drive you crazy.... consider putting your markup in separate files.)

One last thing: from a client standpoint, depending on what you're doing, an entry type might be a better way to handle multiple layouts or if there needs to be additional options/fields in a  certain layout. (In that case, use entry.type instead of entry.column but the rest of the syntax posted above would be exactly the same).


Mike: yes you do. It sounds like you had your site built by another developer?

Unlike other CMS, everything that displays on your website in Craft is custom built. The gist is you setup a bunch of fields on the backend (Craft's "control panel")—which is probably what you did. Think of the control panel as simply an interface to database.

However, those fields won't display anything on the front-end. What is output is controlled by templates. If you're used to something like WordPress, Craft basically only has one "theme" and it's not accessible in the control panel.

In short, you basically need to tell Craft where to spit it out.  Depending on how your site was built, it's probably in a _layout.html file inside the craft/app/templates folder.

If your field's name is Meta Description, you could add it to the template in the appropriate place  somewhere like:

{% if entry is defined and entry.metaDescription is defined %}
  <meta name="description" content="{{ entry.metaDescription }}">
{% endif %}

In the control panel, the field would need to added to any section you want to use the Meta Description. If you've added that field to a section, the field will be output.

If you need more help with this, check out the Craft documentation, Mijingo's  lessons on Craft, or hire a Craft professional to help you out.


RedactorClips and RedactorStyles plugins not working

Did you add the buttons to your toolbar by editing or adding a config file:
/craft/config/redactor/my_custom_toolbar.json?

You can configure multiple redactor setting files and apply them individually to your rich text fields from the field settings.


How can I mitigate caching performance issues with Craft?

First off:

Craft stores cached content in the templatecaches table.
Craft stores criteria mapping to the cached versions in templatecachecriteria.

1. Make sure Craft isn't caching too much.

Originally, we were using

{% cache using key craft.request.path if not craft.config.devMode %}

We discovered it's critical to use the globally keyword:

{% cache globally using key craft.request.path if not craft.config.devMode %}

Without the 'globally' keyword, Craft continues to collect query string variables and will make a record in templatecaches for each unique set of query string variables. That means that things like CRM mailers which may include a unique query string in every email will create tons of entries in templatecaches. I'm not sure why you would ever want to use {% cache using key %} without the globally keyword, as it seems like without the globally keyword, the key isn't being used.

2. Reduce 'criteria'.

When caching a {% cache %} tag, it looks like Craft tracks all of the 'criteria' to determine when this chunk of content should be invalidated. Examples of criteria are:

Building entries from craft.entries,
Building related entries from an entry, or
Getting all the assets for a particular field on an entry.

So, for example, if you Are showing a list of the five most recent blog articles, you might have

1 Criteria for building the list of recent entries,
1 Criteria for each entry getting a cover photo,
1 Criteria for each entry getting the author, and
1 Criteria for each entry getting the author's photo.

So, that's 16 criteria for this example. Some of the pages on our site did had as many as 247 associated criteria.

Criteria are stored as JSON within MySQL. For each one, Craft has to decode the JSON and compare it to determine whether it should be cleaned up or not, so if you end up with a really high number of criteria, the background tasks will take longer and longer, and in our experience, eventually get stuck.

3. Linking to transformed images might prevent for your page from caching.

If you link to a transformed asset but don't include it on the page (say, as the target for <a> but not the src for an <img> tag.) then you may interfere with the caching of your page.

Craft doesn't generate transformed assets until they are requested, which is fine for <img> tags but not for <a> tags. Instead, it returns a special URL that, when requested, will generate the transformed asset on demand. After the asset is generated, Craft will simply return a link to the generated asset.

However, Craft will not cache any page which has these special URLs in it. For example, if you're caching a page with an image gallery with thumbnails that need to be clicked through to the larger (but still transformed) version, Craft will not cache that page until after all of the large versions have been generated.

I'm interested to know if anyone else has run into these issues, whether there's any other tips worth knowing for controlling performance of Craft's caching.


This is fixed in 3.0.0-beta.10. Additionally, there's no longer the concept of environment variables in Craft, instead we now have aliases. So instead of using:

{siteUrl}assets/data/clients.xml

Use:

@web/assets/data/clients.xml


Accessing the attributes of an Asset field

I'm assuming that Alt Text (handle altText), Source Name (handle sourceName) and Source URL (handle sourceUrl are all plain text custom fields you've created on your Assets.

If so, you'd be able to access sourceUrl the same as the others:

{{ entry.assetHandle.first().sourceUrl }}

They definitely aren't attributes on Craft's AssetSourceModel.


You could create a simple plugin with just a Template Variable that sends the mail: https://craftcms.com/docs/plugins/variables

Not sure if I'd put this kind of logic in templates though.


Problem installing plugin via path repository

The article I wrote So You Wanna Make a Craft 3 Plugin? may help you in terms of figuring out how to properly set up a "host" website to run your plugin development from.

TL;DR your repo shouldn't point to your site's vendor directory, it should point to wherever that plugin exists on your local dev environment.


Image transforms on remote server are broken by `cpresources/transforms` url

1.) Did you check if you have GD extension or ImageMagick extension working on the remote system?

2.) Are you using Apache on your remote system? If yes, is mod_rewrite working? (because the second URL does not point to a real file but is rewritten instead)

3.) Maybe you are using Nginx on the remote system and therefor pretty urls are not working?


Building an area for users to add content for Craft site

Welcome to Craft!

For starters, I would definitely recommend checking out the Pixel and Tonic Guest Entries plugin, brought to you by the guys who built the CMS. As the title suggests, it allows users to create entries from a custom form on the website front-end.

So, from your example, you can have an 'Events' channel and allows users to create entries (events) using the form.

These entries can then be moderated like any normal entry.


In any for loop you can use the loop variable that twig gives you.

For example:

{% for row in myTable %}
  {% if loop.last %}
    This is the last row
  {% else %}
    This is anything but the last row
  {% endif %}
{% endfor %}

More information on the loop variable can be found in the twig docs.


For my answer I am going to assume you are running Craft 3.

Notes are displayed in the sidebar:

When viewing the "Current" version of an entry, you can see the notes in the sidebar from when that entry was last saved.

If you go back through the version history of an entry, the notes in the sidebar will change to the notes left from the previous version of that entry.

You can also add notes to a draft version of an entry:

Once the draft has been published, the draft version will now become the "Current" version, and the notes from the draft should show in the sidebar.


List Only Child Categories Related to Entries

Having the need for a similar setup to yourself, I came up with a more efficient example below.

{% set entryIds = craft.entries.section('news').status('live').limit(null).ids() %}

{% set parentSlug = craft.request.getSegment(1) %}
{% set catParent = craft.categories.slug(parentSlug).first() %}

{% set categories = craft.categories.relatedTo({ sourceElement: entryIds }).groupId(1).limit(null).descendantOf(catParent).find() %}

{% nav category in categories %}

        {{ category.title }}
        {% ifchildren %}

                {% children %}

        {% endifchildren %}

{% endnav %}


How to save extra data when I save an entry

I think the short answer is yes, you do need a plugin to listen for events or tie into Craft's hooks.

Luckily if that is all you need to do you can probably get away with writing a plugin that is only the singular plugin class file, you may not need any other plugin classes (models/records/etc).

It seems as if you want to listen for onSaveEntry.


Unable to set error message in onBeforeDeleteUser

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

craft()->userSession->setError() is just a wrapper for craft()->userSession->setFlash() that uses a key of error and saves the message to user session and is good for one request.  Multiple calls to it just overwrite the same key causing the last one in to win.

You could maybe use setFlash() directly, passing in your own key, then add some JS for displaying the additional flash message similar to how Craft does it.


I just had a bit more of a look into this, I got the same error as you but by changing

'id' => array(AttributeType::Number, 'required' => true, 'unique' => true),

to just

id => AttributeType::Number

It fixed the issue and I was able to validate on it no problem, I don't think you need to worry about the ID being unique or being set on the model as this will be handled automatically by your record when you use it to save to the database, so you can be certain that every models id will always be unique.


Can multi-environment configuration be used in 'index.php'?

Should be able to. Use a switch statement to check on the host and then server up the correct environment configuration like so:

public/index.php:

switch (strtolower($_SERVER['SERVER_NAME']))
{
    // Staging
    case 'stage.mydomain.com' :
        define('CRAFT_ENVIRONMENT', 'stage');
        $craftPath = '../../craft';
        break;

    // Local
    default :
        define('CRAFT_ENVIRONMENT', 'local');
        $craftPath = '../craft';
        break;
}


Fetching entries from an advanced search form on the front end

I came across a similar issue today where I was creating a search form that included checkboxes. I did it as follows.

First, I checked if the URL had the query string I was looking for and joined the query string since it's an array. I used OR because I want it to search for any of the checked options.

{% if craft.request.getParam('services') %}
    {% set services = craft.request.getParam('services') %}
    {% set services = services|join(' OR ') %}
{% endif %}

The query string in getParam('services') is the same as the name field of the checkbox.

Then I listed out my options

{% for option in craft.fields.getFieldByHandle('memberServices').settings.options %}

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

{% endfor %}

The conditional that gives the checkbox the checked attribute is

{% if services is defined and option.value in services %}checked{% endif %}

That is, if services is defined (is in the URL) and the option value is contained within the services variable, apply the checked attribute.

It also works with multiple checkboxes, IE the URL search?q=&services%5B%5D=counselling&services%5B%5D=supervision&sessions=individual will check the "Counselling" and "Supervision" "services" checkboxes, and the "Individual" "sessions" checkbox.


Charge plugin redirecting to page with "1" on it

I'm the developer of Charge.

I've never directly observed that behaviour, but it sounds like it's most likely hitting a redirect failure and falling back to some base success/fail responses.

The most likely cause of that, is that you've not specified the default success route in the Charge settings. You'll find that under Charge > Settings > General > Success URL.

In there, you can specify the exact redirect route to push a user to after a successful transaction.

A common format would be something like thanks/{slug}, and load up your receipt template, on a path like payments/receipt etc..

Alternatively you can supply a hidden input on the form called redirect with the url you'd want the user redirected to after the transaction completes.


It's my understanding that Twig's set tag can only be used on variables.

But in your case entry is an object and title is it's property.

You could however create a work-around:

{% set my_title = 'New' %}
{{ my_title is defined ? my_title : entry.title }}

If my_title is defined it will be outputted.


Transfer licenses into another Craft ID account

You will have to release the license in your Craft ID account:
https://id.craftcms.com/account/licenses/cms

After that you will be able to claim the license in your other Craft ID account:
https://id.craftcms.com/account/licenses/claim


Can the Element API export Craft Commerce orders as the element?

Orders are in fact an ElementType in Craft.

See Commerce_OrderElementType.php inside the commerce plug-in folder. With that said you should have no problem retrieving orders like you would any other element type in Craft.

There are also services available that make it very easy to retrieve orders so you may find a simple PHP plug-in will get the job done in terms of returning JSON for an order(s).


Sorting multi-dimensional grouped arrays

Not really an answer that fixes the question per sé if anyone else has the same issue, but none the less the answer that worked for me was simple:

Split up your sorting where possible and simplify things!

I wanted my main array to be sorted by condition A, grouped by condition B and than sort the sub arrays alphabeticaly. All done to the same array in a few lines of code so I could use this one array in my template to get all information from it. Bad idea.

So what I did was sort everything by condition A in PhP in my plugin, in my template I than group everything by condition B and only when I needed to iterate over my array to reveal my sub arrays, only then I sort the values alphabetically.

So short answer: keep it simple damnit! :)


Entries relations with additional fields

From a database point of view you would have a pivot table between stores and products. And in that pivot table you would have additional columns like the price.

Using native fields

You can‘t do that on a relation field per se. (In this case entry field, assuming that products are entries) But you could wrap a repeatable field around an entry field and a price field, e.g. matrix or table and build the relationship this way. This way you can select products from within a store entry and put a price on each product.

One caveat is that you can’t bulk select products anymore. You’d have to select them one by one.

Alternative solution

You could write a custom module where you create a new field type that solves your problem. This would not result in an actual pivot table but it would work in a similar way. As far as I know a field type's value is bound to be saved in a single database column (may be wrong). However, you could even come up with some kind of bulk editing solution if you want to, although this would require some more work.


There is currently not a native way to do this in Craft. You should consider adding a thumbs-up/comment to this feature request if you'd like to see it, though.


Separated DB for each locale in subdomain with no shared Craft installation

Generally speaking, locales are designed to share the same templates, so craft is not necessarily looking for a /template/[locale]/ folder to find the correct templates to load. You may have to specify the different locale template paths as part of your section settings in that locales database. As far as I know the only automatic locale routing happens in your public folder, if craft is trying to resolve a route for a static page.

I'm curious as to why you would want to point the different locales to different databases? Keep in mind that structure and data are both stored in the craft database, so if you point 'locale1' at 'db1', and 'locale2' at 'db2', you are essentially loading two entirely separate sites (with their own CP, users, sections, fields, etc). This might make sense if you want to share templates and resources between the two sites. However, if you are also not sharing templates, then it might make more sense to just create two separate installations of craft.

Update

Regarding licensing and subdomains. My understanding is that you can use the same craft license on more than one craft install as long as they share the same primary domain (subdomains are ok). In your case you would set up your local dev environment to be something like: 'project.craft.dev' and 'localeA.project.craft.dev'; and the production environment to be 'domain.com' and 'localeA.domain.com'. You can then purchase the license on 'domain.com' and copy the license file (craft/config/license.key) over to 'localeA.domain.com'.

This is presuming of course that they share the same primary domain. What you can NOT do is create 'domain-localeA.com' and 'domain-localeB.com' using the same license.


I don't actually think Commerce has an option to disable guest checkout, no.

But Craft itself makes this, in effect, quite easy.  (In fact, Commerce's whole concept of customers is largely separate from the Craft concept of users.  A customer may be a user, and vice versa, of course, but they are really two separate things.)

In any case, you can hide all checkout access and pages behind {% requireLogin %} tags so those parts of your front end are simply then not reachable by customers who are not logged in users.

https://docs.craftcms.com/v3/dev/tags/requirelogin.html


Entries grouped by Category and then Sub Category

You can get the categories to display hierarchically pretty efficiently using the {% nav %} tag:

{% set categories = craft.categories.group('myGroup').find() %}

  {% nav category in categories %}

      {{ category.title }}
      {% ifchildren %}

          {% children %}

      {% endifchildren %}

  {% endnav %}

Then, you can add in the related entries like so:

  ...
  {% endifchildren %}

  {# Are we on the second level of categories? #}
  {% if category.level == 2 %}
    {# Look for any entries that are related to this category #}
    {% set entries = craft.entries.relatedTo({
      targetElement: category,
      field: 'myCategoriesField'
    }) %}
    {# If there are any, then output them in a nested UL #}
    {% if entries|length %}

        {% for entry in entries %}

{{ entry.getLink() }}

        {% endfor %}

    {% endif %}
  {% endif %}

That code suffers from the “N+1” problem though - each 2nd level category is going to need to initiate a new SQL query to fetch the related entries. So rendering this list will require N+1 SQL queries – one query to geth the initial set of categories, plus N, the total number of second-level categories. If you have 100 categories, that’s 101 SQL queries.

To solve this, you’d need to “eager-load” the related entries. Craft doesn’t support that of the box, but Mike Pepper has a nice little plugin called Fetch which makes it possible.  Download and install that, and then you can do the following:

{% set categories = craft.categories.group('myGroup').find() %}
{% do craft.fetch.entries(categories, 'reverse:myCategoriesField') %}

  {% nav category in categories %}

      {{ category.title }}
      {% ifchildren %}

          {% children %}

      {% endifchildren %}

      {# Are we on the second level of categories, and are there any related entries? #}
      {% if category.level == 2 and
            category.fetched('reverse:myCategoriesField')|length %}

          {% for entry in category.fetched('reverse:myCategoriesField') %}

{{ entry.getLink() }}

          {% endfor %}

      {% endif %}

  {% endnav %}


How do you get the user id on the front-end?

In Craft, there is no difference between the currently logged in user in the CP, and the currently logged in frontend user. Whenever a user logs in (be it through a frontend form, or the CP login page), it results in that user being logged in. Period. There's no 'being logged in in the frontend', as far as Craft is concerned.


As a quick but not elegant fix, You can disabled the entries you don't want to show up in the url.

When you want to use the content just put

 craft.entries({
   section: someSection,
   status: null
 })

or

 craft.entries({....}).status(null)


ImagickException: data encoding scheme is not supported `/var/www/html/storage/runtime/temp/P0LY_Test60a2e191a91de2.16978634.webp' @ error/webp.c/ReadWEBPImage/338 in /var/www/html/vendor/pixelandtonic/imagine/src/Imagick/Imagine.php:69

Based on that error, it definitely seems like an Imagick bug or Imagick configuration issue.
https://github.com/ImageMagick/ImageMagick/issues/22
https://github.com/gographics/imagick/issues/181
I don't understand most of that (sounds like you might have a webp image that is using some extended features that Imagick doesn't know about), but hopefully it points you in the right direction.


Reference a field name relatedTo(category)

Not sure I totally get your problem, but you can use bracket style notation to use variables for field handles, i.e.

{{ variable[someVariableHandle].topLeftStyles }}

or even something like

{{ variable[someVariableHandle][someVariableProperty] }}

As for actually outputting the fields in a sane manner, you'll need to map the variable field handles to your entries in some way – one way to do it is to simply use a naming convention for the field handles where you use some unique property on the entries (e.g. the entry ID) as part of the handle:

...
{% set fieldHandle = 'fieldname-'~entry.id' %}
{% if variable[fieldHandle] is defined %}
    {{ variable[fieldHandle].topLeftStyles }}
{% endif %}
...

Another way is to manually set up a map in your template – here's an example using entry IDs for keys, and the field handles for values:

{% set fieldHandles = {
    35: 'someFieldHandle',
    464: 'anotherFieldHandle'
} %}
...
{% for variable in sitemap.relatedTo(category) %}
    {% set fieldHandle = fieldHandles[variable.id] ?? null %}
    {% if fieldHandle and variable[fieldHandle] is defined %}
        {{ variable.title }}
    {% endif %}
{% endfor %}


Get different kind of entries relatedTo one asset (many to one)?

OK in fact it was very simple: criteria params accept arrays...

        $criteria = craft()->elements->getCriteria(ElementType::Entry);

        $fields = [
            'articleBody.efficyDocuments',
            'efficyDocuments'
        ];

        $criteria->relatedTo = array(
            'targetElement' => $asset->id,
            'field' => $fields,
        );


How to set url of delete button of editableTableField?

Because the table saves the inputs as JSON they are not individually deleted from the backend.

The way the table works is, when you click a delete button javascript removes those inputs for each cell from the form. When the user saves the form it saves the updated cells as JSON, if there are any.

However if you are saving each row individually then I would listen for the click of the delete button. When clicked, grab your id, then call your plugin action method for delete by using this:

Craft.postActionRequest('pluginname/controller/deleteMethod', {params:value}, function(data){
   "do stuff if needed…";
});


Why is the Craft without filter not working correctly and how to debug?

Try using |without based on arrays of user IDs, not entire UserModel objects. Behind the scenes, it's just using PHP's in_array method, which works much better on simple primitives like ints, strings, etc. instead of complex objects like Models (that has magic methods, other objects, primitives, etc.).  in_array probably doesn't know how deep of a comparison to make on those objects.


How to use localized categories properly?

To answer my own question see below:

As carlcs pointed out correctly the problem actually isn't located in getting the category - which works just well and is the right way to do it - but in how the relation to the entries is done.

I should check if the tag (coming from the url) actually resolves to a "real" category, otherwise just all entries will be shown.
just handling over the category to the .relatedTo method on craft.entries won't do it because that just fetches all entries related to this category irrespective to its locale - sourceLocale: craft.locale needs to be set.
Still not finished; because we want to "find elements related to the given element, where the given element is the target of the relation" – target in this sense is the category – we need to define it as tagetElement in the relatedTo method.

...

Getting the entries should now look like this:

{% if categories|length %}
    {% set entries =
              craft.entries.section('projects').relatedTo({
                 targetElement: categories,
                 sourceLocale: craft.locale
              })
    %}
    {% for entry in entries %}
    ...
    {% endfor %}
{% endif %}

...

And the actual title of my question should be "How to do category relations with locales" ;)


This should get it sorted.  There were 2 issues with yours.  First is you were using the wrong 'and' syntax in the craft.entries call and second you need to use the Y-m-d pattern so MySQL understands to convert it a proper DateTime field instead of the m/d/Y format you had.

{% set currMonth = now|date('m') %}
{% set currMonthFirst = now|date('Y') ~ '-' ~ currMonth ~ '-1'  %}
{% set nextMonthFirst = currMonthFirst|date_modify('+1 month') %}

{{ currMonthFirst|date('Y-m-d') }} - {{ nextMonthFirst|date('Y-m-d') }}

{% set events = craft.entries.section('events').event_startDateTime('and', '>= ' ~ currMonthFirst|date('Y-m-d'), '< ' ~ nextMonthFirst|date('Y-m-d')) %}

{% for event in events %}

{{event.title}}

{% endfor %}

Completely untested, but try using:

{% set events = craft.entries.section('events').event_startDateTime('and', '>= ' ~ currMonthFirst|date('m/d/Y'), '< ' ~ nextMonthFirst|date('m/d/Y')) %}


Is there an easy way to create Craft plugins that will call my existing Yii controllers?

There might be a way, but I'm not sure how easy it'd be.

I think it'd be a more guaranteed easy path if you were to take your existing Yii controllers and turn them into Craft plugin controllers, but I'm not sure of the extent and complexity of your existing application.


Management of large number of downloadable PDFs

I'm not familiar with Docman (or Joomla for that matter), but I think Craft is perfectly capable of doing what you're describing.

Your strategy of creating an entry per PDF seems reasonable.  Entries get custom fields (of course) and revisions and you can use Entry Types to display them in the various formats that you require.


I'm guessing that 'submission.entry' is not really the same as entry id. If you are using the connections method with Freeform then the data is stored as json against the form id. I think we need more info about how this bit works: "the ID of a specific entry that the Email is associated to"


How can I force a download of entry data to an excel file?

Craft's HttpRequestService has a sendFile method (available via craft()->request->sendFile()).

The 3rd parameter is an optional $options array that accepts key => value pairs.  One of those is 'forceDownload' => true and when that is passed in, Craft will set the proper HTTP headers to force the given file to be sent to the browser as a download.

You could do this from inside an action in one of your plugin's controllers.  Something like:

public function actionDownloadFile()
{
    // Grab your file content from wherever you have it stored. Here, it's just hard coded into a string.
    $contents = 'row1column1,row2column2'.PHP_EOL.'row2column1,row2column2'.PHP_EOL;

    // Call sendFile, giving it the name of the file to send, the contents and tell it to force a download to the browser.
    craft()->request->sendFile('filename.csv', $contents, array('forceDownload' => true));
}


How to check if a user's new email has been verified

This might not be what you are looking for, but one way to approach the problem:

You are able to set the STMP, IMAP credentials for the email service that Craft uses. Maybe use a service that has read receipts and use that to see if the new user has checked the confirmation email?


Display freeform entries with a status on open – on the front end

Have you tried the syntax for one status rather than an array?

{% set submissions = craft.freeform.submissions({
      form: formHandle,
      status: "open",
}) %}

Ref: http://docs.solspace.com/craft/freeform/v2/template-functions/freeform.submissions.html#param-status


Something like the following should work:

// elementapi.php
return [
    'endpoints' => [
        'assets.json' => [
            'paginate' => false,
            'elementType' => ElementType::Asset,
            'criteria' => [
                'limit' => null,
            ],
            'transformer' => function(AssetFileModel $asset) {
                // Set `generateTransformsBeforePageLoad` to `true` to have Craft generate transforms at runtime
                craft()->config->set('generateTransformsBeforePageLoad', true);
                return [
                    'title' => $asset->title,
                    'url' => $asset->url,
                    'thumb' => $asset->getUrl(['width' => 100, 'height' => 100]),
                ];
            },
       ],
    ]
];

One small gotcha: By default, Element API will paginate results. To avoid that, you can add a 'paginate' => false, parameter to your endpoint.

Another small gotcha: If you want to return transformed Assets (e.g. a thumbnail version), you can pass a named or inline (array) transform to $asset->getUrl(), but you'll need to set the generateTransformsBeforePageLoad config setting to true at runtime in order to have Craft actually generate the transforms when the endpoint is requested.

Finally: Depending on the number of Assets and Entries, you might see some performance issues with this method (especially if you're going to include transforms and don't paginate the results), so it'll probably be a good idea to cache the assets.json output in some way.


How do I save a front-end form as a specific Entry Type?

This has been solved via a support ticket, which I'm posting here for others etc.

  The first time you load the template, the URI is mapping to your "Get
  A Quote" entry, which gets assigned to the entry variable when your
  template is loaded.

  When you submit the form, the same URL is requested again, once again
  matching your "Get A Quote" entry, but this time the
  guestEntries/saveEntry controller action is summoned. When there's a
  validation error, Guest Entries will pass the new entry back to the
  template as an entry variable, overriding the "Get A Quote" entry that
  the URL matched. So, then the template gets routed to
  hire-us/index.html like it normally did, but this time entry.type is
  enquiryWeddingDance instead of getAQuote, since it's a different entry
  altogether. The template tries to include
  hire-us/enquiryWeddingDance.html, but that doesn't exist, so you get
  the error.

  To fix this, I've just released an update to the Guest Entries plugin,
  which adds a new entryVariable config setting. You can use that to
  customize the variable name that Guest Entries will set the invalid
  entry to (i.e. 'guestEntry' or 'invalidEntry'), so it doesn't conflict
  with the entry variable that the request is getting routed to.

After setting the Guest Entries variable as suggested in the documentation, it's now working as expected without conflicts. Thanks Brandon!

Usage:

{% if guestEntry is defined %}{{ errorList(guestEntry.getErrors('variableName')) }}{% endif %}


I ended up finding this code snipped, which worked for me:

https://gist.github.com/zackspear/7cdd656f9bb34e210676


Empty .getParam() does not return an array with dump()

The behaviour you're seeing is by design – craft.request.getQuery() will return all GET variables if it's called without arguments, whereas craft.request.getParam() requires the name argument – i.e. craft.request.getParam('foo').

The changelog notes for build 1.3.2465 does reference a couple of issues related to these methods, but nothing suggesting any changes in regards to the required name argument for getParam(). Unfortunately, the GitHub repo for Craft builds doesn't go back as far as 1.3.2465, so I'm unable to verify this though.


Is it possible to have Craft send an email on page load?

I would think you would want to instead set up a controller action, as URLs route directly to them, rather than use the overhead of a page.

Your cron job could hit the corresponding Controller Action URL (i.e., http://mysite.com/actions/myplugin/entriescreated/weekly), and run your job like that. Note, where you're accessing an action via cron you would have to set it to allow anonymous access to the action.

http://buildwithcraft.com/docs/plugins/controllers


Has anybody built a plugin or API integration with Xero or Cin7?

I don't believe so. The complete list of known plugins can be found here:

  https://straightupcraft.com/craft-plugins


Craft 2 new locale and dealing with root-relative links

Try using {{ url('/page_a') }}, this should generate the correct url.


How I am supposed to send product data to stripe for web hooks?

If this is Commerce 2, you're probably looking for the buildGatewayRequest event. From the transaction property set on that event, you should be able to get the Order and all the products.


How can I get the parent author from sprout forms to send to sprout mail?

This can be done using an Invisible Field and the addFieldVariables tag.  Define the value you want as your email in your template:

{% do craft.sproutForms.addFieldVariables({
    'secretEmailAddress': entry.author.email
}) %}

Set the Invisible Field to target that value:

{secretEmailAddress}

And then customize the Notification Email Recipients field to target the handle of the Invisible Field:

{invisibleFieldHandle}

Another example of doing this dynamically from an Entry with a Form Relations field has been posted in response to another question here: https://craftcms.stackexchange.com/a/29553/115


How to check whether a named Asset Transform exists?

You can check for the existence of a transform within your controller (for example), as follows:

 if (craft()->assetTransforms->getTransformByHandle('jimbob')) {
      // Transform exists.
 } else {
      // Transform does not exist (null is returned).
 }

Unfortunately, there doesn't seem to be an equivalent service (such as craft.assetTransforms) for use within templates.

Stephen


Best practices for plugin service/controller/etc file names

At the end of the day, it all comes down to personal preference. Depending on how large and/or complex each of your Service files is, it may make sense to break them up into separate files. Or if you've got less than a dozen service methods total, you could easily combine them into a single service file (if you choose).

For me personally, I try to break it up by where those service methods are being called from. MyPlugin_VariableService and MyPlugin_ControllerService for example... and any methods that are shared would go in the "main" MyPluginService file.

But every developer (and project) is different. You may have some other method of organizing that's better suited to you. So mostly personal preference.

However, the one thing I would definitely suggest... If you build any service methods which you'd like to be triggered from other plugins, then you may want to put those in your main service file. So the other plugins could simply call it like this:

craft->myPlugin->myMethod();

As far as an API for your plugin goes, it's much cleaner. Similarly, for any Controller actions which submit through a front-end form, you may want to have those submit through the "main" controller:

<input type="hidden" name="action" value="myPlugin/myAction">

Lastly, the same thinking applies to your main Variable file:

{{ craft.myPlugin.myVariable }}

Just makes for a cleaner interface for end-users and other devs. :)


Craig, I really don't know much directly about this, but it occurred to me to look at the ConsoleApp, which is used in one normal way to run Craft headless (from yiic on command line). It's in app/etc/console/ConsoleApp.php.

A little hunting around with PhpStorm, excellent for this sort of thing as others, turns up that ConsoleApp is loading plugins, and I think it will be loading things like Assets through the loadEditionComponents call -- edition checks out to mean Craft Edition, as Personal, Client, Pro, etc. by your license -- so that S3 might be available for Assets, and so forth.

Just what you would need to do, haven't time to go further on. You might find just calling ConsoleApp->run() would do, or may have to make a modified version of ConsoleApp, but seems it might make a good scaffold in that case.

Good fortune on this; interested to know what you work out.


How to disable plugin when unable to log in?

You can disable plugins by adding their handles to an array disabledPlugins in your config/general.php file:

<?php
    '*' => [
        'isSystemLive' => true,
        'disabledPlugins' => [
            'redactor',
            'some-plugin',
            ...
        ],
        ...
    ],


"Call to undefined method Calendar\Library\Carbon::setWeekStartsAt()" Solspace Calendar

The issue has to do with another third party plugin (Postmaster) installed and also using Carbon. The Postmaster plugin appears to be using an older copy of Carbon and Calendar is loading Postmaster's Carbon library, causing issues.

Manually updating the vendors directory to use latest versions may resolve this issue. We will try to reach out to the developer of Postmaster and see if they can resolve this on their end. :)

Customers effected with this issue can contact Solspace support for an updated vendors folder for Postmaster that may resolve the issue.


Dynamic subject for form notification email

Yes.  You can use the value of your custom field subject in two ways:

Shorthand Syntax:

{subject}

Object Syntax

{{ object.subject }}

If you want to perform any conditional logic, you will need to use object syntax for the conditional logic:

{% if object.subject != '' %}{{ object.subject }}{% else %}Fallback{% endif %}


Modelling flexible content sections and recommendations

I'm not familiar with ACF, but if you're looking for blocks-within-blocks, you could use the Neo plugin/fieldType. It allows you to define blocks, and then have nested blocks. It allows for decent management of blocks, too, so that you have children of specific parents.

For example:
You could have the following blocks/content types:

Copy
Card
Image slider
Form
Ad Unit
Related Content

And then the following layouts and components:

Two-column
Three-column
Single column w/ Sidebar
Column
Sidebar

The Neo fieldType would allow you to make block groups, and then allow the content blocks to be limited to certain layout blocks. It would look like this (demo only, not fully configured):

The layouts are selectable at the top level. You need these to target template files (or at least it makes it easier, IMHO).

The layouts can only have columns or sidebars. The two- and three-column only have columns, while the single has column and sidebar.

  Note: Currently blocks are only limited on the page level and not the block level, meaning if you set the max number of columns to 1, you'll only be allowed one column per entry.

The column block has the main content types, while the sidebar block has the sidebar content types.


SQLSTATE[23000]: Column 'targetId' cannot be null

I've managed to fix the issue. Originally I was converting the Blob to a File, but this was causing the upload to silently fail. So, when Craft tried to create the relation between the asset field and the image, it threw the error above.

Now, instead of converting to a file, I'm leaving the Blob as is but adding additional metadata (Last modified data & name), and passing a file name to the FormData.append() when creating the FormData object.


Need help: Multiple Listing channels with one template. DRY

A good option here is to make use of craft.request. As long as the URL is the section handle, you can do something like this:

{% current_section = craft.request.firstSegment %}

{% for entry in craft.entries.section(current_section).limit(20).find() %}
...
{% endfor %}

If the url is mysite.com/news, firstSegment will return 'news', which you can use in your craft.entries call.

UPDATE:

If your URLs need to be different than the section handles, make use of Twig's include with tag. For each section, you will need an index.html template with the following:

{% set current_section = 'thisSectionHanle' %}
{% include listPage.html with current_section %}

listPage.html can be the template that has the actual fetch and display logic. Using include with, listPage.html will have access to the current_section variable.

So not perfectly dry, but the main logic chunk will not have to be repeated.


Craft is unable to transfer your license to this domain at this time

With the launch of Craft ID, you can no longer transfer a license to a new domain directly from a Craft installation.  You can create a Craft ID account and from there, you can manage all of your Craft licenses, orders and download order receipts for previous orders.

This will also allow you to transfer the licenses that you own to other domains.


What are Search Targets and Search Query Input in seomatic?

This has to do with Google Structured Data and how your site appears in search results. If you use these fields, your site will show a custom search box in Google Search results, like this:

Basically, the Search Target is a URL where you'd want any search queries to get directed to. So in the example above for Pinterest and a custom search for "Pizza", the Search Target might be:

pinterest.com/search?q={search_term_string}

The Search Query Input basically just tells Google what the placeholder is that you used in the Search Target. So in our example it would be:

search_term_string

I'd recommend reading this
page from the Google Search docs in order to better understand what Search Targets and the Search Query Input are.


Include with -- variable does not exist error

You're probably looking for:

{% include "singlepage" with { 'currentPage': 'leaders' } %}

The key (the part before the :) needs to be a string, hence in quotes.

The relevant Twig template docs are here: https://twig.symfony.com/doc/2.x/tags/include.html#include


Redirect on front end Password Redirect not working

This issue is caused by the presence of the {% requireLogin %} tag in one of your Craft templates. Remove the tag from the template in question, and the redirect should work as expected.

Craft Docs: https://craftcms.com/docs/templating/requirelogin


Within your variables class file you will want to define methods that 'return' values to your template, like so:

class HelloVariable
{
    public function message()
    {
        return "Hello, world!";
    }
}

Which you would call from your template using:

{{ craft.hello.message }}

On a side note, a really good place to start plugin development is to download and install a plugin template such as BusinessLogic, which provides a basic plugin structure, some sample files, and includes inline documentation for basic business logic kind of functionality.


Feedme import formatting into Refactor from JSON

So thanks to @Dajo on the Craft Discord channel for any other folk out there experiencing similar turns out there was a config set-up for the site wasn't aware of that had set the dataDelimiter parameter to  , which was exploding the HTML content into an array.
Changing this has sorted the problem!


get post data after submitting User Profile Form for success message

Not possible – any input values added to your profile editing form (such as test in your case) will be included in the POST request to the users/saveUser controller action, but they won't actually be included in the redirect request back to the page (or to whatever URL is in your form's hidden redirect input).

As a workaround you can always check for the Flash notice that the UsersController sets after the user is successfully saved:

{% if craft.session.getFlash('notice') == 'User saved.'|t %}

Success message!

{% endif %}


Check paginated currentPage before setting the paginate tag

Ok, so after discovering the getPageNum request, I found the following solution:

{% set pageNumber = craft.request.getPageNum %}
{% set firstPageLimit = 5 %}
{% set defaultLimit = 8 %}
{% set limit = pageNumber == 1 ? firstPageLimit : defaultLimit %}
{% set offset = pageNumber == 1 ? 0 : firstPageLimit - defaultLimit %}
{% paginate craft.entries.section('news').limit(limit).offset(offset) as articles %}


When a task actually fails (as opposed to getting stuck), Craft will log an error message explaining why. To fish it up, open craft/storage/runtime/logs/craft.log, and search for:

Encountered an error running task

Each time the task runner encounters an error, its log message will begin with that, followed by the task’s ID, its type, which step it was on (if applicable), and the error message the actual task returned.

If you’re not seeing it, check craft.log.1, craft.log.2, etc.


You could build it up using a couple of the request variables:

{{ craft.request.serverName ~'/'~ craft.request.getSegments | join('/') }}


There's a whole slew of PHP constants you can define in each public index.php file to separate out the templates, config settings, etc. for each of the sites.

It's a very similar method we use for https://craftcms.com, too (just based on subdomains instead of subfolders.


Check if entry has a descendant with a certain field enabled

Wow - thanks for listening ;-)

I solved it like this:

{# loop through continents #}
{% for entry in craft.entries.section('destinations').type('continent').find() %}
    {# only show links to continent pages if it has any travelguides #}
    {% if entry.hasDescendants() %}
        {% set continentID = entry.id %}
        {% if entry.howLongWillYouBeGoing == 'mediumStay' in craft.entries.section('destinations').descendantOf(continentID) %}
            {# if subpage is marked as mediumstay, show a link to it #}

{{ entry.title }}

        {% else %}
            {# if it's not a mediumStay, just show the text #}

{{ entry.title }}

        {% endif %}
    {% else %}

{{ entry.title }}

    {% endif %}
{% endfor %}


Create a Single called Sign Up with a URI (section > settings) of academy/sign-up while keeping your current template academy/sign-up.html.


Can't include relative JS file from layout

It looks like this is all happening in Craft's template folder, where anything with an underscore—like your _layout directory and its contents—won't be accessible via URL.

You'll definitely want to adjust your project layout to keep Craft's templates together in /craft/templates, and any front-end resources (like your videojs.thumbnails.js, thumbnails.png, etc.) in the /public folder.

The Routing documentation fully explains what Craft does with any front-end URL it gets—it's a tad intense but should fully explain what happens with a request.


Forcing creation of all transformations for all assets

Author of the ImageOptimize plugin... when you say no luck with that either, what is going wrong? Once you install ImageOptimize, and add an Optimized Images field type to your asset volumes, it will create all of those responsive image transform for you.

Check out the Using the Optimized Images Field section of the documentation.

It can't just create all of your image transforms for you, because unlike EE, you can create transforms via your frontend Twig templates as well, and there's no real way it can know what is being created there, or all of the possible permutations.


Based on your controller's class name, I believe you need to POST to this endpoint...

/actions/googleMap/map/getLocations


Passing multiple parameters to the Element API

You can fetch GET parameters using HttpRequestService::getQuery() or getRequiredQuery():

'entries-by-category' => function() {
    $categoryIds = craft()->request->getRequiredQuery('categoryIds');

    return [
        'elementType' => 'Entry',
        'criteria' => [
            'relatedTo' => ['targetElement' => $categoryIds],
        ],
        // ...
    ];
},


How to do CSS/JS bundles/minifying in Craft 3

Craft doesn't output any code unless you write it, so you have complete freedom to use any standard front end build process and include the built files in your templates. There are a few plugins that help with this depending on build process though, such as:

https://plugins.craftcms.com/mix
https://plugins.craftcms.com/twigpack
https://plugins.craftcms.com/minify
https://plugins.craftcms.com/assetrev


Get radio button's value from a form by PHP

I have solved it by myself;

$application = $event->sender->application;

Even for radio button's value, no suffix is necessary like value.


Trouble with submitting Contact Form plugin contact via AJAX

This is your html

<div id="my-form" class="form">

And This is your js event handler

$('#my-form').submit(function(ev) {

So $(this) is actually a <div> container element and $(this).serialize() is null so you'll send no data. You should add a id to your form

<form method="post" action="" id="myForm" accept-charset="UTF-8">

and send the form data instead of a div data.

var data = $("#myForm").serialize();

I reproduced it, and it worked - even though I would prefer sending an actual object instead of a serialized form, but that's only subjective


Add a form field into the details bar on the entry edit screen and do something with the value

Just take your value direct from the $_POST array.


i don't think it is possible via GUI but you can do this via feed me events and a simple plugin.

because entrytype's fieldlayout and field mappings are different, in my solution, you should edit feed and update fieldmapping for each entry type, change the if condition of the code and run the feed again.

    Event::on(Process::class, Process::EVENT_STEP_BEFORE_ELEMENT_SAVE, function (FeedProcessEvent $event) {
        $entryTypeId=$event->feedData['entrytype'];
        if ($entryTypeId==1){
            $event->element->typeId=1;
        }
        //maybe, if field mapping for entrytype1 and entrytype2 are same
        elseif ($entryTypeId==2){
            $event->element->typeId=2;
        }
        else {
            //skip saving element for other entry types because they have different field mapping.
            $event->isValid=false;
        }
    });

about event->isValid


You can create a custom validation at the EVENT_BEFORE_SAVE event

Event::on(Entry::class,
    Entry::EVENT_BEFORE_SAVE,
    function(ModelEvent $event){
        /** @var Entry $entry */
        $entry = $event->sender;
        // you can check for the section and the type

        $model = DynamicModel::validateData(['title' => $entry->title], [
            [['title'], 'string', 'max' => 2, 'message'=>'{attribute} should not be longer than 2 characters']
        ]);
        if($model->hasErrors()){
            $entry->addErrors($model->getErrors());
            $event->isValid = false;
        }
});

You can leave remove the message attribute if you don't want to use a custom error message, I just wanted to provide a full example how to validate data in Yii2. That way you can define whatever rule you want


Error when Attempting to Install Plugins

I don't really know what is causing this error but I've got the same problem for plugins install and update. To avoid this annoying error page, I prefer to install/update plugins via composer.

composer update

or

composer require {plugin name}


There is craftimport which is an 'unsupported' starting point for importing entries from an XML source.

https://github.com/clearbold/craftimport

There is also Import:

https://github.com/boboldehampsink/import

which can import from CSV sources.

Check out http://straightupcraft.com/craft-plugins for a list of current Craft plugins.


Global templates are absolutely possible by taking advantage of the Twig {% extends %} tag. You can read more about template inheritance in Twig's documentation.

If you set up multiple sections, you can assign certain users edit privileges to their appropriate sections.

You can set up your navs and footers as Globals (or use a plugin), you can set editing privileges just to admins. Simply create a header and footer partial template and include them in a main template file that your other templates extend.


Loading assets cross-domain with SSL or non-SSL option

You could try something like '@assetBaseUrl' => $_SERVER['HTTPS'] ? 'https://site1.domain.org/files' : 'http://site1.domain.org/files' which checks for a secure request.


Simple way to use craft for databaseless prototypes

Using Craft without a database isn't possible, you're probably best off doing things the way you are now (with a minimal Craft install).

At its core, Craft is built on two very powerful frameworks:

Twig
Yii

(There are other components as well, but these are the driving forces.)

You can, of course, just use Twig as a templating language for your prototyping. But that's all you'll have... a templating language.

You can't use Yii without a database, since the primary purpose of Yii is to act as a DAO (Data Access Object). Without a database, it's kinda useless.

My official recommendation: Create a "base installation" repo with a generic website, and have Craft completely installed. Then you can quickly clone that and work your prototyping magic!


Redactor source plugin working on Text field but not on a Text field in Matrix

in german settings look carefully at the Redactor-Konfiguration , if you select Standardwert it uses Simple.json and not Standard.json.


Problem getting relationship between entries to work

I recommend doing it like so:

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

{% set catSlug = craft.request.segment(3) %}

{% if catSlug %}
    {% set cat = craft.entries.section('apprenticeships').slug(catSlug).first() %}

    {% if cat %}
        {% set vacancies = vacancies.relatedTo(cat) %}
    {% endif %}
{% endif %}

This sets up an ElementCriteriaModel for all your Vacancies entries (don't use the find() method yet!).
Then checks for the first entry from the Apprenticeships section with a slug of your URL segment.
If there's really such an entry, it further extends the ElementCriteriaModel with a relatedTo parameter.


If you have gzip compression enabled (either at the PHP or Apache level), try disabling that and see if helps.  Obviously that's not a proper long-term solution, but if you leave it on and set the runTasksAutomatically config setting to false and setup a cron job as described in the docs, you can see if that helps as well.


Override permissions for Craft Commerce saveProduct controller

You'll have to write a custom plugin and point your frontend form to save to its own controller action that allows anonymous access.

That action can either 1) duplicate Commerce's saveProduct method, which can be brittle if it changes or 2) start a session from a generic user account that has the proper permissions and forward the request onto Commerce's saveProduct method.


Is cache condition necessary to stop HTML being inserted into database cache?

No, there is a better way to do this. Set the enableTemplateCaching config value to false.

'enableTemplateCaching' => false,

With that setting disabled, all caching will be skipped.

// Won't be cached
{% cache for 1 hour %}


Render markdown as GFM (GitHub Flavored Markdown), therefore preserving line breaks?

I was able to get good results using {{ block.myFieldName|nl2br|markdown }}


The hosting company says the only error they see is "image missing" and the DB connection is fine.

That seems suspicious to me.  Assuming the 503 Service Unavailable status code is initiated in Craft, it will do that in two common occurrences for front-end requests.  One is when Craft is in the middle of being updated, and the other is when it is having problems connecting to the database.

A look through the Craft logs as well as your web server access logs should help verify this.


Licence error and update issue cause of same plugin name / handle

You're not gonna like this answer, but... rename your plugin. There's no way to reasonably circumvent all of the conflicts you're going to run into by keeping the same name as an existing public plugin.
If it's a private plugin that you're only using on a single site, consider converting it into a module instead.


When defining your siteUrl, you can do:

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


craft()->urlManager->setRouteVariables() loads the correct template but does not pass in the variables

My solution was to load the template directly rather than routing to the controller first.  Essentially, in my registerSiteRoutes() function I replaced this:

"payment" => ['action' => 'someController/doPayment']

with

"payment" => 'templateDir/core/payment'

I didn't even realize you could do this in registerSiteRoutes()!


How do I create a link to an entry using entry's id?

The reason why your example fail is that you are using the entry variable. You are trying to call the function getUrl on the model entry, but the function (or model) doesn't exist yet, and has to be created (fetched).

Example:

You can use craft.entries to fetch the EntryModel, and than output its url:

{% set my_id = 5 %}
{% set entry = craft.entries.id(my_id).first() %}
{{ entry.url }}

If you are in an entry loop, it works the same way:

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


Is there a name for Craft 3's database model?

Craft uses a fairly typical relational model, where most1 custom fields have a single column in the content table, set to an appropriate column type chosen by the field type. Unlike EAV, which crams all data into a fixed schema, Craft’s schema will change over time based on the custom fields you’ve configured.
There are both performance and storage benefits to this. However there’s one significant downside, which is that it’s possible to hit row size limits if you have hundreds of custom fields (particularly with MySQL). We’re going to address that in Craft 4 by splitting the content table up into multiple tables – one per field layout.
1There are a couple exceptions: relational fields (like Entries) which store their data in the relations table, and fields that store nested elements such as Matrix and a couple third party field types, which create their own field-specific content-esque tables.


Limiting the Upload Location for assets in a Matrix Block

owner is the element which contains your Matrix field.

For example, if you attach a Matrix field to a Section, the owner would be the specific Entry in that Section.

{owner.slug} - The slug of your entry.
{owner.author.username} - The username of the person who created the entry.


Is it possible to POST to an action if the system is offline?

Completely untested, but something like this in your craft/config/general.php file should work:

return array(
   'isSystemOn' => (isset($_REQUEST['action']) && !$_REQUEST['action'] != 'mailchimpSubscribe/list/Subscribe'),
);


In Craft 2.5, how can you sort the entry index page by a custom field?

Currently, the only way to add custom fields to the sortable attributes is to write a custom plugin which makes use of the modifyEntrySortableAttributes hook, e.g.:

public function modifyEntrySortableAttributes(&$attributes)
{
    $attributes['yourCustomFieldHandle'] = Craft::t('Label');
    $attributes['anotherCustomField'] = Craft::t('Another label');
}

The modifyEntrySortableAttributes method would go into your plugin's primary class.

Apart from custom fields, it's also possible to add other attributes in this manner, such as authorId (to sort on author) or typeId (to sort on entry type).

It's also possible to remove a sortable attribute:

unset($attributes['postDate']);

There are corresponding hooks for adding sortable attributes to category, asset and user index tables, see the official docs for details.

One gotcha to note is that since the sortable attributes are source agnostic (i.e. they're the same across all sections), any custom field you add to the sortable attributes should ideally exist for all your entry types, as attempting to sort on a custom field that doesn't exist for the entries in the current index table will throw an error.

Moving into opinionated waters here, but to close: While the Customizable Element Indexes (CEI) is a great thing to have in core (and with a brilliant UI), I personally feel there's room for improvement; especially pertaining to sortable attributes. On that note, there are a few relevant feature requests:

http://feedback.craftcms.com/forums/285221-feature-requests/suggestions/7274973-add-a-source-parameter-to-modifyentrysortableattr
http://feedback.craftcms.com/forums/285221-feature-requests/suggestions/10943841-sortable-custom-columns
http://feedback.craftcms.com/forums/285221-feature-requests/suggestions/11533941-sort-filter-entries-by-entry-type
http://feedback.craftcms.com/forums/285221-feature-requests/suggestions/10579029-add-custom-fields-in-customizable-element-indexes

EDIT

I just published a new plugin which will add any (sortable) custom field or meta value in any given element index to the index' sortable attributes:   https://github.com/mmikkel/CpSortableCustomColumns-Craft
The plugin is source aware, so it should avoid the issue with sorting on non-existing fields (as described above) in most cases. Like most Control Panel-specific plugins, it's basically one big hack – but it works until we can have better sorting abilities in core. Hopefully it's useful to someone!


You can apply conditions within the same field but you can't create conditions for multiple fields.

Here are some great examples

$criteria->expiryDate = 'or, :empty:, =' . $yourDateValue;

However you can't combine conditions for multiple fields. So you can't say Where (fieldX = 4 OR FieldY = 5) you would have to create an sql object based on your ElementCriteriaModel and use Yii's great Query Builder for that and use the OrWhere function

$query = craft()->elements->buildElementsQuery($criteria);


Changed this to be :

{% set userBrands = craft.entries.section('brands').relatedTo(currentUser) %}
{% set fans = craft.users.relatedTo(userBrands) %}

{% for user in fans %}
    <li>{{ user.username }}
{%  endfor %}

{% endblock %}


Using cache tag on array outputs nothing

The {% cache %} tag is only designed to do one thing – to capture output (e.g. HTML) and store that output to the database, so that the next time Craft encounters that particular cache tag, it can serve up the cached output from the database, instead of having to run whatever code is contained inside the {% cache %} tag pair, on every pageload.

In your code, you're attempting to cache a variable (data). That won't work. Essentially, you're just feeding the {% cache %} tag empty output, and the code that actually sets the data variable will only run on the first pageload (or whenever the cache has been cleared out). On subsequent pageloads, Craft won't bother to actually run the code inside the {% cache %} tag, it'll simply print whatever output was stored for that particular cache (which, in this case, is empty). Hence your code breaking.

What you need to do, is to revise your caching strategy so that your business logic (i.e. the part of your code that pulls and operates on data – which is usually the expensive part, resource-wise) and the part that actually prints your data is contained within the same {% cache %} tag pair.

Here's a small example to illustrate good vs. bad use of the {% cache %} tag:

Bad

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

{% for entry in entries %}
    {{ entry.title }}

{% endfor %}

^ Ouch. The variable entries will only be set whenever the cache is empty; on subsequent pageloads, Craft will serve up an empty, cached string instead of actually running the craft.entries query and the for loop will fail because it'll operate on a variable that isn't set.

Good

{% cache %}

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

    {% for entry in entries %}
        {{ entry.title }}

    {% endfor %}

{% endcache %}

^ Awesome. The page will probably be served a bit faster because Craft doesn't have to pull the entries and compile the HTML for every pageload – it'll just spit out the output resulting from the code within the {% cache %} tag.


Sorted.

It was a .htaccess issue

One of my redirects had a typo in it

RewriteRule ^old-page$ /new-page [R=301,L#]

should be

RewriteRule ^old-page$ /new-page [R=301,L]


CraftCMS Push Notifications: New Device Token

I have finally figured this out with the help of the developer, boboldehampsink. Thank you so much for your help!

The post parameters are:

{
    'app': 'app_handle',
    'platform': 'ios/android',
    'registrationId': 'token'
}

Note:

You must use the front-end url to register a device without needing login credentials.

Post to the URL:
http://localhost/CraftCMS/public/actions/pushNotifications/devices/registerDevice

More information found here: https://github.com/boboldehampsink/pushnotifications/issues/1


I found out that, somehow, the files and the foldernames containing special characters where not well handled (In my case, a lot of é and è).

Removing the special characters, and adding 'convertFilenamesToAscii' => true to the general.php config file for future edition / creation / upload resolved this issue for me.


Filtering entires via tag field and checkbox field using a form

I'm not sure why your search is not working in this instance (though it might be because you're not executing the query, see my comment). But in general, fulltext search is way less precise, I would only do that if you need to support actual search terms. Since you're only filtering by categories and tags, I wouldn't search by category/tag titles, but instead use IDs to match the selected categories/tags directly. This will be way more precise, avoid edge-cases and will be much faster as well.
First you'll need to adjust your form so the select fields use IDs instead of titles as their value:
{# category filter #}
<option value="{{ option.id }}">{{ option.label }}</option>

{# tag filter #}
<option value="{{ tag.id }}">{{ tag.title }}</option>

Then adjust your query to query your blogcategory and tags field directly by ID:
{% set entries = craft.entries.section('blog') %}
{% set blogcategory =  craft.request.getQuery('blogcategory') %}
{% set tags =  craft.request.getQuery('tags') %}

{% if blogcategory %}
    {% do entries.blogcategory(blogcategory) %}
{% endif %}

{% if tags %}
    {% do entries.tags(tags) %}
{% endif %}

Finally, make sure to actually execute the query:
{% for entry in entries.all() %}
    {# output results #}
{% endfor %}


I think the best way to do this, is by creating a small Twig extension plugin that uses PHP's html parser to find the first occurrence of an IMG tag and return the src of that tag to your template. This is a step-by-step explanation of how to create your very own Twig filter.

You could then to this:

{{ entry.body | firstImageSrc }}

And it would return the url you need.

The easiest way, however, is to add an asset field to your Entry Type's field layout and choose a file manually.


ElementCriteriaModel combine with 'and' and 'or' filters

I suspect you're looking for this section on passing parameters to ElementCriteriaModels, in the docs.

The examples fail to highlight one aspect of the query you're building, but I think you'll find the same strategies hold up for many field values, as well as basic Element properties (like id, title, etc.)

For example…

craft.users({ myFieldA: [1, 2, 3] }).all()

…will fetch User Elements with the custom myFieldA matching the values 1, 2, or 3. The or is implicit!


How to reference the current entry via twig in the control panel?

As far as I know. The variable {{ entry }} is not available to custom field plugins through inheritance and must be explicitly set and returned as a variable in the getInputHtml method within the class definition file.

See this question for details on how to set this variable and things to be aware of.


Retrieve entry field value from a different locale?

You can just manually fetch the entry in the other locale.  Assuming you already have the first entry, something like:

{% set localeEntry = craft.entries.id(entry.id).locale(languageID1).first() %}

{% if localeEntry %}
    {{ localEntry.otherWordDefinition }}
{% endif %}


Blog/_entry breaking all assets globals like header & footer logos

If the entry is in a subdirectory, the image path will be incorrect. If the images are in a folder called "assets" in your home folder:
image.url for your main page would be "assets/imagename.jpg"
image.url for your entries in "blog" SHOULD be "../assets/imagename.jpg" BUT it will still return just "assets/imagename.jpg" instead of jumping up a directory to get the assets directory. Therefore, no image found at blog/assets/imagename.jpg.
Depending on your setup you might try img src="{{ siteUrl }}/{{ image.url }}". This will fetch the full site path to the image every time no matter what where it's called from.


Pagination is for breaking up a list of entries into different pages. p3 means page 3 of entries.

What you're looking for is the ability to link to the next/previous entry. If you are ordering your entries like a blog, by post date, newest first you can create the links like this. On your single entry template:

{% set nextEntry = craft.entries.section('posts')
    .postDate('>= ' ~ entry.postDate.timestamp)
    .order('postDate asc')
    .id('not ' ~ entry.id)
    .one() %}

{% if nextEntry %}
    Next Post
{% endif %}

{% set previousEntry = craft.entries.section('news')
     .postDate('<= ' ~ entry.postDate.timestamp)
     .order('postDate desc')
     .id('not ' ~ entry.id)
     .one() %}

{% if previousEntry %}
    Previous Post
{% endif %}

entry is the current entry you're viewing. If you're ordering the entries in a different way you can adjust the queries. This answer goes into more detail, including how to change this if you're ordering by title.

If you have your entries in a structure section you can do this:

{% if entry.getNextSibling() %}
    Previous Post
{% endif %}

{% if entry.getPrevSibling() %}
    Previous Post
{% endif %}


How to clear a third-party cache when Craft updates its own template caches

Can't think of any clever workarounds, but this is on our 2.2 list to add events so that 3rd party services can be notified when template caches get invalidated.


Is it possible to use a loop variable to target a specific field entry?

Turns out Twig has a nifty little attribute function that does the trick. Here's how it works:

{% for row in entry.table %}
   {% set foo = attribute(entry, 'fieldHandle' ~ loop.index) %}
{% endfor %}

Big hat tip to Mr. Brad Bell for posting the original answer in Stack Exchange.


How do I properly use Twig syntax in dynamic title/URL fields?

After chatting with The Honorable Brad Bell I learned that the sample tags in the field's label are showing some shorthand references to a few variables. (The {slug} reference for example.)

All I needed to do was use the object object to fully utilize twig tags/filters/etc. Here are a few ways to achieve what I was aiming for:

{% set num = (object.id * 1234567) | number_format(0, null, '-') %}documents/{{ num }}

or slightly more concise code:

documents/{{ (object.id * 1234567) | number_format(0, null, '-') }}

Also, thanks to carlsc for sharing the documentation on this feature. Reference: https://craftcms.com/docs/sections-and-entries#dynamic-entry-titles.

Happy Dynamic Titling and URLing.


How would I omit zero value decimals in a number format?

This can be done with Twig's trim filter. It works just like PHP's trim function.

{{ item.width|trim('0','right')|trim('.','right') }}


Updating index tables' sortable attributes on AJAX

The modifyEntrySortableAttributes technically gets called each time you load new elements on the index page, just so that the controller can confirm that the posted order attribute is valid. But the only time that your plugin can actually affect what is shown in the dropdown is the first time it’s called, on page load.

Maybe a better way to go about this would be to have your plugin return all the available options up front, and then simply hide/show them with JavaScript when the source changes.


Adding link type to Redactor Rich Editor

You could do this with a custom plugin that used the addRichTextLinkOptions to add extra options to that dropdown.

You can use https://pluginfactory.io to generate boilerplate plugin code to get you up and running quickly.


Is there a way to print the tax and discount percentages?

See my answer here for discount percentages:
How can I display the Discount Value onSale of Products

For tax, I think there answer is actually currently the same, I don't think you can currently retrieve tax rates in templates as such (you can get tax categories models, but not, it seems, the rate models.  So again, twig maths might be your best bet here.


Your question is just about entries without relationships but your code example is attempting to display both items with a relationship and without a relationship.  I think your example is making things a bit more complicated than this needs to be.  Rather than looping through both sections (databytes and databyteSeries), I believe you only need to loop through one section.  The databyteSeries section, as you've described it, has a relation field for databytes, so all the info you need to know about databytes should be available to you in the relation field.

Let me know if the following example gets at what you are going for.  It simplifies your loop to just the databyteSeries section, and then uses Twig's length filter to test the entry.relatedDatabytes field to see if it has any entries. If there are related databytes, it displays one output, and if there are not, it displays an alternative output.

I've also updated the method in which you were using to output the first item in the series.  Rather than loop through the entire entry.relatedDatabytes field and just output the first item using a loop.first conditional, I've updated the code to use entry.relatedDatabytes.first().  Using the first() method on an EntryModel will just grab the first item, and then you can output it as you wish with whatever variable you assign it to.  Below, I've assigned the first item to the firstInSeries variable.

{% paginate craft.entries
     .section('databyteSeries')
     .limit(6)
     as entries
%}

    {# Loop through databyteSeries entries #}
    {% for entry in entries %}

        {% if entry.relatedDatabytes|length %}

            {# Display the first item in a Databyte Series that has a relationship #}
            {% set firstInSeries = entry.relatedDatabytes.first() %}
        {{ firstInSeries.title }}

      {% else %}

        {# Display the Databyte Series name that has no relationships #}
        {{ entry.title }}

      {% endif %}

    {% endfor %}

{% endpaginate %}

UPDATE

Based on your clarification in the comments and your potential solution, here's another method to consider using Craft's without filter:

{# Get all databyteSeries and databytes #}
{% set databyteSeries = craft.entries.section('databyteSeries').limit(null) %}
{% set databytes = craft.entries.section('databytes').limit(null).indexBy('id') %}

{# Determine which databytes already have a relationship to a databyteSeries #}
{% set alreadyUsedDatabytes = craft.entries.section('databytes').relatedTo(databyteSeries).indexBy('id') %}

{# Use the without filter to remove all 'alreadyUsedDatabytes' from the complete 'databytes' result, so you are left with only 'unusedDatabytes'  #}
{% set unusedDatabytes = databytes|without(alreadyUsedDatabytes) %}

{# Output the unusedDatabytes #}

{% for entry in unusedDatabytes %}

{{ entry.title }}

{% endfor %}

I have not tested this code so let me know if you run into any issues to troubleshoot.


How to create a template file for Categories?

When you create a category you will need to tell craft which template to load:

So for your example you would put categories/index in there and you should find the template gets loaded when you visit the category url.

See more about templating in the docs


Not sure about specific integrations with Craft per se, but one way to achieve this fairly quickly is to integrate with SCORM Cloud's API. It is a SaaS offering that can be leveraged to add SCORM capability to just about any site, LMS, CMS, etc. Integrations with Moodle, WordPress, etc. already exist. See https://scorm.com/scorm-solved/scorm-cloud-features/


Transitioning local Craft site to AWS EC2

Figured out the issue. I had one character off in my MySQL database name versus what I was telling craft it was called in the db.php file which is why it was failing to access it. User error prevails again!


Craft has a pretty solid engine for relational queries, so unless what you want to do is totally outside the box, there's a good chance you can accomplish what you want by using the relatedTo parameter available to the ElementCriteriaModel. Note that the relatedTo entry in the docs pertain to templates and not plugin development per se, but aside from the syntax the concept and approach will be identical in PHP.

Here are some examples, since its not obvious to me exactly what you hope to achieve:

To pull entries related to a certain category:

$criteria = craft()->elements->getCriteria(ElementType::Entry, [
    'section' => 'affiliates',
    'limit' => null,
    'relatedTo' => [
        'element' => $category, // Instance of CategoryModel, or a category ID
    ],
]);

To pull entries related to multiple categories:

...
'relatedTo' => [
    'element' => $categories, // Array of CategoryModels or category IDs
],
...

To pull entries related to a category, where the relation is made in a certain Categories field:

...
'relatedTo' => [
    'element' => $category,
    'field' => 'someCategoriesFieldHandle',
],
...

To pull entries related to a category, where the relation is made in a certain Categories field on the EntryModel:

...
'relatedTo' => [
    'targetElement' => $category,
    'field' => 'someCategoriesField',
],
...

To pull entries related to a category, where the relation is made in a certain Entries field on the CategoryModel:

...
'relatedTo' => [
    'sourceElement' => $category,
    'field' => 'someEntriesField',
],
...

To pull entries with multiple possible relations, where any of the relational parameters can be met:

...
'relatedTo' => ['or', [
    'targetElement' => $categories,
    'field' => 'someCategoriesField',
], [
    'targetElement' => $someOtherCategories,
    'field' => 'someOtherCategoriesField',
]],
...

To pull entries with multiple possible relations, where all of the relational parameters must be met:

...
'relatedTo' => ['and', [
    'targetElement' => $categories,
    'field' => 'someCategoriesField',
], [
    'targetElement' => $someOtherCategories,
    'field' => 'someOtherCategoriesField',
]],
...

If you edit your question to include exactly what you want to do, I might be able to give you more specific advice or examples.


It seems /login is a reserved route - is that correct?

That is set by the loginPath config setting so yes, you can change it in your craft/config/general.php file.

There are a few other configurable URLs for templates and redirects, all of which are described on that page.


How to search based on a Multi select category field in Craft 3?

For filtering entries based on relationships (categories/assets/users/tags/other entries), you need to use the relatedTo parameter, not the search parameter.

Here's an example: Filter based Search Form


"... why does it work on the original website, but not here?"

Undefined index is a notice level PHP error. Which means it's barely important, and can generally be ignored.

This is probably a result of either:

Your PHP error level settings are more strict on this machine, and/or
Craft is in devMode on this machine.