Winter CMS resources and help articles

Simple and to the point. Optimized by the community.

Add all pages to a backend dropdown field (CMS pages, StaticPages and other plugins like a blog) with translations

2
by AIC BV, last modified on September 14th, 2022

It might not be perfect for your case and you will have to change a few things, but I'm sure it will help you on the way!

  1. Create a dropdown field. Options you can leave empty (getCtaOptions in YourModel.php) or use a global static method like I did
cta:
        label: Link
        type: dropdown
        emptyOption: -- select  a page --
        options: \Aic\Globals\Helpers\FormHelper::getCtaOptions
  1. Create your method (static method example)
<?php namespace Aic\Globals\Helpers;

use Cms\Classes\Theme;
use Cms\Classes\Page as CmsPage;
use Winter\Pages\Classes\Page as StaticPage;

use Aic\BlogX\Models\Blog as BlogX;
use Aic\BlogY\Models\Blog as BlogY;
use Aic\BlogZ\Models\Blog as BlogZ;

class FormHelper
{

    public static function getCtaOptions($formWidget, $formField) {

        $currentTheme = Theme::getActiveTheme();
        $pages = [];

        foreach (CmsPage::listInTheme($currentTheme, false) as $page) {

            // BlogX
            if ($page->baseFileName == 'blog-x/article') {
                foreach (BlogX::select('id', 'slug', 'title')->get() as $post) {
                    $key = 'cms:' . $page->baseFileName . ':slug:' . $post->slug . ':Aic\BlogX\Models\Blog:' . $post->id;
                    $pages[$key] = 'Blog X - ' . $post->title;
                }
            }

            // Same as BlogX for BlogY, BlogZ, ...
                        // ... else if
                        // ... else if

            // All CMS pages
            else {
                if (strpos($page->baseFileName, 'category') || strpos($page->baseFileName, 'tag')) {
                    // don't include pages that contain category or tag (in my case not needed)
                } else {
                    $key = 'cms:' . $page->baseFileName;
                    $pages[$key] = $page->title;
                }
            }

        }

        foreach (StaticPage::listInTheme($currentTheme, false) as $page) {
            $key = 'static:' . $page->baseFileName;
            $pages[$key] = $page->title;
        }

        // sort the associative array alphabetically
        asort($pages);

        // return the pages
        return $pages;

    }

}
  1. Your dropdown should now be populated with all your pages

  2. Now you can render them in the frontend using twig

{% set cta = cta|split(':') %}
{% set type = cta[0] %}
{% set baseFileName = cta[1] %}
{% set property = cta[2] %}
{% set slug = cta[3] %}
{% set model = cta[4] %}
{% set id = cta[5] %}

{% if type == 'cms' %}
        {% if property == 'slug' %}

                {% set translatedSlug = slug|translateSlug(model, id) %}
                {% if translatedSlug %}
                        <a href='{{ baseFileName|page({ slug: translatedSlug }) }}'>Button label</a>
                {% endif %}

        {% else %}
                <a href='{{ baseFileName|page }}'>Button label</a>
        {% endif %}
{% else %}
        <a href='{{ baseFileName|staticPage }}'>Button label</a>
{% endif %}
  1. Finally, create the |translateSlug filter in your own Plugin.php. Note that for translations, your plugins need to implement the translatableModel
public function registerMarkupTags()
{
        return [
                'filters' => [
                        'translateSlug' => [$this, 'translateSlug']
                ]
        ];
}

public function translateSlug($slug, $model, $id)
{
        // cancel if Winter.Translate isn't installed
        if (!class_exists('Winter\Translate\Behaviors\TranslatableModel')) return $slug;

        // return the translated slug. Returns an empty string of none was found.
        return $model::find($id)?->noFallbackLocale()->getAttributeTranslated('slug');
}

Special thanks to mjauvin and Romain 'Maz' B

Discussion

0 comments

We use cookies to measure the performance of this website. Do you want to accept these cookies?