Skip to content
Code-Schnipsel Gruppen Projekte

Revisionen vergleichen

Änderungen werden so angezeigt, als ob die Quellrevision mit der Zielrevision zusammengeführt würde. Erfahre mehr über den Vergleich von Revisionen.

Quelle

Zielprojekt auswählen
No results found

Ziel

Zielprojekt auswählen
  • quiqqer/package-menu
1 Ergebnis
Änderungen anzeigen
Commits auf Quelle (2)
......@@ -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 . ')'
);
}
}