Jak zobrazit vybraný node pomocí jiného tématu vzhledu

Pomocí ThemeNegotiatorInterface si můžeme měnit téma vzhledu podle námi nadefinovaných podmínek. Tentokrát si ukážeme, jak si udělat checkbox pro vybrání libovolného nodu, který se má zobrazit s pomocí admin tématu.

Minule jsme si ukázali, jak použít theme negotiators (ThemeNegotiatorInterface) pro nastavení jiného tématu pro vybraný content type. Někdy je ale chceme třeba použít jiné téma je pro jednotlivé nody. Tady už nám ani modul Theme Switcher Rules nepomůže. Naštěstí jednoduchý vlastní modul nám problém vyřeší.

 

Identifikace nodu pro jiné téma pomocí contrib modulu

Nejdříve si nějak potřebujeme naše vybrané nody označit, že právě pro ně má být aplikovaný jiný než defaultní vzhled. K tomu můžeme využít dva existující modulu podobného jména i funkcionality.

Prvním modulem je Custom Publishing Options https://www.drupal.org/project/custom_pub známý už z dob Drupal 7. Je velmi jednoduchý, nastaví se jen jméno volby, a to je vlastně všechno. Pro definici nové volby se aktivuje hook_entity_base_field_info(), který přidá nové políčko do tabulky node_field_data.

Druhý modul je Publishing Options https://www.drupal.org/project/pub_options. Ten umožnuje si nastavit volby pro vybrané content typy. Nastavení si uchovává ve vlastních tabulkách.

Identifikace nodu pro jiné téma pomocí vlastního kódu

Pokud chceme mít plnou kontrolu na funkčností, pomůžeme si vlastním modulem. I zde použijeme funkci hook_entity_base_field_info(), kterou si ale můžeme nakonfigurovat do detailů – viz. třída BaseFieldDefinition https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Field%21….

Náš hook pak může vypadat takto:

/**
 * Implements hook_entity_base_field_info().
 */
function my_module_entity_base_field_info(EntityTypeInterface $entity_type)
{
    if ($entity_type->id() == 'node') {
        $fields = [];
        $fields['use_admin_theme'] = BaseFieldDefinition::create('boolean')
            ->setLabel(t('Use admin theme'))
            ->setDescription(t('If checked, this page will displayed using admin theme.'))
            ->setSettings(['on_label' => 'Use admin theme', 'off_label' => 'Use default front-end theme'])
            ->setDisplayOptions('form', [
                'type' => 'boolean_checkbox',
                'weight' => 2,
            ])
            ->setDisplayConfigurable('form', true)
            ->setDisplayConfigurable('view', false)
            ->setDefaultValue(false);
        return $fields;
    }
}

Pěkný článek o baseFieldDefinition je zde https://fivejars.com/blog/entity-basefielddefinitions-fields-examples-d….

Stejně jako u modulu Custom Publishing Options se nové políčku ukazuje u všech existujících content typů. Díky definici setDisplayConfigurable('form', true) si jeho viditelnost můžeme konfigurovat na stránce Manage form display.

33Manage form display

 

Jako běžné políčko ho vidíme při vytváření / editaci nodu

33Create Article

 

Pokud si ho chceme zobrazit např. ve skupině např. Promotion options, je třeba použít hook_form_BASE_FORM_ID_alter() třeba takto:

/**
 * Implements hook_form_BASE_FORM_ID_alter().
 */
function my_module_form_node_form_alter(&$form, $form_state, $form_id)
{
    $form['use_admin_theme']['#group'] = 'options';
}

33Promotion options

 

Implementace ThemeNegotiatorInterface

minule jsme si ukázali, jak používat vlastní ThemeNegotiatorInterface. Teď se předchozí kód jen trochu poupravíme.

Naše podmínka pro použití admin tématu bude využívat hodnotu našeho políčka

            if ($node->is_admin_route->value) {
                return true;
            }

33Force admin theme

Samozřejmě, pro určité případy si nemusíme vytvářet žádné custom políčko, a jako podmínku můžeme použít prostě jen nid ($node->id()).

 

Závěr

Dnes jsme si ukázali, jak použít admin téma – díky využití ThemeNegotiatorInterface - pro vybrané nody, které si můžeme zvolit pomocí nového custom políčka, které jsme si definovali pomocí BaseFieldDefinition.

Můžeme si také pomoci existujícími contrib moduly Custom Publishing Options a také Theme Switcher Rules, pro který bychom ale museli napsat vlastní podmínku, což by mělo jít pomocí RulesConditionBase https://www.drupal.org/docs/contributed-modules/rules-essentials/for-de….