This is a custom CMS where menu list can be edited in backend and then need to be displayed in front end layout.
Menu controller is in -/application/modules/admin/controllers
and the code for render action is :
<?php
class Admin_MenuController extends CMS_Controller_AdminbaseController
{
public function renderAction()
{
$menu = $this->_request->getParam('menu');
$mdlMenuItems = new Model_MenuItems();
$menuItems = $mdlMenuItems->getItemsByMenu($menu);
if(count($menuItems)>0){
foreach($menuItems as $item){
$label = $item->label;
if(!empty($item->link)){
$uri = $item->link;
}else{
$uri = '/page/open/id/' . $item->pageId;
}
$itemArray[] = array(
'label' => $label,
'uri' => $uri
);
}
$container = new Zend_Navigation($itemArray);
$this->view->navigation()->setContainer($container);
}
}
}
When rendered in - /application/modules/admin/views/scripts/menu/render.phtml using
<? echo $this->navigation()->menu(); ?>
it renders fine, but instead I want to render it in /application/layouts/scripts.
Any help is much appreciated.
go to Zend_View_Helper create exapmle.php as an example;
on it insert function
public function abc()
{
//insert your code here
}
then go to layout.phtml and call it
echo $this->abc();
You can render it in layout this way <?= $this->action('render', 'menu', 'admin');?>
Additionally you can pass some parametrs in array.
Hope this helps you.
Related
I am converting a static an html code to wordpress theme, i want to open another page to open when i click on the anchor tag, how do i go about it. Thanks.
<li>About Us</li>
In WordPress, links are permalinks:
Permalinks are the permanent URLs to your individual weblog posts, as
well as categories and other lists of weblog postings.
Original link: https://wordpress.org/support/article/using-permalinks
When creating a theme, you must display the links that are available in the admin panel: Admin panel -> Appearance -> Menus
The menu consists of locations, location is the place in the template where the user menu is displayed
I created a mini plugin for you that allows you to create custom menus and display them anywhere
Plugin structure:
wp-content\plugins\unbywyd-custom-menus
wp-content\plugins\unbywyd-custom-menus\unbywyd-custom-menus.php
wp-content\plugins\unbywyd-custom-menus\templates
wp-content\plugins\unbywyd-custom-menus\templates\navbar.hbs
wp-content\plugins\unbywyd-custom-menus\partials
wp-content\plugins\unbywyd-custom-menus\partials\menu_item.hbs
wp-content\plugins\unbywyd-custom-menus\partials\handlebars
wp-content\plugins\unbywyd-custom-menus\partials\handlebars\{library: https://github.com/zordius/lightncandy}
My example will be complete and working so that you can create any custom menus in WordPress. I will use the handlebars template engine to make things easier.
And so the contents of the unbywyd-custom-menus.php file:
<?php
/*
Plugin Name: Unbywyd custom menus
Version: 0.1
Author: Unbywyd
Author URI: unbywyd.com
*/
/*
* We will use the Handlebars template engine
*/
if(!class_exists('LightnCandy\LightnCandy')) {
require_once ("handlebars/autoload.php");
}
use LightnCandy\LightnCandy;
define('UCMS_DIR', plugin_dir_path(__FILE__));
class unbywydCustomMenus {
public $menus = [];
function __construct($menus=array()) {
$this->menus = $menus;
add_action('init', array($this, 'init'));
/*
* Create use_custom_menu shortcode
* You can use [use_custom_menu location="navbar"] in wordpress posts to display navbar menu
* And also for using from php <php print do_shortcode('[use_custom_menu location="navbar" customparam="test" class="test"]'); ?>
*/
add_shortcode( 'use_custom_menu', array($this, 'use_custom_menu'));
}
function use_custom_menu($attrs) { // Create shortcode handler
if(!isset($attrs['location'])) {
$attrs['location'] = '';
}
return $this->get_nav($attrs['location'], $attrs);
}
function get_template( $template_name ) { // Get a template by its name from templates/ directory
$path_to_file = wp_normalize_path(UCMS_DIR . 'templates/' . $template_name . '.hbs');
if(!file_exists($path_to_file)) {
return '';
}
return file_get_contents($path_to_file);
}
function get_handlebars_partials() { // Get all partials from partials/ directory
$path_to_partials = wp_normalize_path(UCMS_DIR . 'partials/');
if(!file_exists($path_to_partials)) {
return array();
}
$list_files = scandir($path_to_partials);
$partials = array();
foreach($list_files as $path) {
$path_to_file = wp_normalize_path($path_to_partials . '/'. $path);
if(is_file($path_to_file)) {
$ext = pathinfo($path_to_file, PATHINFO_EXTENSION);
if($ext == 'hbs') {
$partials[pathinfo($path, PATHINFO_FILENAME)] = function($name, $context) use($path_to_file) {
return $this->prepare_template(file_get_contents($path_to_file))($context, array('partials' => $this->get_handlebars_partials()));
};
}
}
}
return $partials;
}
function get_handlebars_helpers() {
return array(
/*
* You can use debug helper to display the incoming data into the template
* {{{debug}}}
*/
'debug' => function($context, $options=array()) {
if(!current_user_can('editor') && !current_user_can('administrator')) {
return '';
}
return '<pre class="debug" dir="ltr" style="text-align:left !important;">'.json_encode($context['data']['root'], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE).'</pre>';
}
);
}
// You can use this function to render any of your templates from /template directory
function template_render($template_name, $data) {
$prepared_template = $this->prepare_template($this->get_template( $template_name ));
$partials = $this->get_handlebars_partials();
return $prepared_template($data, array('partials' => $partials));
}
function prepare_template($template) {
$template = do_shortcode($template);
$prepared = LightnCandy::compile($template, array(
'flags' => LightnCandy::FLAG_HANDLEBARSJS | LightnCandy::FLAG_ADVARNAME | LightnCandy::FLAG_RUNTIMEPARTIAL | LightnCandy::FLAG_ERROR_SKIPPARTIAL,
'helpers' => $this->get_handlebars_helpers()
));
return LightnCandy::prepare($prepared);
}
function init() {
/*
* Registering custom menu locations
*/
foreach($this->menus as $menu) {
register_nav_menu($menu['id'], $menu['label']);
}
}
function build_tree(Array $data, $parent = 0) {
$tree = array();
foreach ($data as $d) {
if ($d['parent'] == $parent) {
$children = $this->build_tree($data, $d['id']);
if (!empty($children)) {
$d['children'] = $children;
}
$tree[] = $d;
}
}
return $tree;
}
// Get generated HTML of navigation
function get_nav( $location, $other_params=array() ) {
$menu_data = $this->get_nav_menu_items_by_location($location);
if(empty($menu_data)) {
return 'You can do nothing, or you can display a notification that there are no links in the menu';
} else {
return $this->template_render($location, array_merge($other_params, array('menu' => $menu_data)));
}
}
// Simple handler to build data of custom navigation
function get_nav_menu_items_by_location( $location, $args = [] ) {
$locations = get_nav_menu_locations();
if(!isset($locations[$location])) {
return array();
}
$object = wp_get_nav_menu_object( $locations[$location] );
if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') {
$link = "https";
} else {
$link = "http";
}
$link .= "://";
$link .= $_SERVER['HTTP_HOST'];
$link .= $_SERVER['REQUEST_URI'];
if(!$object) {
return array();
}
$menu_items = wp_get_nav_menu_items( $object->name, $args );
if(!$menu_items) {
return array();
} else {
$menu = array();
foreach( $menu_items as $i) {
$data = array(
'url' => $i->url,
'id' => $i->ID,
'parent' => $i->menu_item_parent,
'title' => $i->title,
'active' => $i->url == $link || $i->url . '/' == $link,
'attr_title' => $i->attr_title,
'description' => $i->description,
'class' => implode(' ', $i->classes)
);
if(!empty($i->target)) {
$data['target'] = $i->target;
}
$menu[] = $data;
}
return $this->build_tree($menu);
}
return $menu_items;
}
}
/*
* Сreate our custom menus
* Of course, you can add this complexity and bring it up to the plugin settings and display it in the wordpress admin panel as option page.
*/
new unbywydCustomMenus(
[
['id' => 'navbar', 'label' => 'Navbar menu'],
['id' => 'footer', 'label'=> 'Menu in footer']
]);
First you call the plugin class and pass your custom menus to register them:
new unbywydCustomMenus(
[
['id' => 'navbar', 'label' => 'Navbar menu'],
['id' => 'footer', 'label'=> 'Menu in footer']
]);
Then you can customize the menus in the admin panel and add them to your locations
Admin panel -> Appearance -> Menus | Manage Locations
and now you can display your menu anywhere in the post using a shortcode:
[use_custom_menu location="navbar" customparam="test" class="test"]
You will also be able to display it programmatically using php:
<php print do_shortcode('[use_custom_menu location="navbar" customparam="test" class="test"]'); ?>
Link to GutHub with working plugin
You could just put in the static URL https://www.website.com/about but that will change if you move the about page into another folder. To keep this dynamic, you can use the wordpress function get_page_link() (if you have the page id) or get_permalink and get_page_by_path if you have the slug. The about page will need to be created in the database first so you can get these parameters.
Using page ID: (ex: page ID is 40)
<li>About Us</li>
Using slug: (ex: slug is 'about-us')
<li>About Us</li>
You can also get it using the page title, though this might change over time so I don't recommend it:
<li>About Us</li>
More information about retrieving links dynamically here: https://code.tutsplus.com/tutorials/why-you-shouldnt-code-urls-in-wordpress-themes-or-plugins--cms-23262
I use this partial to generate my submenu.
<?php foreach ($this->container as $page): ?>
<?php foreach ($page->getPages() as $child): ?>
<a href="<?php echo $child->getHref(); ?>" class="list-group-item">
<?php echo $this->translate($child->getLabel()); ?>
</a>
<?php endforeach; ?>
<?php endforeach; ?>
Which is called like this:
$this->navigation('navigation')->menu()->setPartial('partial/submenu')->render();
But when i render the menu the "$child->getHref()" renders the url without the needed "slug/id" parameter.
I tried to create the url with "$this->url()" in ZF1 you could pass the params in an array to the partial but in ZF2 that doesn't seem to work anymore.
Can anybody tell me how to add the params to the menu urls?
Thanks in advance!
PS!
I'm not referring to $this->Partial, i'm talking about $this->navigation('navigation')->menu()->setPartial('partial/submenu')->render() which apparently doesn't support a param array.
If I'm understanding your question, yes, you can pass params to partials. Example:
<?php echo $this->partial('partial.phtml', array(
'from' => 'Team Framework',
'subject' => 'view partials')); ?>
See http://framework.zend.com/manual/2.3/en/modules/zend.view.helpers.partial.html
I'm not sure this completely solves your issue, since you are not showing what the menu helper is. Is it your own view helper? Are you saying that setPartial method only accepts one argument?
All that said, have you considered Spiffy Navigation?
https://github.com/spiffyjr/spiffy-navigation
It's been sometime since this question was asked, however today I came across the same problem (using version 2.4).
If you have a segment route to be included within the menu that requires some parameters there is no way to pass these through to the navigation's view partial helper.
The change I've made allows a ViewModel instance to be passed to the menu navigation helper's setPartial() method. This view model will be the context for the navigation's partial template rendering; therefore we can use it to set the variables we need for the route creation and fetch them just like within other views using $this->variableName.
The change requires you to extend the Menu helper (or which ever navigation helper requires it).
namespace Foo\Navigation;
use Zend\Navigation\AbstractContainer;
use Zend\View\Model\ViewModel;
class Menu extends \Zend\View\Helper\Navigation\Menu
{
public function renderPartial($container = null, $partial = null)
{
if (null == $container) {
$container = $this->getContainer();
}
if ($container && $partial instanceof ViewModel) {
$partial->setVariable('container', $container);
}
return parent::renderPartial($container, $partial);
}
public function setPartial($partial)
{
if ($partial instanceof ViewModel) {
$this->partial = $partial;
} else {
parent::setPartial($partial);
}
return $this;
}
}
Because this extends the default implementation of the helper updated configuration is required in module.config.php to ensure the extend class is loaded.
'navigation_helpers' => [
'invokables' => [
'Menu' => 'Foo\Navigation\Menu',
],
],
The menu helper will then accept a view model instance.
$viewModel = new \Zend\View\Model\ViewModel;
$viewModel->setTemplate('path/to/partial/template')
->setVariable('id', $foo->getId());
echo $this->navigation()
->menu()
->setPartial($viewModel)
->render();
The only change in the actual partial script will require you to create the URL's using the URL view helper.
foreach ($container as $page) {
//...
$href = $this->url($page->getRoute(), ['id' => $this->id]);
//...
}
I need a helper to change the default view of index page in wordpress.
My plugin is WPMVC generated and as per instructions in the official tutorial of WPMVC, i have created and loaded the helper but it is not working.
Can any one show me the right way to proceed?
Check the below link for a screen shot.
http://i.stack.imgur.com/3a1Ao.png
In the screeshot, the links and button below the records are added by me, overwriting the index file.
Now, i need to add a link near 'Edit | View | Delete' in the image, like,
Edit | View | Add Rule | Delete
Any suggestions on how to do that?
As i have told earlier, i created and loaded the helper but it is not functioning.
Need help. Thanks.
Codes:
/app/helpers/geozone_helper.php (Create Helper):
<?php
class GeozoneHelper extends MvcHelper {
public $_redirect_action = '';
public function __construct() {
if(empty($this->_redirect_action)) {
$this->_redirect_action = 'geozone_rules-add';
}
parent::__construct();
}
public function admin_actions_cell($controller, $object) {
$links = array();
$object_name = empty($object->__name) ? 'Item #'.$object->__id : $object->__name;
$encoded_object_name = $this->esc_attr($object_name);
$links[] = 'Edit';
$links[] = 'View';
$links[] = 'Add Rule';
$links[] = 'Delete';
$html = implode(' | ', $links);
return '<td>'.$html.'</td>';
}
}
/app/controllers/geozones_controller.php (load helper):
public function show() {
$object = $this->model->find_by_id($this->params['id'], array(
'includes' => array('Geozone')));
if (!empty($object)) {
$this->set('object', $object);
$this->render_view('show', array('layout' => 'public'));
}
$this->load_helper('geozone');
$this->set_object();
}
/app/view/geozones/show.php (link to the helper):
<h2><?php echo $object->__name; ?></h2>
<p>
<?php echo $this->html->link('← All Geozones', array('controller' => 'geozones')); ?>
<?php echo $this->geozone->admin_actions_cell($controller, $object->content); ?>
</p>
Thanks a lot again.
Issue resolved like this: The function
public function show() {
$this->load_helper('geozone');
$this->set_object();
}
in public controller is shifted to admin controller and function name is changed to index() like this:
public function index() {
$this->load_helper('geozone');
$this->set_objects();
}
Thanks for everyone who tried to solve this.
I have a breadcrumb in a child view, but it is not showing any pages.
When I show it in the root view, everything is working correct
controller:
public function categoriesAction()
{
$view = new ViewModel();
$heading = new ViewModel(array(
'headTitle' => 'Categorieën'
));
$heading->setTemplate('templates/head');
$view->addChild($heading, 'header')
->addChild($storecontent, 'content');
return $view;
}
templates/head.phtml
<?php echo $this->navigation()->breadcrumbs()->setPartial('Application/partials/breadcrumbs'); ?>
When I place the above code in the root view, it is working. But I want it in the head so I can use it in more actions.
I'm making a language selector and followed this wiki. I can implement the widget, but when I try the dropdown it doesn't make the postback. For the controller I have the idea that the controller should be: components/Controller.php in stead of components/MyController.php. But anyways both don't work. Does anyone know what to do here? I'm missing something about the essentials of catching a postback here i think..
Controller (components/controller.php):
function init()
{
parent::init();
$app = Yii::app();
if (isset($_POST['_lang']))
{
$app->language = $_POST['_lang'];
$app->session['_lang'] = $app->language;
}
else if (isset($app->session['_lang']))
{
$app->language = $app->session['_lang'];
}
Yii::app()->session['_lang'] = 'anders';
}
widget class (components/LangBox.php):
class LangBox extends CWidget
{
public function run()
{
$currentLang = Yii::app()->language;
$this->render('langBox', array('currentLang' => $currentLang));
}
}
widget view (components/views/langBox.php)
<?php echo CHtml::form(); ?>
<div id="langdrop">
<?php echo CHtml::dropDownList('_lang', $currentLang, array(
'en_us' => 'English', 'is_is' => 'Icelandic'), array('submit' => '')); ?>
</div>
<?php echo CHtml::endForm(); ?>
I am sure your code works ok, but are you actually submitting the form? You should really have a jquery that detects when the dropdown changed and submits it to the server and refreshes the page. Everything else is sound.
I have no idea what 'submit'=>'' does.