Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify menu partial, remove "settings", make it easier to override default paritial #3

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 54 additions & 16 deletions components/Menu.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
class Menu extends ComponentBase
{

public $menuTree;

public function componentDetails()
{
return [
Expand Down Expand Up @@ -40,23 +42,59 @@ public function getMenu_idOptions()
*/
public function onRender()
{
$menu = MenuModel::find($this->property('menu_id', 0));
// Grab a list of menu settings
$settings = $menu->getDefaultSettings();
$menu = MenuModel::with(array('items' => function($query)
{
$query->where('enabled', '=', '1'); // Make sure to check if enabled.
}))->where('id', '=', $this->property('menu_id', 0))->get();

// Update $settings with any inline paramters they specified on their {% component %}
foreach ( $settings as $key => $setting )
$settings[$key] = $this->property($key, $setting);
$settings['menu'] = $menu;
$settings['selected_item'] = $this->property('selected_item', '');
foreach($menu as $singlemenu) // there is only one menu... but eager loading seems to make me do a loop
$this->menuTree= $this->buildTree($singlemenu, $this->controller);
}

// foreach ( $settings as $key => $setting )
// $this->page[$key] = $setting;
/**
* Using eager loading and creating my menuTree here uses way less database queries.
* The same thing could easily be done in the twig template using methods like getEagerChildren(), but this queries
* the database more.
*
* This essentially creates a hierarchical order of the items in the menu. Something like:
* returned array
* 0 = Menuitem {object}
* children = {array}
* 0 = Menuitem {object}
* 1 = Menuitem {object}
* 2 = etc...
* 1 = Menuitem {object}
* 2 = etc...
*
* @param $items
* @param int $parentId
* @param $controller
* @return array
*/
function buildTree($items, $controller, $parentId = 0) {
$branch = array();

// // This is an ugly and memory intensive hack required to get around
// // Controller not having a getVars() method.
// $this->page['settings'] = $settings;
// check if this is the first run through of this function
if(isset($items->items)){
$items = $items->items;
}

return $menu->render($this->controller, $settings);
}
}
foreach ($items as $item) {
if ($item->parent_id == $parentId) {
$children = $this->buildTree($items, $controller, $item->id);
if ($children) {
$item->children = $children;
}
// Support custom itemType-specific output
if ( class_exists($item->master_object_class) )
{
$itemTypeObj = new $item->master_object_class;
if ( $render = $itemTypeObj->onRender($item, $controller) )
$item->render = $render;
}
$branch[] = $item;
}
}

return $branch;
}}
68 changes: 63 additions & 5 deletions components/menu/default.htm
Original file line number Diff line number Diff line change
@@ -1,5 +1,63 @@
{{ before_menu|format(menu.id, menu.name|e, menu.short_desc|e)|raw }}
{% for item in menu.items().getNested() %}
{% partial __SELF__~"::item" item=item url=item.getUrl() child_count=item.getChildren().count() %}
{% endfor %}
{{ after_menu|format(menu.id, menu.name|e, menu.short_desc|e)|raw }}
{#
#### Options for overriding this file####
# Option 1:
# Add this DIRECTLY into your page/layout/paritial, change the __SELF__ below (note: NOT the _self)to your
# component alias (eg. menu.menuTree)
#
# See the end of this screencast for more and example: http://octobercms.com/blog/post/mastering-components)
#
# Option 2:
# If your overriding this partial using a paritial in your theme, leave the __SELF__ alone
# See: https://github.com/octobercms/docs/issues/18)
#}

{#
# This the __SELF__.menuTree uses octobercms's NestedTree trait. So on top of all the regular october/laravel methods,
# you can use all sorts of methods with the model. Here are a few from the NestedTree Trait:
#
# * $model->getRoot(); // Returns the highest parent of a node.
# * $model->getRootList(); // Returns an indented array of key and value columns from root.
# * $model->getParent(); // The direct parent node.
# * $model->getParents(); // Returns all parents up the tree.
# * $model->getParentsAndSelf(); // Returns all parents up the tree and self.
# * $model->getChildren(); // Set of all direct child nodes.
# * $model->getSiblings(); // Return all siblings (parent's children).
# * $model->getSiblingsAndSelf(); // Return all siblings and self.
# * $model->getLeaves(); // Returns all final nodes without children.
# * $model->getDepth(); // Returns the depth of a current node.
# * $model->getChildCount(); // Returns number of all children.
#}

{# Note: Only one levels of children are supported by Bootstrap 3 #}
{# This is usually added inside a navbar ul, eg: <ul class="nav navbar-nav navbar-right"> #}
{% macro render_menu(links) %}
{% for code, link in links %}
<li class=" {{ link.children ? 'dropdown' }} {{ code == currentPage ? 'active' }}">
{% if link.render %}
{{ link.render|raw }}
{% else %}
<a href="{{ link.children ? '#' : (link.page)|page }}"
{% if link.children %}data-toggle="dropdown"{% endif %}
class="{{ link.children ? 'dropdown-toggle' }}"
>
{% if link.getAttributes().icon %}
<i class="fa {{ link.getAttributes().icon ? link.getAttributes().icon :
(menu.getAttributes().default_icon ? menu.getAttributes().default_icon) }}"></i>
{% endif %}
<span>{{ link.getAttributes().label }}</span>
{% if link.children %}<span class="caret"></span>{% endif %}
</a>
{% if link.children %}
<ul class="dropdown-menu">
{{ _self.render_menu(link.children) }}
</ul>
{% endif %}
{% endif %}
</li>
{% endfor %}
{% endmacro %}

{% set menuTree = __SELF__.menuTree %}

{{ _self.render_menu(menuTree) }} {# this actually prints the menu #}

23 changes: 0 additions & 23 deletions components/menu/item.htm

This file was deleted.

2 changes: 1 addition & 1 deletion menuitemtypes/ItemTypeBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,5 @@ abstract public function getUrl(MenuItem $item);
*
* @return string
*/
public function onRender(MenuItem $item, Controller $controller, array $settings, $depth=0, $url, $child_count=0) {}
public function onRender(MenuItem $item, Controller $controller) {}
}
10 changes: 2 additions & 8 deletions menuitemtypes/Partial.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,12 @@ public function getUrl(MenuItem $item)
*
* @return string
*/
public function onRender(MenuItem $item, Controller $controller, array $settings, $depth=0, $url, $child_count=0)
public function onRender(MenuItem $item, Controller $controller)
{
$theme = Theme::getEditTheme();

return $controller->renderPartial($item->master_object_id, [
'item' => $item,
'settings' => $settings,
'depth' => $depth,
'url' => $url,
'child_count' => $child_count,
'before_item' => sprintf($settings['before_item'], $item->id, $item->id_attrib, $item->getClassAttrib($settings, $depth), $item->title_attrib),
'after_item' => sprintf($settings['after_item'], $item->id, $item->id_attrib, $item->getClassAttrib($settings, $depth), $item->title_attrib),
]);
]);
}
}
3 changes: 3 additions & 0 deletions models/Menuitem.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ class Menuitem extends Model
*/
public $table = 'flynsarmy_menu_menuitems';

public $children; // used when building a menu tree.
public $render; // used when building a menu tree.

// public $implement = ['October.Rain.Database.Behaviors.NestedSetModel'];

/**
Expand Down
7 changes: 0 additions & 7 deletions partials/_menu.php

This file was deleted.

24 changes: 0 additions & 24 deletions partials/_menuitem.php

This file was deleted.