The Craft 3 multi-sites is very useful. However, I found the list dropdown while editing an entry confusing and awkward in my case.

I have several sites group, each containing a localized version of the site version:

- International Sales
    - English version
- Production
    - English version
    - French version
— Distribution
    - English version
    - French version

I could have set the sites group like this, to get the right display name when looping on each sites (using craft.app.sites.getAllSites()):

- International Sales
    - International Sales
- Production
    - Production
    - Production
— Distribution
    - French Distribution
    - Distribution France

But as you can see, there's almost nothing that inform the user which site version is using which locale, when editing the sites from the CP's dropdown.

So I had to change each name by something like this:

- International Sales
    - International Sales → English
- Production
    - Production → English
    - Production → French
— Distribution
    - Distribution France → English
    - Distribution France → French

Sites Dropdown when editing an Entry

Now I'm facing two problems:

  • How can I set an ordered list of all sites using Twig? Because craft.app.sites.getAllSites() loop through sites using an alphabetical order, like in the CP. For example, I would like the Distribution group displayed before the Production group.

  • How can I set a display name different from the site name? Because International Sales → English, Production → English, etc. are ugly names, only for visual reference in the CP. I would like to display their names like in the second version of the list: International Sales, French Distribution, etc.

  • For both questions, are they in the context of the Control Panel or on the front-end of the site? – Brad Bell Jan 10 at 18:56
  • Both questions are in context of the front-end. – Romain Poirier Jan 11 at 8:41
up vote 2 down vote accepted

If you would use a custom plugin you can create this function in your (I know it's deprecated but I don't know a better name) PluginVariable

public function createSiteQuery(): Query
{
    return (new Query())
        ->select(['id', 'groupId', 'name', 'handle', 'language', 'primary', 'hasUrls', 'baseUrl', 'sortOrder'])
        ->from(['{{%sites}}']);
}

You can then use

{% set sites = craft.plugin-handle.createSiteQuery().orderby({'whatever': 'you want'}).all() %}

And attach as many parameters to the query as you like... If you would like to fetch only sites with a specific language you can do

{% set sites = craft.plugin-handle.createSiteQuery().where('language = "en"').all() %}

You have the full power of Yii2 Query class. You can group your sites as you like, change the order. You'll receive a single SiteRecord or multiple SiteRecords Class reference and you can display whatever information you like in the frontend.

You are free to change the site names in your frontend with a static array map in your php code as well. Create a map with siteHandle => "new display name" and do something like

{{ craft.plugin-handle.displayCustomSiteName(site.handle) }}
  • Thank you! I was able to create the plugin using pluginfactory.io, and following this tuto: nystudio107.com/blog/so-you-wanna-make-a-craft-3-plugin. However, I get this error while using the Twig query: Class 'vendorname\pluginname\variables\Query' not found. How should I add this Class? Regarding the ordered list, do you have any tips to set this order in the CP? Like we would set the order of a Structure. – Romain Poirier Jan 12 at 10:48
  • Of course you have to include the Query class. If you have a good IDE it's done automatically otherwise you have to include use craft\db\Query; at the beginning of your file. As of now I can't think of a clean (performance wise) good way to change the order in the cp. for your sites. There is no official hook for the internal site query right now. The CP backend list is just ordered by name – Robin Schambach Jan 12 at 13:15
  • Thank you! I'm new to plugin development, also to Craft 3. Please update your example: {% set sites = craft.sitesList.createSiteQuery().where(['=', 'language', 'en']).all() %} is working fine (instead of .where(['language = en'])) – Romain Poirier Jan 12 at 13:55
  • Yii2 is really flexible when it comes to parameters. You can include an array or a single statement in the where() function. Both statements work, but I had a twig syntax error in the example above. You can see a full list of all examples what parameters to add here yiiframework.com/doc-2.0/guide-db-query-builder.html#where – Robin Schambach Jan 12 at 14:11
  • 1
    .where('language = "en"') or .where({'language': 'en'}) or .where(['language = "en"']) don't mix these. It's so much easier in php in my opinion... that's one reason why I don't understand why so many people stick to twig. Syntax errors are sometimes incredible hard to see – Robin Schambach Jan 12 at 15:41

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.