Aligator (ProcessWire): Unterschied zwischen den Versionen
| (8 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt) | |||
| Zeile 1: | Zeile 1: | ||
Modul zum Erzeugen von Navigationen. Für meinen Geschmack sehr flexibel und übersichtlich. Bei Standard Menüs etwas mehr PHP Kenntnisse erforderlich. Bei komplexeren Markups und Anforderungen aber erheblich einfacher als bei MarkupSimpleNavigation vom selben Autor. | Modul zum Erzeugen von Navigationen. Für meinen Geschmack sehr flexibel und übersichtlich. Bei Standard Menüs etwas mehr PHP Kenntnisse erforderlich. Bei komplexeren Markups und Anforderungen aber erheblich einfacher als bei MarkupSimpleNavigation vom selben Autor. | ||
| − | + | == Links == | |
| + | https://processwire.com/talk/topic/13688-aligator/ | ||
| + | https://github.com/somatonic/Aligator | ||
== Funktionsweise == | == Funktionsweise == | ||
=== Options Array === | === Options Array === | ||
| Zeile 225: | Zeile 227: | ||
Any feedback or improvements are welcome. | Any feedback or improvements are welcome. | ||
| + | |||
| + | == Praxis Beispiele == | ||
| + | === Next Level Navigation === | ||
| + | <syntaxhighlight lang="php"> | ||
| + | <?php namespace ProcessWire; | ||
| + | // nav_next_level renders only next level from current page | ||
| + | $selector = 'menus.id=1';//only main items on next level | ||
| + | |||
| + | $nav = $modules->Aligator; | ||
| + | $nav->setDefaultOptions(array( | ||
| + | 'selector' => $selector, | ||
| + | 'callback' => function($item, $level){ | ||
| + | $item === wire('page') ? $liClasses = 'el-item uk-active' : $liClasses = 'el-item'; | ||
| + | return array( | ||
| + | 'item' => '<a class="el-link" href="'.$item->url.'">'.$item->title.'</a>', | ||
| + | 'listOpen' => ' | ||
| + | <li class="'.$liClasses.'">', | ||
| + | 'listClose' => '</li> | ||
| + | ', | ||
| + | 'wrapperOpen' => ' | ||
| + | <ul class="nav">', | ||
| + | 'wrapperClose' => '</ul> | ||
| + | ', | ||
| + | ); | ||
| + | }) | ||
| + | ); | ||
| + | $startpage = $page; | ||
| + | $markup = $nav->render($startpage,array(), $levels = 1, $collapsed = true); | ||
| + | |||
| + | echo $markup; | ||
| + | </syntaxhighlight> | ||
| + | === Only Second Level Navigation === | ||
| + | |||
| + | |||
| + | === UIkit Metamenu === | ||
| + | |||
| + | <syntaxhighlight lang="php"> | ||
| + | <?php namespace ProcessWire; | ||
| + | $selector = 'menus.id=2';//only metamenu items | ||
| + | $nav = $modules->Aligator; | ||
| + | $nav->setDefaultOptions(array( | ||
| + | 'selector' => $selector, | ||
| + | 'callback' => function($item, $level){ | ||
| + | $item === wire('page') ? $liClasses = 'el-item uk-active' : $liClasses = 'el-item'; | ||
| + | return array( | ||
| + | 'item' => '<a class="el-link" href="'.$item->url.'">'.$item->title.'</a>', | ||
| + | 'listOpen' => '<li class="'.$liClasses.'">', | ||
| + | 'listClose' => '</li>', | ||
| + | 'wrapperOpen' => '<ul class="uk-subnav uk-margin-remove-bottom uk-subnav-divider uk-flex-center" uk-margin>', | ||
| + | 'wrapperClose' => '</ul>', | ||
| + | ); | ||
| + | }) | ||
| + | ); | ||
| + | |||
| + | $root = $pages->get("/"); | ||
| + | $markup = $nav->render($root,array(), $levels = 1, $collaped = true); | ||
| + | echo $markup; | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | === UIkit Navigation === | ||
| + | '''header.inc''' | ||
| + | <syntaxhighlight lang="php"> | ||
| + | <header class='uk-background-transparent'> | ||
| + | <div id='masthead' class="uk-container"> | ||
| + | <?php include('nav-navbar-mobile.inc'); ?> | ||
| + | <?php include('nav-navbar-desktop.inc'); ?> | ||
| + | </div> | ||
| + | </header> | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | '''nav-navbar-mobile.inc''' | ||
| + | <syntaxhighlight lang="php"> | ||
| + | <?php namespace ProcessWire; | ||
| + | ?> | ||
| + | <nav id='navbar-mobile' class="uk-navbar-container uk-navbar-transparent uk-hidden@m" uk-navbar> | ||
| + | <div class="uk-navbar-left"> | ||
| + | <div class="uk-navbar-toggle"> | ||
| + | <a id='offcanvas-toggle' class='' href="#offcanvas-nav" uk-toggle> | ||
| + | <div uk-navbar-toggle-icon></div> | ||
| + | </a> | ||
| + | </div> | ||
| + | </div> | ||
| + | <div class="uk-navbar-center"> | ||
| + | <div class="uk-navbar-item"> | ||
| + | <a class="uk-logo" href="<?= $root ?>"> | ||
| + | <img class="logo" src="<?= $brandmarkImage->url?>" class="uk-responsive-height" alt="<?=$brandmarkImage->description?>"> | ||
| + | </a> | ||
| + | </div> | ||
| + | </div> | ||
| + | </nav> | ||
| + | |||
| + | </syntaxhighlight> | ||
| + | nav-navbar-desktop.inc | ||
| + | <syntaxhighlight lang="php"> | ||
| + | TODO | ||
| + | </syntaxhighlight> | ||
| + | <syntaxhighlight lang="php"> | ||
| + | TODO | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | === uiKit Accordion Navigation === | ||
| + | |||
| + | === Therapiezirkel (Main Menu) === | ||
| + | <syntaxhighlight lang="php"> | ||
| + | <?php namespace ProcessWire; | ||
| + | |||
| + | $nav = $modules->Aligator; | ||
| + | $menuPages = new PageArray(); | ||
| + | $home = $pages->get("/"); | ||
| + | |||
| + | $nav->enableStates = true; // enable states ("parent current has_children first last") | ||
| + | $nav->levels = 2; // set max levels to render | ||
| + | |||
| + | // the default options for all levels | ||
| + | $nav->setDefaultOptions(array( | ||
| + | "selector" => "", | ||
| + | "callback" => function($item, $level, $states){ | ||
| + | // $states is a string of item state classes to insert somewhere | ||
| + | $classes = $states ? " class='$states'" : ""; | ||
| + | $template = $item->template; | ||
| + | // Handle Dropdown $items | ||
| + | |||
| + | $ddAttribute = ""; | ||
| + | $ddLink = ""; | ||
| + | if( $item->numChildren() ) { | ||
| + | $ddAttribute = " data-ix='open-dd-res'"; | ||
| + | $ddLink = '<a href="#" class="w-inline-block arrow-ico-res"><i class="fa fa-angle-down"></i></a>'; | ||
| + | } | ||
| + | // Handle Placeholder code | ||
| + | if($template->name == "placeholder"){ | ||
| + | $itemString = "<div$ddAttribute class='w-clearfix nav-res-link'><a href='#' class='res-txt'>$item->title</a>$ddLink</div>"; | ||
| + | } | ||
| + | else { | ||
| + | $itemString = "<div class='w-clearfix nav-res-link'><a href='$item->url' class='res-txt animsition-link'>$item->title</a></div>"; | ||
| + | } | ||
| + | return array( | ||
| + | // todo animsition-link only when has children | ||
| + | "item" => $itemString, | ||
| + | "listOpen" => "<li$classes>", | ||
| + | "listClose" => "</li>", | ||
| + | "wrapperOpen" => "<ul class='w-list-unstyled dd-big-res'>", | ||
| + | "wrapperClose" => "</ul>", | ||
| + | ); | ||
| + | } | ||
| + | ) | ||
| + | ); | ||
| + | |||
| + | // render the menu | ||
| + | $markup = $nav->render($home, array( | ||
| + | array( // LEVEL 1 | ||
| + | "selector" => "menus.id=1", | ||
| + | "callback" => function($item, $level) use($home){ | ||
| + | return array( | ||
| + | //add homepage | ||
| + | "wrapperOpen" => "<ul class='w-list-unstyled dd-big-res'> | ||
| + | <li><div class='w-clearfix nav-res-link'><a href='$home->httpUrl' class='res-txt animsition-link'>$home->title</a></div></li>" | ||
| + | ); | ||
| + | } | ||
| + | ), | ||
| + | array( // LEVEL 2 | ||
| + | "selector" => "menus.id=1", | ||
| + | "callback" => function($item, $level, $states){ | ||
| + | // $states is a string of item state classes to insert somewhere | ||
| + | $classes = $states ? " class='$states'" : ""; | ||
| + | $template = $item->template; | ||
| + | // Handle Dropdown $items | ||
| + | $ddAttribute = ""; | ||
| + | |||
| + | // Handle Placeholder code | ||
| + | if($template->name == "placeholder"){ | ||
| + | $itemString = "<div$ddAttribute class='w-clearfix nav-res-link'><a href='#' class='res-txt'>$item->title</a></div>"; | ||
| + | } | ||
| + | else { | ||
| + | $itemString = "<div class='w-clearfix nav-res-link'><a href='$item->url' class='res-txt animsition-link'>$item->title</a></div>"; | ||
| + | } | ||
| + | return array( | ||
| + | // todo animsition-link only when has children | ||
| + | "item" => $itemString, | ||
| + | "listOpen" => "<li$classes>", | ||
| + | "listClose" => "</li>", | ||
| + | "wrapperOpen" => "<ul class='w-list-unstyled dd-res'>", | ||
| + | "wrapperClose" => "</ul>", | ||
| + | ); | ||
| + | } | ||
| + | ) | ||
| + | )); | ||
| + | |||
| + | |||
| + | |||
| + | echo ' | ||
| + | <!-- Mobile NAVIGATION --> | ||
| + | <div class="w-hidden-main"> | ||
| + | <div class="responsive-menu"> | ||
| + | <div class="w-container"> | ||
| + | <a href="index.html" class="w-inline-block brand-logo more-margin animsition-link"> | ||
| + | <img width="135" src="'.$config->urls->templates.'images/logo-therapiezirkel.png" alt="logo"> | ||
| + | </a> | ||
| + | <div data-ix="open-responsive-menu" class="hamburger"> | ||
| + | <div class="w-embed"> | ||
| + | <button class="c-hamburger c-hamburger--htx"> | ||
| + | <span>toggle menu</span> | ||
| + | </button> | ||
| + | </div> | ||
| + | </div> | ||
| + | </div> | ||
| + | </div><!-- .responsive-menu end --> | ||
| + | |||
| + | <nav class="responsive-nav"> | ||
| + | <div class="w-container"> | ||
| + | '.$markup.' | ||
| + | </div> | ||
| + | </nav> | ||
| + | </div> | ||
| + | |||
| + | <!-- Mobile NAVIGATION END--> | ||
| + | '; | ||
| + | |||
| + | </syntaxhighlight> | ||
Aktuelle Version vom 7. August 2019, 12:10 Uhr
Modul zum Erzeugen von Navigationen. Für meinen Geschmack sehr flexibel und übersichtlich. Bei Standard Menüs etwas mehr PHP Kenntnisse erforderlich. Bei komplexeren Markups und Anforderungen aber erheblich einfacher als bei MarkupSimpleNavigation vom selben Autor.
Links[Bearbeiten]
https://processwire.com/talk/topic/13688-aligator/ https://github.com/somatonic/Aligator
Funktionsweise[Bearbeiten]
Options Array[Bearbeiten]
The options array can contain a configuration for each level separately. So each entry represents a level.
$menuOptions = array(
array(...), // level 1
array(...), // level 2
array(...), // level 3
);
Render Methode[Bearbeiten]
The render method accepts four arguments and returns the markup as a string:
$markup = $modules->Aligator->render(root, options, maxlevels, collapsed);
Root kann sowohl eine Seite als auch ein PageArray sein.
Selektoren und Callback[Bearbeiten]
The options array is meant as a configuration for each level and item and contains two entries
selector
Is a regular ProcessWire selector used to filter children for this level
callback
Is an anonymous function that will get called for each page the module renders. It recieves two arguments for you to use: item and level where $item would be the current rendered child page object and $level the current level.
The callback function must return an associative array containing the markups for the current entry and level. Since this is a function, you can use your own logic and conditions to determine the markup you want to render.
Default options[Bearbeiten]
$menuOptions = array(
array(
"selector" => "",
"callback" => function($item, $level){
// any code here to determine the output
return array(
"item" => "<a href='$item->url'>$item->title</a>",
"listOpen" => "<li>",
"listClose" => "</li>",
"wrapperOpen" => "<ul>",
"wrapperClose" => "</ul>"
);
}
)
);
The array you return in the callback contains various predefined keys to define the markup. They're pretty self explanatory. If you omit any of these in the returned array, the module will take the default.
Praktischer Einsatz[Bearbeiten]
Wie in PW üblich entweder direkt das Modul aufrufen oder ein Objekt erzeugen:
$nav = $modules->get("Aligator");
// $nav = $modules->Aligator; // Kurzform
$menuOptions = array(...);
$root = $pages->get("/");
$markup = $nav->render($root, $menuOptions, $levels = 3, $collaped = false);
Oder direkt rendern
$markup = $modules->Aligator->render(root, options, maxlevels, collapsed);
oder auch
Overwrite Default Options[Bearbeiten]
You can overwrite the default options the module uses by using the setDefaultOptions() method:
$nav = $modules->Aligator;
$nav->setDefaultOptions(array(
"selector" => "",
"callback" => function($item, $level){
return array(
"item" => "<a href='$item->url'>$item->title</a>",
"listOpen" => "<li>",
"listClose" => "</li>",
"wrapperOpen" => "<ol>",
"wrapperClose" => "</ol>",
);
}
)
);
Beispiele[Bearbeiten]
Default Options überschreiben[Bearbeiten]
Here we set the default options. This will be used to render the markup when the level it renders isn't defined in the options array. In this example we set only the first level (1 entry) in the options. It will overwrite the default here only using a different "wrapperOpen". After that the default will be used to render the further levels .
$nav = $modules->Aligator;
$nav->setDefaultOptions(array(
"selector" => "template=basic-page",
"callback" => function($item, $level){
$class = $item === wire("page") ? " current" : "";
$class .= wire("page")->parents->has($item) ? " parent" : "";
if($level < 3) $class .= $item->numChildren("template=basic-page") ? " has_children" : "";
return array(
"item" => "<a href='$item->url'>$item->title</a>",
"listOpen" => "<li class='level$level$class'>",
"listClose" => "</li>",
"wrapperOpen" => "<ul class='dropdown$level'>",
"wrapperClose" => "</ul>",
);
}
)
);
$menuOptions = array(
array( // overwrite for first level
"selector" => "",
"callback" => function($item, $level){
return array(
"wrapperOpen" => "<ul class='mainnav'>"
);
},
)
);
$root = $pages->get("/");
$markup = $nav->render($root, $menuOptions, $levels = 3, $collaped = false);
Level unterschiedlich rendern[Bearbeiten]
Here we let the default options the module has and specify explicit the options for each level.
$menuOptions = array(
array( // level 1
"selector" => "template=basic-page|domain_root",
"callback" => function($item, $level){
$class = $item === wire("page") ? " current" : "";
$class .= wire("page")->parents->has($item) ? " parent" : "";
$class .= $item->numChildren("template=basic-page") ? " has_children" : "";
return array(
"item" => "<a href='$item->url'>$item->title $item->template</a>",
"listOpen" => "<li class='level$level$class'>",
"listClose" => "</li>",
"wrapperOpen" => "<ul class='mainnav'>",
"wrapperClose" => "</ul>",
);
},
),
array( // level 2
"selector" => "template=basic-page",
"callback" => function($item, $level){
$class = $item === wire("page") ? " current" : "";
$class .= wire("page")->parents->has($item) ? " parent" : "";
$class .= $item->numChildren("template=basic-page") ? " has_children" : "";
return array(
"item" => "<a href='$item->url'>$item->title</a>",
"listOpen" => "<li class='level$level$class'>",
"listClose" => "</li>",
"wrapperOpen" => "<ul class='dropdown2'>",
"wrapperClose" => "</ul>",
);
},
),
array( // level 3
"selector" => "template=basic-page|entry",
"callback" => function($item, $level){
$class = $item === wire("page") ? " current" : "";
$class .= wire("page")->parents->has($item) ? " parent" : "";
return array(
"item" => "<a href='$item->url'>$item->title</a>",
"listOpen" => "<li class='level$level$class'>",
"listClose" => "</li>",
"wrapperOpen" => "<ul class='dropdown3'>",
"wrapperClose" => "</ul>",
);
},
),
);
$root = $pages->get("/");
$markup = $nav->render($root, $menuOptions, $levels = 3, $collaped = false);
Homepage hinzufügen[Bearbeiten]
$menuPages = new PageArray();
$home = $pages->get("/");
$menuPages->add($home->children());
$menuPages->prepend($home);
$content .= $modules->Aligator->render($menuPages, array(
array( // level1
"selector" => ""
),
array( // level2 : don't render the children of "home"
"selector" => "parent!=1"
)
), 3);
oder
$homeUrl = $pages->get(1)->url;
$nav = $modules->Aligator->render($pages->get(1), array(
array( // level1
"selector" => "",
"callback" => function($item, $level) use($homeUrl){
return array(
"wrapperOpen" => "<ul><li><a href='$homeUrl'>Home</a></li>",
);
}
)
), 3);
What else
Nothing else. With these spare examples you should be able grasp the concept and use it and render navigations like crazy.
Any feedback or improvements are welcome.
Praxis Beispiele[Bearbeiten]
[Bearbeiten]
<?php namespace ProcessWire;
// nav_next_level renders only next level from current page
$selector = 'menus.id=1';//only main items on next level
$nav = $modules->Aligator;
$nav->setDefaultOptions(array(
'selector' => $selector,
'callback' => function($item, $level){
$item === wire('page') ? $liClasses = 'el-item uk-active' : $liClasses = 'el-item';
return array(
'item' => '<a class="el-link" href="'.$item->url.'">'.$item->title.'</a>',
'listOpen' => '
<li class="'.$liClasses.'">',
'listClose' => '</li>
',
'wrapperOpen' => '
<ul class="nav">',
'wrapperClose' => '</ul>
',
);
})
);
$startpage = $page;
$markup = $nav->render($startpage,array(), $levels = 1, $collapsed = true);
echo $markup;
[Bearbeiten]
[Bearbeiten]
<?php namespace ProcessWire;
$selector = 'menus.id=2';//only metamenu items
$nav = $modules->Aligator;
$nav->setDefaultOptions(array(
'selector' => $selector,
'callback' => function($item, $level){
$item === wire('page') ? $liClasses = 'el-item uk-active' : $liClasses = 'el-item';
return array(
'item' => '<a class="el-link" href="'.$item->url.'">'.$item->title.'</a>',
'listOpen' => '<li class="'.$liClasses.'">',
'listClose' => '</li>',
'wrapperOpen' => '<ul class="uk-subnav uk-margin-remove-bottom uk-subnav-divider uk-flex-center" uk-margin>',
'wrapperClose' => '</ul>',
);
})
);
$root = $pages->get("/");
$markup = $nav->render($root,array(), $levels = 1, $collaped = true);
echo $markup;
[Bearbeiten]
header.inc
<header class='uk-background-transparent'>
<div id='masthead' class="uk-container">
<?php include('nav-navbar-mobile.inc'); ?>
<?php include('nav-navbar-desktop.inc'); ?>
</div>
</header>
nav-navbar-mobile.inc
<?php namespace ProcessWire;
?>
<nav id='navbar-mobile' class="uk-navbar-container uk-navbar-transparent uk-hidden@m" uk-navbar>
<div class="uk-navbar-left">
<div class="uk-navbar-toggle">
<a id='offcanvas-toggle' class='' href="#offcanvas-nav" uk-toggle>
<div uk-navbar-toggle-icon></div>
</a>
</div>
</div>
<div class="uk-navbar-center">
<div class="uk-navbar-item">
<a class="uk-logo" href="<?= $root ?>">
<img class="logo" src="<?= $brandmarkImage->url?>" class="uk-responsive-height" alt="<?=$brandmarkImage->description?>">
</a>
</div>
</div>
</nav>
nav-navbar-desktop.inc
TODO
TODO
[Bearbeiten]
Therapiezirkel (Main Menu)[Bearbeiten]
<?php namespace ProcessWire;
$nav = $modules->Aligator;
$menuPages = new PageArray();
$home = $pages->get("/");
$nav->enableStates = true; // enable states ("parent current has_children first last")
$nav->levels = 2; // set max levels to render
// the default options for all levels
$nav->setDefaultOptions(array(
"selector" => "",
"callback" => function($item, $level, $states){
// $states is a string of item state classes to insert somewhere
$classes = $states ? " class='$states'" : "";
$template = $item->template;
// Handle Dropdown $items
$ddAttribute = "";
$ddLink = "";
if( $item->numChildren() ) {
$ddAttribute = " data-ix='open-dd-res'";
$ddLink = '<a href="#" class="w-inline-block arrow-ico-res"><i class="fa fa-angle-down"></i></a>';
}
// Handle Placeholder code
if($template->name == "placeholder"){
$itemString = "<div$ddAttribute class='w-clearfix nav-res-link'><a href='#' class='res-txt'>$item->title</a>$ddLink</div>";
}
else {
$itemString = "<div class='w-clearfix nav-res-link'><a href='$item->url' class='res-txt animsition-link'>$item->title</a></div>";
}
return array(
// todo animsition-link only when has children
"item" => $itemString,
"listOpen" => "<li$classes>",
"listClose" => "</li>",
"wrapperOpen" => "<ul class='w-list-unstyled dd-big-res'>",
"wrapperClose" => "</ul>",
);
}
)
);
// render the menu
$markup = $nav->render($home, array(
array( // LEVEL 1
"selector" => "menus.id=1",
"callback" => function($item, $level) use($home){
return array(
//add homepage
"wrapperOpen" => "<ul class='w-list-unstyled dd-big-res'>
<li><div class='w-clearfix nav-res-link'><a href='$home->httpUrl' class='res-txt animsition-link'>$home->title</a></div></li>"
);
}
),
array( // LEVEL 2
"selector" => "menus.id=1",
"callback" => function($item, $level, $states){
// $states is a string of item state classes to insert somewhere
$classes = $states ? " class='$states'" : "";
$template = $item->template;
// Handle Dropdown $items
$ddAttribute = "";
// Handle Placeholder code
if($template->name == "placeholder"){
$itemString = "<div$ddAttribute class='w-clearfix nav-res-link'><a href='#' class='res-txt'>$item->title</a></div>";
}
else {
$itemString = "<div class='w-clearfix nav-res-link'><a href='$item->url' class='res-txt animsition-link'>$item->title</a></div>";
}
return array(
// todo animsition-link only when has children
"item" => $itemString,
"listOpen" => "<li$classes>",
"listClose" => "</li>",
"wrapperOpen" => "<ul class='w-list-unstyled dd-res'>",
"wrapperClose" => "</ul>",
);
}
)
));
echo '
<!-- Mobile NAVIGATION -->
<div class="w-hidden-main">
<div class="responsive-menu">
<div class="w-container">
<a href="index.html" class="w-inline-block brand-logo more-margin animsition-link">
<img width="135" src="'.$config->urls->templates.'images/logo-therapiezirkel.png" alt="logo">
</a>
<div data-ix="open-responsive-menu" class="hamburger">
<div class="w-embed">
<button class="c-hamburger c-hamburger--htx">
<span>toggle menu</span>
</button>
</div>
</div>
</div>
</div><!-- .responsive-menu end -->
<nav class="responsive-nav">
<div class="w-container">
'.$markup.'
</div>
</nav>
</div>
<!-- Mobile NAVIGATION END-->
';