Skip to content
Code-Schnipsel Gruppen Projekte
Commit 01ff2ccc erstellt von Michael Danielczok's avatar Michael Danielczok
Dateien durchsuchen

Merge branch 'next-3.x' into 'main'

Next 3.x

See merge request !32
Übergeordnete a516fd34 ddc32729
No related branches found
Tags 3.1.0
2 Merge Requests!34Update 'next-4.x' with latest changes from 'main',!32Next 3.x
Pipeline #8612 bestanden mit Phase
in 50 Sekunden
......@@ -339,5 +339,179 @@
</settings>
</brick>
<!-- nav tabs vertical -->
<brick control="\QUI\Menu\Bricks\Submenu">
<title>
<locale group="quiqqer/menu"
var="bricks.submenu.title"/>
</title>
<description>
<locale group="quiqqer/menu"
var="bricks.submenu.description"/>
</description>
<settings>
<setting name="menuId" data-qui="package/quiqqer/menu/bin/Controls/Independent/Input" type="text">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.menuId"/>
<description>
<locale group="quiqqer/menu"
var="bricks.submenu.settings.menuId.desc"/>
</description>
</setting>
<setting name="startId" class="project-site">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.startId"/>
<description>
<locale group="quiqqer/menu"
var="bricks.submenu.settings.startId.desc"/>
</description>
</setting>
<setting name="template" type="select">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.template"/>
<option value="list-simple">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.template.list-simple"/>
</option>
<option value="list-buttonStyle">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.template.list-buttonStyle"/>
</option>
<option value="box-imageTop">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.template.box-imageTop"/>
</option>
<option value="box-imageOverlay">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.template.box-imageOverlay"/>
</option>
</setting>
<setting name="controlBgColor" type="color">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.controlBgColor"/>
<description>
<locale group="quiqqer/menu"
var="bricks.submenu.settings.controlBgColor.desc"/>
</description>
</setting>
<setting name="linkColor" type="color">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.linkColor"/>
<description>
<locale group="quiqqer/menu"
var="bricks.submenu.settings.linkColor.desc"/>
</description>
</setting>
<setting name="linkColorHover" type="color">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.linkColorHover"/>
<description>
<locale group="quiqqer/menu"
var="bricks.submenu.settings.linkColorHover.desc"/>
</description>
</setting>
<setting name="itemsAlignment" type="select">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.itemsAlignment"/>
<option value="start">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.itemsAlignment.start"/>
</option>
<option value="center">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.itemsAlignment.center"/>
</option>
<option value="end">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.itemsAlignment.end"/>
</option>
<option value="space-between">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.itemsAlignment.space-between"/>
</option>
<option value="space-around">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.itemsAlignment.space-around"/>
</option>
</setting>
<setting name="showImages" type="checkbox">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.showImages"/>
<description>
<locale group="quiqqer/menu"
var="bricks.submenu.settings.showImages.desc"/>
</description>
</setting>
<setting name="imageFitMode" type="select">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.imageFitMode"/>
<description>
<locale group="quiqqer/menu"
var="bricks.submenu.settings.imageFitMode.desc"/>
</description>
<option value="fill">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.imageFitMode.fill"/>
</option>
<option value="contain">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.imageFitMode.contain"/>
</option>
<option value="cover">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.imageFitMode.cover"/>
</option>
<option value="none">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.imageFitMode.none"/>
</option>
<option value="scale-down">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.imageFitMode.scale-down"/>
</option>
</setting>
<setting name="imageContainerHeight" type="text">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.imageContainerHeight"/>
<description>
<locale group="quiqqer/menu"
var="bricks.submenu.settings.imageContainerHeight.desc"/>
</description>
</setting>
<setting name="boxBgColor" type="color">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.boxBgColor"/>
<description>
<locale group="quiqqer/menu"
var="bricks.submenu.settings.boxBgColor.desc"/>
</description>
</setting>
<setting name="boxWidth" type="text">
<locale group="quiqqer/menu"
var="bricks.submenu.settings.boxWidth"/>
<description>
<locale group="quiqqer/menu"
var="bricks.submenu.settings.boxWidth.desc"/>
</description>
</setting>
</settings>
</brick>
</bricks>
</quiqqer>
\ No newline at end of file
......@@ -515,6 +515,166 @@
<de><![CDATA[Tab Einträge]]></de>
<en><![CDATA[Tab entries]]></en>
</locale>
<locale name="bricks.submenu.title">
<de><![CDATA[Menü: Submenu (Navigation)]]></de>
<en><![CDATA[Menu: Submenu]]></en>
</locale>
<locale name="bricks.submenu.desc">
<de><![CDATA[Platziere auf deiner Seite eine Subnavigation. Dadurch kann innerhalb der Seite gescrollt oder zu anderen Unterseiten verlinkt werden.]]></de>
<en><![CDATA[Place a sub-navigation on your page. This allows you to scroll within the page or link to other subpages.]]></en>
</locale>
<locale name="bricks.submenu.settings.menuId">
<de><![CDATA[Menu ID]]></de>
<en><![CDATA[Menu ID]]></en>
</locale>
<locale name="bricks.submenu.settings.menuId.desc">
<de><![CDATA[Menu ID auswählen.]]></de>
<en><![CDATA[Select your menu]]></en>
</locale>
<locale name="bricks.submenu.settings.startId">
<de><![CDATA[Elternseite]]></de>
<en><![CDATA[Parent site]]></en>
</locale>
<locale name="bricks.submenu.settings.startId.desc">
<de><![CDATA[Bitte die Elternseite auswählen. <strong>Achtung!</strong> Wenn "Menu ID" ausgewählt ist, hat diese Option keine Auswirkung.]]></de>
<en><![CDATA[Select the parent site. <strong>Notice:</strong> if "Menu ID" is selected, this option has no effect.]]></en>
</locale>
<locale name="bricks.submenu.settings.template">
<de><![CDATA[Vorlage]]></de>
<en><![CDATA[Template]]></en>
</locale>
<locale name="bricks.submenu.settings.template.list-simple">
<de><![CDATA[Liste: einfach]]></de>
<en><![CDATA[List: simple]]></en>
</locale>
<locale name="bricks.submenu.settings.template.list-buttonStyle">
<de><![CDATA[Liste: Button Style]]></de>
<en><![CDATA[Liste: button style]]></en>
</locale>
<locale name="bricks.submenu.settings.template.box-imageTop">
<de><![CDATA[Box: Bild / Icon über dem Text]]></de>
<en><![CDATA[Box: Image with text below]]></en>
</locale>
<locale name="bricks.submenu.settings.template.box-imageOverlay">
<de><![CDATA[Box: Text über dem Bild (nicht geeignet, wenn Icons als Bild gesetzt ist)]]></de>
<en><![CDATA[Box: Text above the image (not suitable if icons are set as images)]]></en>
</locale>
<locale name="bricks.submenu.settings.controlBgColor">
<de><![CDATA[Menu Hintergrundfarbe]]></de>
<en><![CDATA[Menu background color]]></en>
</locale>
<locale name="bricks.submenu.settings.controlBgColor.desc">
<de><![CDATA[Die ausgewählte Farbe wird hinter dem Menü angewendet.]]></de>
<en><![CDATA[The selected color is applied behind the menu.]]></en>
</locale>
<locale name="bricks.submenu.settings.linkColor">
<de><![CDATA[Link Farbe]]></de>
<en><![CDATA[Link color]]></en>
</locale>
<locale name="bricks.submenu.settings.linkColor.desc">
<de><![CDATA[Setzt die Farbe des Links. Wenn keine Farbe ausgewählt ist, wird die Farbe vererbt (meistens Textfarbe).]]></de>
<en><![CDATA[Sets the color of the link. If no color is selected, the color is inherited (usually text color).]]></en>
</locale>
<locale name="bricks.submenu.settings.linkColorHover">
<de><![CDATA[Aktive Link Farbe ("hover")]]></de>
<en><![CDATA[Hover link color]]></en>
</locale>
<locale name="bricks.submenu.settings.linkColorHover.desc">
<de><![CDATA[Diese Farbe wird benutzt, wenn man mit der Maus über dem Link fährt.]]></de>
<en><![CDATA[This color is used when you move the mouse over the link.]]></en>
</locale>
<locale name="bricks.submenu.settings.itemsAlignment">
<de><![CDATA[Menüpunkte Ausrichtung]]></de>
<en><![CDATA[Menu items alignment]]></en>
</locale>
<locale name="bricks.submenu.settings.itemsAlignment.start">
<de><![CDATA[Anfang (links)]]></de>
<en><![CDATA[Start (left)]]></en>
</locale>
<locale name="bricks.submenu.settings.itemsAlignment.center">
<de><![CDATA[Zentriert]]></de>
<en><![CDATA[Center]]></en>
</locale>
<locale name="bricks.submenu.settings.itemsAlignment.end">
<de><![CDATA[Ende (rechts)]]></de>
<en><![CDATA[End (right)]]></en>
</locale>
<locale name="bricks.submenu.settings.itemsAlignment.space-between">
<de><![CDATA[Menüpunkte gleichmäßig verteilen ("space between")]]></de>
<en><![CDATA[Space between]]></en>
</locale>
<locale name="bricks.submenu.settings.itemsAlignment.space-around">
<de><![CDATA[Menüpunkte gleichmäßig verteilen ("space around")]]></de>
<en><![CDATA[Space around]]></en>
</locale>
<locale name="bricks.submenu.settings.showImages">
<de><![CDATA[Bilder / Icons aktivieren]]></de>
<en><![CDATA[Active images or icons]]></en>
</locale>
<locale name="bricks.submenu.settings.showImages.desc">
<de><![CDATA[Falls die einzelne Einträge Bilder oder Icons eingestellt haben, werden diese angezeigt (außer in Template "List: einfach").]]></de>
<en><![CDATA[If the menu entries have images or icons set, these are displayed (except in template "List: simple").]]></en>
</locale>
<locale name="bricks.submenu.settings.imageFitMode">
<de><![CDATA[Bildverhalten]]></de>
<en><![CDATA[Image fit mode]]></en>
</locale>
<locale name="bricks.submenu.settings.imageFitMode.desc">
<de><![CDATA[Diese Einstellung hat Auswirkung nur auf Bilder, keine Icons.]]></de>
<en><![CDATA[This setting only affects images, not icons.]]></en>
</locale>
<locale name="bricks.submenu.settings.imageFitMode.fill">
<de><![CDATA[Fill: Die gesamte Fläche Ausfüllen - Bild kann verzerrt werden]]></de>
<en><![CDATA[Fill: Fill the entire area - image can be distorted]]></en>
</locale>
<locale name="bricks.submenu.settings.imageFitMode.contain">
<de><![CDATA[Contain: Bild wird verkleinert um in den verfügbaren Platz zu passen]]></de>
<en><![CDATA[Contain: Image is resized to fit in the available space]]></en>
</locale>
<locale name="bricks.submenu.settings.imageFitMode.cover">
<de><![CDATA[Cover: Die gesamte Fläche Ausfüllen - Bild kann abgeschnitten werden]]></de>
<en><![CDATA[Cover: Fill entire area - image can be cut off]]></en>
</locale>
<locale name="bricks.submenu.settings.imageFitMode.none">
<de><![CDATA[None: das Bild behält seine originale Größe]]></de>
<en><![CDATA[None: the image retains its original size]]></en>
</locale>
<locale name="bricks.submenu.settings.imageFitMode.scale-down">
<de><![CDATA[Scale down: das Bild wird u.U. verkleinert.]]></de>
<en><![CDATA[Scale down: the image may be reduced in size.]]></en>
</locale>
<locale name="bricks.submenu.settings.imageContainerHeight">
<de><![CDATA[Höhe der Bildbox]]></de>
<en><![CDATA[Image container height]]></en>
</locale>
<locale name="bricks.submenu.settings.imageContainerHeight.desc">
<de><![CDATA[Man kan jeden validen CSS Wert verwenden, auch die <code>clamp()</code> Funktion. Wird kein Wert gesetzt, wird die Box quadratisch.]]></de>
<en><![CDATA[You can use any valid CSS value, including the <code>clamp()</code> function. If no value is set, the container becomes square.]]></en>
</locale>
<locale name="bricks.submenu.settings.boxBgColor">
<de><![CDATA[Bildbox Farbe]]></de>
<en><![CDATA[Image container color]]></en>
</locale>
<locale name="bricks.submenu.settings.boxBgColor.desc">
<de><![CDATA[Diese Einstellung funktioniert nur mit Templates "Box: Bild / Icon oben" und "Box: Text über dem Bild" zusammen.]]></de>
<en><![CDATA[This setting only works with templates "Box: image or icon top" and "Box: Image with text below" together.]]></en>
</locale>
<locale name="bricks.submenu.settings.boxWidth">
<de><![CDATA[Breite der Menüeinträgen]]></de>
<en><![CDATA[Width of the menu items]]></en>
</locale>
<locale name="bricks.submenu.settings.boxWidth.desc">
<de><![CDATA[Man kan jeden validen CSS Wert verwenden, auch die <code>clamp()</code> Funktion. Diese Einstellung funktioniert nur mit Templates "Box: Bild / Icon oben" und "Box: Text über dem Bild" zusammen.]]></de>
<en><![CDATA[You can use any valid CSS value, including the <code>clamp()</code> function. If no value is set, the container becomes square. This setting only works with templates "Box: image or icon top" and "Box: Image with text below" together.]]></en>
</locale>
</groups>
<groups name="quiqqer/menu" datatype="php">
......
{if $this->getAttribute('showTitle') && $this->getAttribute('frontendTitle')}
<header class="control-header">
<h1>{$this->getAttribute('frontendTitle')}</h1>
</header>
{/if}
{if $this->getAttribute('content') != ""}
<div class="control-content">
{$this->getAttribute('content')}
</div>
{/if}
{$Submenu->create()}
\ No newline at end of file
<?php
/**
* This file contains \QUI\Menu\Bricks\Submenu
*/
namespace QUI\Menu\Bricks;
use QUI;
use QUI\Exception;
use QUI\Menu\Independent;
use QUI\Projects\Site\Utils;
/**
* Class Brick Submenu
*
* It creates a submenu navigation
*
* This control is supposed to work with QUI Independent Menu, but you can use it with QUI Site.
* You have to pass a menu ID or a parent page.
*
* @package QUI\Menu
* @author www.pcsg.de (Michael Danielczok)
*/
class Submenu extends QUI\Control
{
/**
* @param array $attributes
*/
public function __construct(array $attributes = [])
{
// defaults values
$this->setAttributes([
'class' => 'quiqqer-menu-bricks-submenu',
'startId' => false, // id or site link
'menuId' => false, // id of an independent menu
'template' => 'list-buttonStyle', // 'list-buttonStyle', 'list-simple', 'box-imageTop', 'box-imageOverlay'
'controlBgColor' => '',
'controlBgPadding' => '1rem',
'linkColor' => '',
'linkColorHover' => '',
'itemsAlignment' => 'center', // 'start', 'center', 'end', 'space-between', 'space-around'
'showImages' => true, // if true, icons or images will be displayed
'imageFitMode' => 'cover', // any valid css property for image-fit attribute , i.e. 'cover', 'contain', 'scale-down'
'imageContainerHeight' => '',// any valid css property (with unit!) for height attribute, i.e. '150px', '10vw' or even clamp() function (if no value passed the container will be a square)
'boxBgColor' => '#f5f5f6',
'boxWidth' => '250px'// any valid css property (with unit!) for height attribute, i.e. '250px', '10vw' or even clamp() function
]);
parent::__construct($attributes);
$this->setAttribute('cacheable', false);
}
/**
* (non-PHPdoc)
*
* @throws Exception
* @see \QUI\Control::create()
*/
public function getBody(): string
{
$Engine = QUI::getTemplateManager()->getEngine();
$linkColor = $this->getAttribute('linkColor');
if ($linkColor === '') {
$linkColor = 'inherit';
}
$linkColorHover = $this->getAttribute('linkColorHover');
if ($linkColor === '') {
$linkColorHover = 'inherit';
}
$Submenu = new QUI\Menu\Controls\Submenu([
'startId' => $this->getAttribute('startId'),
'menuId' => $this->getAttribute('menuId'),
'template' => $this->getAttribute('template'),
'controlBgColor' => $this->getAttribute('controlBgColor'),
'controlBgPadding' => $this->getAttribute('controlBgPadding'),
'linkColor' => $linkColor,
'linkColorHover' => $linkColorHover,
'itemsAlignment' => $this->getAttribute('itemsAlignment'),
'showImages' => $this->getAttribute('showImages'),
'imageFitMode' => $this->getAttribute('imageFitMode'),
'imageContainerHeight' => $this->getAttribute('imageContainerHeight'),
'boxBgColor' => $this->getAttribute('boxBgColor'),
'boxWidth' => $this->getAttribute('boxWidth')
]);
$Engine->assign([
'this' => $this,
'Submenu' => $Submenu
]);
return $Engine->fetch(dirname(__FILE__) . '/Submenu.html');
}
}
{strip}
{if count($children)}
<ul class="quiqqer-submenu__items">
{assign var=current value='quiqqer-submenu__item--current'}
{foreach from=$children item=Child}
<li class="quiqqer-submenu__item {if $Child->getUrl() === $url}{$current}{/if}">
{if $Child->getUrl()}
<a href="{$Child->getUrl()}" class="quiqqer-submenu__link"
title="{$Child->getTitleAttribute()|escape:'html'}"
{if $Child->getTarget()}target="{$Child->getTarget()}"{/if}>
{if $this->getAttribute('showImages') && $Child->getIcon()}
<div class="quiqqer-submenu__iconContainer">
{if $IconHandler->isIcon($Child->getIcon())}
<span class="{$Child->getIcon()} fa-fw quiqqer-submenu__icon"></span>
{else}
{image src=$Child->getIcon() height="500" class="quiqqer-submenu__image"}
{/if}
</div>
{/if}
<span class="quiqqer-submenu__label">{$Child->getTitle()}</span>
</a>
{else}
<span class="quiqqer-submenu__link"
title="{$Child->getTitleAttribute()|escape:'html'}">
{if $this->getAttribute('showImages') && $Child->getIcon()}
<div class="quiqqer-submenu__iconContainer">
{if $IconHandler->isIcon($Child->getIcon())}
<span class="{$Child->getIcon()} fa-fw quiqqer-submenu__icon"></span>
{else}
{image src=$Child->getIcon() height="500" class="quiqqer-submenu__image"}
{/if}
</div>
{/if}
<span class="quiqqer-submenu__label">{$Child->getTitle()}</span>
</span>
{/if}
</li>
{/foreach}
</ul>
{/if}
{/strip}
.quiqqer-submenu--box-imageTop, .quiqqer-submenu--box-imageOverlay {
--_quiqqer-menu-submenu__imageOverlayColor: var(--quiqqer-menu-submenu__imageOverlayColor, transparent);
}
/* Styling: general */
:where(.quiqqer-submenu--box-imageTop, .quiqqer-submenu--box-imageOverlay) .quiqqer-submenu__items {
display: flex;
gap: calc(var(--_quiqqer-menu-submenu__gap) * 1.5);
flex-wrap: wrap;
justify-content: var(--_quiqqer-menu-submenu__itemsAlignment);
}
:where(.quiqqer-submenu--box-imageTop, .quiqqer-submenu--box-imageOverlay) .quiqqer-submenu__item {
flex-basis: var(--_quiqqer-menu-submenu__boxWidth);
padding: 0 !important;
}
:where(.quiqqer-submenu--box-imageTop, .quiqqer-submenu--box-imageOverlay) .quiqqer-submenu__link {
text-align: center;
background-color: var(--_quiqqer-menu-submenu__boxBgColor);
height: 100%;
}
:where(.quiqqer-submenu--box-imageTop, .quiqqer-submenu--box-imageOverlay) .quiqqer-submenu__iconContainer {
width: 100%;
aspect-ratio: 1 / 1;
height: var(--_quiqqer-menu-submenu__imageContainerHeight);
overflow: hidden;
place-content: center;
}
:where(.quiqqer-submenu--box-imageTop, .quiqqer-submenu--box-imageOverlay) .quiqqer-submenu__label {
display: block;
padding: 0.5rem 1rem;
width: 100%;
}
:where(.quiqqer-submenu--box-imageTop, .quiqqer-submenu--box-imageOverlay) .quiqqer-submenu__icon {
font-size: 2em;
display: inline-block;
margin: 1rem;
}
:where(.quiqqer-submenu--box-imageTop, .quiqqer-submenu--box-imageOverlay) .quiqqer-submenu__image {
height: 100%;
width: 100%;
object-fit: var(--_quiqqer-menu-submenu__imageFitMode);
max-width: initial;
display: block;
}
/* Styling: image top */
:where(.quiqqer-submenu--box-imageTop) .quiqqer-submenu__link {
display: flex;
flex-direction: column;
align-items: center;
}
:where(.quiqqer-submenu--box-imageTop) .quiqqer-submenu__label {
margin-top: auto;
}
/* Styling: image overlay */
:where(.quiqqer-submenu--box-imageOverlay) .quiqqer-submenu__link {
display: grid;
align-items: center;
position: relative;
z-index: 1;
}
:where(.quiqqer-submenu--box-imageOverlay) .quiqqer-submenu__link:after {
content: '';
inset: 0;
background-color: var(--_quiqqer-menu-submenu__imageOverlayColor);
opacity: 0.25;
position: absolute;
z-index: 2;
}
:where(.quiqqer-submenu--box-imageOverlay) .quiqqer-submenu__iconContainer {
grid-area: 1 / 1 / 2 / 2;
position: relative;
z-index: 1;
}
:where(.quiqqer-submenu--box-imageOverlay) .quiqqer-submenu__label {
grid-area: 1 / 1 / 2 / 2;
position: relative;
z-index: 3;
}
\ No newline at end of file
{strip}
{if count($children)}
<ul class="quiqqer-submenu__items">
{assign var=current value='quiqqer-submenu__item--current'}
{foreach from=$children item=Child}
<li class="quiqqer-submenu__item {if $Child->getUrl() === $url}{$current}{/if}">
<a href="{$Child->getUrl()}" class="quiqqer-submenu__link"
title="{$Child->getAttribute('title')}">
{if $this->getAttribute('showImages') && $Child->getAttribute('image_site')}
<div class="quiqqer-submenu__iconContainer">
{if $IconHandler->isIcon($Child->getAttribute('image_site'))}
{image src=$Child->getAttribute('image_site') height="500" class="quiqqer-submenu__icon"}
{else}
{image src=$Child->getAttribute('image_site') height="500" class="quiqqer-submenu__image"}
{/if}
</div>
{/if}
<span class="quiqqer-submenu__label">{$Child->getAttribute('title')}</span>
</a>
</li>
{/foreach}
</ul>
{/if}
{/strip}
{strip}
{if count($children)}
<ul class="quiqqer-submenu__items">
{assign var=current value='quiqqer-submenu__item--current'}
{foreach from=$children item=Child}
<li class="quiqqer-submenu__item {if $Child->getUrl() === $url}{$current}{/if}">
{if $Child->getUrl()}
<a href="{$Child->getUrl()}" class="quiqqer-submenu__link"
title="{$Child->getTitleAttribute()|escape:'html'}"
{if $Child->getTarget()}target="{$Child->getTarget()}"{/if}>
{if $this->getAttribute('showImages') && $Child->getIcon()}
{if $IconHandler->isIcon($Child->getIcon())}
<span class="{$Child->getIcon()} fa-fw quiqqer-submenu__icon"></span>
{else}
{image src=$Child->getIcon() height="50" class="quiqqer-submenu__image"}
{/if}
{/if}
<span class="quiqqer-submenu__label">{$Child->getTitle()}</span>
</a>
{else}
<span class="quiqqer-submenu__link"
title="{$Child->getTitleAttribute()|escape:'html'}">
{if $this->getAttribute('showImages') && $Child->getIcon()}
{if $IconHandler->isIcon($Child->getIcon())}
<span class="{$Child->getIcon()} fa-fw quiqqer-submenu__icon"></span>
{else}
{image src=$Child->getIcon() height="50" class="quiqqer-submenu__image"}
{/if}
{/if}
<span class="quiqqer-submenu__label">{$Child->getTitle()}</span>
</span>
{/if}
</li>
{/foreach}
</ul>
{/if}
{/strip}
.quiqqer-submenu--list-simple,
.quiqqer-submenu--list-buttonStyle {
--_quiqqer-menu-submenu__linkBgColor: var(--quiqqer-menu-submenu__linkBgColor, transparent);
--_quiqqer-menu-submenu__linkBgColor--hover: var(--quiqqer-menu-submenu__linkBgColor--hover, #fff);
}
/* Styling: general */
:where(.quiqqer-submenu--list-simple, .quiqqer-submenu--list-buttonStyle) .quiqqer-submenu__items {
display: flex;
gap: 0 calc(var(--_quiqqer-menu-submenu__gap) * 1.5);
flex-wrap: wrap;
justify-content: var(--_quiqqer-menu-submenu__itemsAlignment);
align-items: center;
}
:where(.quiqqer-submenu--list-simple, .quiqqer-submenu--list-buttonStyle) .quiqqer-submenu__image,
:where(.quiqqer-submenu--list-simple, .quiqqer-submenu--list-buttonStyle) .quiqqer-submenu__icon {
margin-right: 0.5em;
}
:where(.quiqqer-submenu--list-simple, .quiqqer-submenu--list-buttonStyle) .quiqqer-submenu__image {
height: 1.5em;
width: auto;
vertical-align: middle;
}
/* Styling: simple list */
/* Styling: button style */
.quiqqer-submenu--list-buttonStyle {
background-color: var(--_quiqqer-menu-submenu__controlBgColor);
padding: 0.75rem 1rem;
}
:where(.quiqqer-submenu--list-buttonStyle) .quiqqer-submenu__link {
border-radius: 0.5em !important;
padding: 0.5em;
display: block;
background-color: var(--_quiqqer-menu-submenu__linkBgColor);
}
:where(.quiqqer-submenu--list-buttonStyle) .quiqqer-submenu__link:is(:hover, :active, :focus) {
background-color: var(--_quiqqer-menu-submenu__linkBgColor--hover);
}
:where(.quiqqer-submenu--list-buttonStyle) .quiqqer-submenu__image {
border-radius: 0.25em;
}
\ No newline at end of file
{strip}
{if count($children)}
<ul class="quiqqer-submenu__items">
{assign var=current value='quiqqer-submenu__item--current'}
{foreach from=$children item=Child}
<li class="quiqqer-submenu__item {if $Child->getUrl() === $url}{$current}{/if}">
<a href="{$Child->getUrl()}" class="quiqqer-submenu__link"
title="{$Child->getAttribute('title')}">
{if $this->getAttribute('showImages') && $Child->getAttribute('image_site')}
{if $IconHandler->isIcon($Child->getAttribute('image_site'))}
{image src=$Child->getAttribute('image_site') height="500" class="quiqqer-submenu__icon"}
{else}
{image src=$Child->getAttribute('image_site') height="50" class="quiqqer-submenu__image"}
{/if}
{/if}
<span class="quiqqer-submenu__label">{$Child->getAttribute('title')}</span>
</a>
</li>
{/foreach}
</ul>
{/if}
{/strip}
.quiqqer-submenu {
--_quiqqer-menu-submenu__gap: clamp(0.5rem, 2vw, 1rem);
background-color: var(--_quiqqer-menu-submenu__controlBgColor);
}
/* reset */
.quiqqer-submenu__items {
list-style: none;
margin: 0;
padding: 0;
}
/* general */
.quiqqer-submenu--controlPadding {
padding: var(--_quiqqer-menu-submenu__controlBgPadding);
}
.quiqqer-submenu__link {
cursor: pointer;
}
:where(.quiqqer-submenu--linkColor) .quiqqer-submenu__link {
color: var(--_quiqqer-menu-submenu__linkColor);
}
:where(.quiqqer-submenu--linkColorHover) .quiqqer-submenu__link:is(:hover, :active, :focus) {
color: var(--_quiqqer-menu-submenu__linkColor--hover);
}
\ No newline at end of file
<?php
/**
* This file contains \QUI\Menu\Controls\Submenu
*/
namespace QUI\Menu\Controls;
use QUI;
use QUI\Exception;
use QUI\Menu\Independent;
use QUI\Projects\Site\Utils;
/**
* Class Submenu
*
* It creates a submenu navigation
*
* This control is supposed to work with QUI Independent Menu, but you can use it with QUI Site.
* You have to pass a menu ID or a parent page.
*
* @package QUI\Menu
* @author www.pcsg.de (Michael Danielczok)
*/
class Submenu extends QUI\Control
{
private string $templateFile;
private string $templateCssFile;
/**
* @param array $attributes
*/
public function __construct(array $attributes = [])
{
// defaults values
$this->setAttributes([
'class' => 'quiqqer-submenu',
'startId' => false, // id or site link
'menuId' => false, // id of an independent menu
'template' => 'list-buttonStyle', // 'list-buttonStyle', 'list-simple', 'box-imageTop', 'box-imageOverlay'
'controlBgColor' => '',
'controlBgPadding' => '1rem',
'linkColor' => 'inherit',
'linkColorHover' => 'inherit',
'itemsAlignment' => 'center', // 'start', 'center', 'end', 'space-between', 'space-around'
'showImages' => true, // if true, icons or images will be displayed
'imageFitMode' => 'cover', // any valid css property for image-fit attribute , i.e. 'cover', 'contain', 'scale-down'
'imageContainerHeight' => '',// any valid css property (with unit!) for height attribute, i.e. '150px', '10vw' or even clamp() function (if no value passed the container will be a square)
'boxBgColor' => '#f5f5f6',
'boxWidth' => '250px'// any valid css property (with unit!) for height attribute, i.e. '250px', '10vw' or even clamp() function
]);
parent::__construct($attributes);
$this->setAttribute('cacheable', false);
}
/**
* (non-PHPdoc)
*
* @throws Exception
* @see \QUI\Control::create()
*/
public function getBody(): string
{
$isIndependentMenu = false;
if ($this->getAttribute('menuId')) {
// independent menu
$children = $this->getChildrenForIndependentMenu();
$isIndependentMenu = true;
} elseif ($this->getAttribute('startId')) {
// qui site
$children = $this->getChildrenForQUISite();
} else {
return '';
}
$url = false;
if (QUI::getRewrite()->getSite()->getUrlRewritten()) {
$url = QUI::getRewrite()->getSite()->getUrlRewritten();
}
$Engine = QUI::getTemplateManager()->getEngine();
$this->addCSSClass('quiqqer-submenu--' . $this->getAttribute('template'));
switch ($this->getAttribute('template')) {
case 'box-imageTop':
case 'box-imageOverlay':
$templateName = '/Submenu.Box.html';
if ($isIndependentMenu) {
$templateName = '/Submenu.Box.Independent.html';
}
$this->templateFile = dirname(__FILE__) . $templateName;
$this->templateCssFile = dirname(__FILE__) . '/Submenu.Box.css';
$this->setCustomVariable('imageFitMode', $this->getAttribute('imageFitMode'));
$imageContainerHeight = $this->getAttribute('imageContainerHeight');
if ($imageContainerHeight) {
$this->setCustomVariable('imageContainerHeight', $imageContainerHeight);
}
$this->setCustomVariable('boxBgColor', $this->getAttribute('boxBgColor'));
$this->setCustomVariable('boxWidth', $this->getAttribute('boxWidth'));
break;
case 'list-simple':
$templateName = '/Submenu.List.html';
if ($isIndependentMenu) {
$templateName = '/Submenu.List.Independent.html';
}
$this->templateFile = dirname(__FILE__) . $templateName;
$this->templateCssFile = dirname(__FILE__) . '/Submenu.List.css';
break;
default:
case 'list-buttonStyle':
$templateName = '/Submenu.List.html';
if ($isIndependentMenu) {
$templateName = '/Submenu.List.Independent.html';
}
if (!$this->getAttribute('controlBgColor')) {
$this->setAttribute('controlBgColor', '#f5f5f5');
}
$this->templateFile = dirname(__FILE__) . $templateName;
$this->templateCssFile = dirname(__FILE__) . '/Submenu.List.css';
break;
}
if ($this->getAttribute('controlBgColor')) {
$this->setCustomVariable(
'controlBgColor',
$this->getAttribute('controlBgColor')
);
if ($this->getAttribute('controlBgPadding')) {
$this->addCSSClass('quiqqer-submenu--controlPadding');
$this->setCustomVariable(
'controlBgPadding',
$this->getAttribute('controlBgPadding')
);
}
}
if ($this->getAttribute('linkColor')) {
$this->setCustomVariable(
'linkColor',
$this->getAttribute('linkColor')
);
$this->addCSSClass('quiqqer-submenu--linkColor');
}
if ($this->getAttribute('linkColorHover')) {
$this->setCustomVariable(
'linkColor--hover',
$this->getAttribute('linkColorHover')
);
$this->addCSSClass('quiqqer-submenu--linkColorHover');
}
switch ($this->getAttribute('itemsAlignment')) {
case 'start':
case 'center':
case 'end':
case 'space-between':
case 'space-around':
$itemsAlignment = $this->getAttribute('itemsAlignment');
break;
default:
$itemsAlignment = 'center';
break;
}
$this->setCustomVariable('itemsAlignment', $itemsAlignment);
$Engine->assign([
'this' => $this,
'children' => $children,
'url' => $url,
'IconHandler' => new QUI\Icons\Handler()
]);
$this->addCSSFile(dirname(__FILE__) . '/Submenu.css');
$this->addCSSFile($this->templateCssFile);
return $Engine->fetch($this->templateFile);
}
/**
* Get sites for independent menu
*
* @return array
* @throws QUI\Exception
*/
public function getChildrenForIndependentMenu(): array
{
$IndependentMenu = Independent\Handler::getMenu($this->getAttribute('menuId'));
return $IndependentMenu->getChildren();
}
/**
* Get sites for QUI site
*
* @return array|int
* @throws Exception
*/
public function getChildrenForQUISite(): array|int
{
$Project = $this->getProject();
// start
try {
$startId = $this->getAttribute('startId');
if (Utils::isSiteLink($startId)) {
$Site = Utils::getSiteByLink($startId);
} else {
$Site = $Project->get((int)$startId);
}
} catch (QUI\Exception $Exception) {
QUI\System\Log::addWarning($Exception->getMessage());
return [];
}
return $this->getChildren($Site);
}
/**
* @param QUI\Projects\Site $Site
* @return array|int
* @throws QUI\Exception
*/
public function getChildren(QUI\Projects\Site $Site): array|int
{
if (!$this->getAttribute('showAllChildren')) {
return $Site->getNavigation();
}
return $Site->getChildren();
}
/**
* Set custom css variable to the control as inline style
* --_quiqqer-menu-submenu-$name: var(--qui-submenu-$name, $value);
*
* Example:
* --_qui-submenu-linkColor: var(--quiqqer-menu-submenu-linkColor, inherit);
*
* @param string $name
* @param string $value
*
* @return void
*/
private function setCustomVariable(string $name, string $value): void
{
if (!$name || !$value) {
return;
}
$this->setStyle(
'--_quiqqer-menu-submenu__' . $name,
'var(--quiqqer-menu-submenu__' . $name . ', ' . $value . ')'
);
}
}
0% oder .
You are about to add 0 people to the discussion. Proceed with caution.
Bearbeitung dieser Nachricht zuerst beenden!
Bitte registrieren oder zum Kommentieren