How to get category discription? - magento2

This is phtml code for getting selected category. I want to get category description. How can I get that?
<?php
$catId =2;
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$subcategory = $objectManager->create('Magento\Catalog\Model\Category')->load($catId);
$subcats = $subcategory->getChildrenCategories();
?>
<ul>
<li> <span> All Categories </span> </li>
<?php
foreach ($subcats as $subcat) {
if ($subcat->getIsActive()) {
$subcat_url = $subcat->getUrl();
$subcat_img = "";
$placeholder_img = "/media/placeholder.png";
?>
<li>
<a href="<?php echo $subcat_url; ?>">
<?php echo $subcat->getName(); ?>
</a>
</li>
<?php
}
}
?>
</ul>

To get the Category Description, you have to load Category and after that, you can use getDescription() function.
I have made some changes in your code. Please find the new code here:
<?php
$catId =2;
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$subcategory = $objectManager->create('Magento\Catalog\Model\Category')->load($catId);
$subcats = $subcategory->getChildrenCategories();
?>
<ul>
<li> <span> All Categories </span> </li>
<?php
foreach ($subcats as $subcat) {
if ($subcat->getIsActive()) {
$subcat = $objectManager->create('Magento\Catalog\Model\Category')->load($subcat->getId());
$subcat_url = $subcat->getUrl();
$subcat_img = "";
$placeholder_img = "/media/placeholder.png";
?>
<li>
<a href="<?php echo $subcat_url; ?>">
<?php echo $subcat->getName(); ?>
</a>
<p><?php echo $subcat->getDescription(); ?></p>
</li>
<?php
}
}
?>
</ul>
Note: In Magento 2, the direct use of ObjectManager in template files is not a good practice. Dependency injection is the recommended approach.
For more details on how to use ObjectManager and what the consequences are of using the ObjectManager directly, you can follow the link below:
https://magento.stackexchange.com/questions/117098/magento-2-to-use-or-not-to-use-the-objectmanager-directly

Related

Magento 2 get store id

magento 2 get store id php
I need to show something based on store id
for exapmle;
<?php if ($store == "2") {?>
<div class="block-bottom">
<a class="button-sticky-bottom" href="<?php echo $this->getUrl('') ?>">
<i class="fa fa-flag" style="font-size: 18px;"></i>
<span><?php echo __('Language'); ?></span>
</a>
</div>
<?php } else { ?>
<div class="block-bottom">
<a class="button-sticky-bottom" href="<?php echo $this->getUrl('') ?>">
<i class="fa fa-flag" style="font-size: 18px;"></i>
<span><?php echo __('Language1'); ?></span>
</a>
</div>
<?php } ?>
<?php
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$storeManager = $objectManager->create('\Magento\Store\Model\StoreManagerInterface');
$storeId = $storeManager->getStore()->getId();
if($storeId == 1){
echo 'Store Id 1 code here';
}else{
echo 'other stores code here';
}
?>
$storeManager = \Magento\Framework\App\ObjectManager::getInstance()->get('\Magento\Store\Model\StoreManagerInterface');
if ($storeManager->getStore()->getStoreId() == 1) {
echo 'Hello';
} else {
echo 'Thanks';
}
The use of object manager is not recommended. It is better to arrange this code for the class of the block using the constructor
I would recommend injecting the StoreManagerInterface in your construct and avoid using the object manager.
Example
/**
* #var \Magento\Store\Model\StoreManagerInterface
*/
protected $storeManager;
public function __construct(Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager)
{
parent::__construct($context);
$this->storeManager = $storeManager;
}
public function myFunction()
{
$storeId = $this->storeManager->getStore()->getId();
if ($storeId == 1) {
echo 'Store Id 1 code here';
} else {
echo 'other stores code here';
}
}
It didnt worked. What is wrong?
<?php
$storeManager = \Magento\Framework\App\ObjectManager::getInstance()->get('\Magento\Store\Model\StoreManagerInterface');
if ($storeManager->getStore()->getStoreId() == 1) { ?>
<div class="block-bottom">
<a class="button-sticky-bottom" href="<?php echo $this->getUrl('') ?>">
<i class="fa fa-flag" style="font-size: 18px;"></i>
<span><?php echo __('Language'); ?></span>
</a>
</div>
<?php } else { ?>
<div class="block-bottom">
<a class="button-sticky-bottom" href="<?php echo $this->getUrl('') ?>">
<i class="fa fa-flag" style="font-size: 18px;"></i>
<span><?php echo __('Language1'); ?></span>
</a>
</div>
<?php }
?>

How to display related post by categories with next post of current post (don't latest post or random post)

How to display related post by categories with next post of current post (don't latest post or random post). I'm use code related post for twentytwelve theme. but now, author in wentytwelve_entry_meta() is repeat.
pls help me :
<div id="related_posts">
<?php
$categories = get_the_category($post->ID);
if ($categories) {
$category_ids = array();
foreach((get_the_category()) as $category) {
$id = $category->cat_ID;
}
global $wpdb;
$query = "
SELECT * FROM $wpdb->posts
LEFT JOIN $wpdb->term_relationships ON
($wpdb->posts.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy ON
($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
WHERE $wpdb->posts.post_status = 'publish'
AND $wpdb->term_taxonomy.taxonomy = 'category'
AND $wpdb->term_taxonomy.term_id = $category_ids[0]
AND $wpdb->posts.id < $post->ID
ORDER BY id DESC limit 3
";
$my_query = $wpdb->get_results($query);
if( $my_query) {
echo '<h3>Related Posts</h3><ul>';
foreach($my_query as $key => $post) {
?>
<li>
<div class="entry-header">
<div class="header-l">
<h1 class="entry-title">
<?php the_title(); ?>
</h1>
<p class="datetime">
<?php twentytwelve_entry_meta(); ?>
</p>
</div>
<?php the_post_thumbnail(); ?>
</div>
<div class="entry-summary">
<?php
$str_content = wp_trim_words($post->post_content);
$str_content = str_replace('[', '<', $str_content);
$str_content = str_replace(']', '>', $str_content);
echo $str_content;
?>
</div>
</li>
<?php
}
echo '</ul>';
}
}?>
WordPress customary is to use WP_Query class to fetch posts from DB, if you can modify your code to use WP_Query it would be easier.
WP_Query Reference
As you are using Custom Query to load your posts from DB, template tags like the_permalink(), the_title_attribute(), the_title() etc will not work properly that is the reason while theme function twentytwelve_entry_meta() fails.
As per codex reference Displaying Posts Using a Custom Select Query
You should try something like this:
global $wpdb;
$query = "
SELECT * FROM $wpdb->posts
LEFT JOIN $wpdb->term_relationships ON
($wpdb->posts.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy ON
($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
WHERE $wpdb->posts.post_status = 'publish'
AND $wpdb->term_taxonomy.taxonomy = 'category'
AND $wpdb->term_taxonomy.term_id = $category_ids[0]
AND $wpdb->posts.id < $post->ID
ORDER BY id DESC limit 3";
$my_query = $wpdb->get_results($query);
if($my_query) {
global $post;
echo '<h3>Related Posts</h3><ul>';
foreach($my_query as $key => $post) {
//use setup postdata, it works only for variable named $post.
setup_postdata($post);
//you can safely use template tags now.
?>
<li>
<div class="entry-header">
<div class="header-l">
<h1 class="entry-title">
<?php the_title(); ?>
</h1>
<p class="datetime">
<?php twentytwelve_entry_meta(); ?>
</p>
</div>
<?php the_post_thumbnail(); ?>
</div>
<div class="entry-summary">
<?php
$str_content = wp_trim_words($post->post_content);
$str_content = str_replace('[', '<', $str_content);
$str_content = str_replace(']', '>', $str_content);
echo $str_content;
?>
</div>
</li>
<?php
}
}
Other interesting post:
What does setup_postdata ($post ) do?

how to convert zend_paginator to ajax in zend framework

this is my action,currently my page is refreshing i want it with ajax.so that without refreshing the whole page my pagination div is refeshing loading the content from DB.
public function calllogsAction(){
if(!Zend_Auth::getInstance()->hasIdentity()){
$this->_redirect('login/login');
}
else{
$request = $this->getRequest();
$phone_service_id = $request->getParam("id");
$registry = Zend_Registry::getInstance();
$DB = $registry['DB'];
$sql ="SELECT caller_name,call_number,call_start_time,call_duration,call_direction FROM CALL_LOG WHERE phone_service_id = $phone_service_id";
$result = $DB->fetchAll($sql);
$page=$this->_getParam('page',1);
$paginator = Zend_Paginator::factory($result);
$paginator->setItemCountPerPage(10);
$paginator->setCurrentPageNumber($page);
$this->view->paginator=$paginator;
$page = $paginator->getCurrentPageNumber();
$perPage = $paginator->getItemCountPerPage();
$total = $paginator->getTotalItemCount();
$A = ($page - 1) * $perPage + 1;
$B = min($A + $perPage - 1, $total);
$C = $total;
$this->view->assign('url', $request->getBaseURL());
$this->view->assign('total',$total );
$this->view->assign('page',$page );
$this->view->assign('A',$A );
$this->view->assign('B',$B );
$this->view->assign('C',$C );
}
}
and this is my view.i have much more in my view but the pagination is here si i want to refresh this div
<div class="container" id="actualbody" style="margin-left:168px;">
<?php
$sr_no = 1;
foreach($this->paginator as $record){
if($sr_no % 2 == 0){
$style = 'class="even-row"';
}
else{
$style = 'class="odd-row"';
<tr <?php echo $style;?>>
<td class="sorting_1"> <input type="checkbox" /> </td>
<td ><?php if($record->call_direction =="Outgoing"){?> <img src=" <?php echo $this->baseUrl('/assets/images/outgoing.png'); ?> " /> <?php } elseif($record->call_direction =="Missed") {?> <img src=" <?php echo $this->baseUrl('/assets/images/misses.png'); ?> " /> <?php } else { ?> <img src=" <?php echo $this->baseUrl('/assets/images/incoming.png'); ?> " /> <?php }?></td>
<td><?php echo $record->caller_name;?></td>
<td><?php echo $record->call_number;?></td>
<td ><?php echo $record->call_start_time;?></td>
<td ><?php echo $record->call_duration;?></td>
</tr>
<?php $sr_no ++; }?>
<div> Showing <?= $this->A; ?> to <?= $this->B; ?> of <?=$this->C; ?> entries </div>
<div> <?php echo $this->paginationControl($this->paginator, 'Sliding', 'pagination.phtml'); ?></div>
</div>
how can i make my pagination through ajax
this pagination.phtml
<div class="pagination" style="width:100%">
<div style="float:left;width:28%">
</div>
<div style="float:right;width:70%;">
<!-- First page link -->
<?php if (isset($this->previous)): ?>
<span class="first ui-corner-tl ui-corner-bl fg-button ui-button ui-state-default ui-state-disabled">Start</span>
<?php else: ?>
<span class="next fg-button ui-button ui-state-default ui-state-disabled">Start</span>
<?php endif; ?>
<!-- Previous page link -->
<?php if (isset($this->previous)): ?>
<span class="previous fg-button ui-button ui-state-default ui-state-disabled">Previous</span>
<?php else: ?>
<span class="next fg-button ui-button ui-state-default ui-state-disabled">Previous</span>
<?php endif; ?>
<!-- Numbered page links -->
<?php foreach ($this->pagesInRange as $page): ?>
<?php if ($page != $this->current): ?>
<span class="fg-button ui-button ui-state-default"><?= $page; ?></span>
<?php else: ?>
<span class="fg-button ui-button ui-state-default ui-state-disabled" ><?= $page; ?></span>
<?php endif; ?>
<?php endforeach; ?>
<!-- Next page link -->
<?php if (isset($this->next)): ?>
<span class="next fg-button ui-button ui-state-default">Next</span>
<?php else: ?>
<span class="next fg-button ui-button ui-state-default ui-state-disabled">Next</span>
<?php endif; ?>
<!-- Last page link -->
<?php if (isset($this->next)): ?>
<span class="last ui-corner-tr ui-corner-br fg-button ui-button ui-state-default">End</span>
<?php else: ?>
<span class="next fg-button ui-button ui-state-default ui-state-disabled">End</span>
<?php endif; ?>
</div>
edited
i add this code
jQuery(function($){
var container = $('#paged-data-container');
var overlay = $('<div>').addClass('loading overlay');
$('.pagination-control').find('a').live('click', function(){
var href = this.href;
var pos = this.rel == 'next' ? '-120%' : '120%';
if (Modernizr.history) {
history.pushState(location.pathname, '', href);
}
container.find('.data').animate({
left: pos
}, 'slow', function(){
var dataContainer = container.find('.paged-data').addClass('loading');
$.get(href, { format: 'html' }, function(data){
dataContainer.removeClass('loading');
container.html(data);
}, 'html');
});
return false;
});
var initialPath = location.pathname;
$(window).bind('popstate', function(e){
// Prevent popstate handler dealing with initial page load
if (location.pathname == initialPath) {
initialPath = null;
return;
}
container.append(overlay);
$.get(location.pathname, { format: 'html' }, function(data){
container.html(data);
}, 'html');
});
});
also add this code to my controller
public function init(){
$this->_helper->ajaxContext->addActionContext('calllogs', 'html')
->initContext();
}
now my collogs.phtml looks like this
<?php
include_once("header.phtml");
include_once("blue1.phtml");
include_once("sidebar.phtml");
?>
<div id="paged-data-container">
<?php echo $this->render('login/calllogs_page.phtml') ?>
</div>
<?php include_once("footer.phtml"); ?>
and this is my calllogs_page.phtml
<?php $paginationControl = $this->paginationControl(
$this->paginator, 'All', 'pagination.phtml') ?>
old stuff here
<div class="pagination-control">
<div class="fg-toolbar ui-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix" style="height:35px">
<?php if (count($this->paginator)): ?>
<div class="dataTables_info" style="float:left;"> Showing <?= $this->A; ?> to <?= $this->B; ?> of <?=$this->C; ?> entries </div>
<div class="pagination-control" style="margin-left:173px;">
<?php echo $paginationControl ?>
</div>
now my page is changing in address bar when ever i click on any pagination link but nothing happens than
this is the jquery which
$(function($){
$('.pagination-control').find('a').live('click', function(){
var link = $(this);
var container = link.parents('.paged-data-container');
$.get(link.attr('href'), { format: 'html' }, function(data){
container.html(data);
}, 'html');
return false;
});
});
Follow these tutorials: Zend framework video tutorials
Starting from video 11 Zend_Paginator is introduced. Later on it is modified to use Ajax in another video.
I really recommend that you look into it.

Doctrine2 large collections

I have been playing with doctrine2 + ZF setup for the last couple of days.
One of the things I still can't figure out is the large array collection assosicaitons. For example let's say we have an entity called Post and each post can have many comments.
<?php
/**
* #Entity
*/
class Post
{
/**
* #OneToMany(targetEntity="Comment", mappedBy="post")
*/
protected $comments;
}
?>
Now this will load all comments if I do
$post->comments
But what if there are, say 10000 comments for this particular post? Then all will be loaded which is not good. And as far as I know slice/pagination will not be available until doctrine 2.1.
Can someone advice me how I can paginate comments? With DQL maybe? if DQL, where do you implement this?Do I create a getComments method in the Post entity and do the DQL there?
Thanks
Bill
I'm using pagination from https://github.com/beberlei/DoctrineExtensions, it works great, at least for me.
Edit: Not sure this will help you, but here's how I did my pagination
Controller
// Create the query
$qb = $this->_em->createQueryBuilder();
$qb->select('p')
->from('Identiti_Entities_Pengguna', 'p');
// Sorting
$qb->addOrderBy('p.' . $input->sort, $input->dir);
$q = $qb->getQuery();
// Pagination
$itemPerPage = 100;
$records = new Zend_Paginator(
new DoctrineExtensions\Paginate\PaginationAdapter($q));
$records->setCurrentPageNumber($input->page)
->setItemCountPerPage($itemPerPage)
->setPageRange(10);
$this->view->records = $records;
View
<?
echo $this->paginationControl($this->records,
'Sliding',
'partials/pagination.phtml');
?>
pagination.html
<?php if ($this->pageCount): ?>
<ul id="pagination-digg">
<li class="previous">Pages: <?=$this->pageCount?></li>
<!-- Previous page link -->
<?php if (isset($this->previous)): ?>
<li class="previous"><a href="<?php echo $this->url(array('page' => $this->previous)); ?>">
< Previous
</a></li>
<?php else: ?>
<li class="previous-off">< Previous</li>
<?php endif; ?>
<!-- Numbered page links -->
<?php foreach ($this->pagesInRange as $page): ?>
<?php if ($page != $this->current): ?>
<li>
<a href="<?php echo $this->url(array('page' => $page)); ?>">
<?php echo $page; ?>
</a>
</li>
<?php else: ?>
<li class="active"><?php echo $page; ?></li>
<?php endif; ?>
<?php endforeach; ?>
<!-- Next page link -->
<?php if (isset($this->next)): ?>
<li class="next">
<a href="<?php echo $this->url(array('page' => $this->next)); ?>">
Next >
</a>
</li>
<?php else: ?>
<li class="next-off">Next ></li>
<?php endif; ?>
</ul>
<?php endif; ?>
You may consider implementing Zend_Paginator_Adapter_Interface.
See ZF docs for more details:
Zend Framework: Documentation: Advanced usage - Zend Framework Manual
Doctrine 2.2 now has a Paginator class. See this link for how to use it with Zend_Framework:
Reply to How to use D2's Paginator with Zend_Paginator

Creating child CMS pages in Magento

I would like to create a subordinate set of CMS pages in Magento so that the breadcrumb navigation at the top of the page looks like this:
Home > Parent CMS Page > Child CMS Page
Even though I can specify a hierarchical relationship with the URL key field, it seems to be that all CMS pages in Magento are listed in the root directory by default:
Home > Child CMS Page
Any ideas?
You are right, there is no hierarchy of CMS pages in Magento. The best solution would be to create a real hierarchy by adding a parent_id to CMS pages and modifying the CMS module to handle nested URLs and breadcrumbs. But that requires a lot of coding.
A quick-and-dirty hack is to modify the breadcrumbs manually on each subpage by adding something like this to the layout update XML:
<reference name="root">
<action method="unsetChild"><alias>breadcrumbs</alias></action>
<block type="page/html_breadcrumbs" name="breadcrumbs" as="breadcrumbs">
<action method="addCrumb">
<crumbName>home</crumbName>
<crumbInfo><label>Home page</label><title>Home page</title><link>/</link></crumbInfo>
</action>
<action method="addCrumb">
<crumbName>myparentpage</crumbName>
<crumbInfo><label>My Parent Page</label><title>My Parent Page</title><link>/myparentpage/</link></crumbInfo>
</action>
<action method="addCrumb">
<crumbName>mysubpage</crumbName>
<crumbInfo><label>My Sub Page</label><title>My Sub Page</title></crumbInfo>
</action>
</block>
</reference>
I had the same problem with breadcrumbs and cms pages a few days ago check here ->
Similar to Anders Rasmussen post I edited every cms page manually
In breadcrumbs.phtml I added a little condition to define if a Page is a CMS page (thanks to Alan Storm) and remove standard crumb(s) and added new crumbs via xmllayout.
<?php
if($this->getRequest()->getModuleName() == 'cms'){
unset($crumbs['cms_page']);
}
?>
xml:
<reference name="breadcrumbs">
<action method="addCrumb">
<crumbName>cms_page_1st_child</crumbName>
<crumbInfo><label>1st child</label><title>1st child</title><link>/1st child/</link></crumbInfo>
</action>
<action method="addCrumb">
<crumbName>cms_page_2nd_child</crumbName>
<crumbInfo><label>2nd child</label><title>2nd child</title></crumbInfo>
</action>
</reference>
hope that helps,
Rito
For enterprise (version 1.12) use this code at following file, location is:
default->template->page->html->breadcrumb.phtml.
<?php
$cms_id = Mage::getSingleton('cms/page')->getPageId();
if($cms_id):
if($_SERVER['REQUEST_URI']) {
$trim_data = substr($_SERVER['REQUEST_URI'],1);
$data = explode('/',$trim_data);
}
$cms_collection = array();
$url_full = '';
$cms_enterprise = '';
foreach($data as $identifier) {
$page_data = Mage::getModel('cms/page')->getCollection()
->addFieldToFilter('identifier', $identifier);
if($page_data) {
foreach($page_data as $single) {
if($single->getContentHeading() != null) {
if($single->getPageId()) {
$cms_enterprise = Mage::getModel('enterprise_cms/hierarchy_node')->getCollection()
->addFieldToFilter('page_id', $single->getPageId());
foreach($cms_enterprise as $single_enterprise) {
$url_full = $single_enterprise->getRequestUrl();
}
}
$cms_collection[] = array($single->getTitle(), $single->getContentHeading(), $url_full );
} else {
if($single->getPageId()) {
$cms_enterprise = Mage::getModel('enterprise_cms/hierarchy_node')->getCollection()
->addFieldToFilter('page_id', $single->getPageId());
foreach($cms_enterprise as $single_enterprise) {
$url_full = $single_enterprise->getRequestUrl();
}
}
$cms_collection[] = array($single->getTitle(), $single->getTitle(), $url_full );
}
}
}
}
$count = count($cms_collection);
$i = 1;
?>
<?php if(count($cms_collection)): ?>
<div class="breadcrumbs">
<ul>
<li>
<a href="<?php echo $this->getUrl() /*Home*/ ?>" title="<?php echo $this->__('Home'); /*Home Title*/ ?>">
<?php echo $this->__('Home'); /*Home Name*/ ?>
</a>
<span>> </span>
</li>
<?php foreach($cms_collection as $key=>$value): ?>
<?php if($i == $count): ?>
<li>
<strong>
<?php echo $value[1]; /*Name*/ ?>
</strong>
</li>
<?php else: ?>
<li>
<a href="<?php echo $this->getUrl().$value[2] /*Identifier*/ ?>" title="<?php echo $value[0] /*Title*/ ?>">
<?php echo $value[1]; /*Name*/ ?>
</a>
<span>> </span>
</li>
<?php endif; ?>
<?php $i++; ?>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<?php else: ?>
<?php if($crumbs && is_array($crumbs)): ?>
<div class="breadcrumbs">
<ul>
<?php foreach($crumbs as $_crumbName=>$_crumbInfo): ?>
<li class="<?php echo $_crumbName ?>">
<?php if($_crumbInfo['link']): ?>
<?php echo $this->htmlEscape($_crumbInfo['label']) ?>
<?php elseif($_crumbInfo['last']): ?>
<strong><?php echo $this->htmlEscape($_crumbInfo['label']) ?></strong>
<?php else: ?>
<?php echo $this->htmlEscape($_crumbInfo['label']) ?>
<?php endif; ?>
<?php if(!$_crumbInfo['last']): ?>
<span>> </span>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
Thanks,
Kashif
This is my solution of the problem. I use custom layout for most of the CMS pages (default/template/page/cmsLayout.phtml) so I heve added following code into the layout file:
<div class="col-main">
<?php
$urlPart=str_replace(Mage::getUrl(),'',Mage::getUrl('', array('_current' => true,'_use_rewrite' => true)));
$urlPart=explode('/',$urlPart);
$string='';
$return='<div class="breadcrumbs"><ul><li class="home">Home<span> / </span></li>';
$count=count($urlPart);
foreach($urlPart as $value)
{
$count--;
$string.='/'.$value;
$string=trim($string, '/');
$pageTitle = Mage::getModel('cms/page')->load($string, 'identifier')->getTitle();
if($count==0)
$return.='<li><strong>'.$pageTitle.'</strong></li>';
else
$return.='<li>'.$pageTitle.'<span> / </span></li>';
}
echo $return.'</li></ul></div>';
?>
<?php echo $this->getChildHtml('global_messages') ?>
<?php echo $this->getChildHtml('content') ?>
</div>
update
-oops- this might be an enterprise feature only
There is a built-in CMS page hierarchy option in Magento.
To turn it on:
System > Configuration > General > Content Management > CMS Page Hierarchy - see here
To organise the hierarchy tree:
CMS > Pages > Manage Hierarchy
To manage the position of a page in the tree, after saving a page, go to its "hierarchy tab" - see the screenshot:
In the example the page "Our culture" is a child of "jobs" and not of the root directory
For Magento Enterprise, I have created an extension to solve this. It uses the built in CMS Hierarchy in the backend. The module is called Demac/BananaBread and shouldn't require any hacks or customization.
Direct download: here
Link to article: http://www.demacmedia.com/magento-commerce/introducing-demac_bananabread-adding-cms-breadcrumbs-from-the-hierarchy-in-magento/
I built a custom block as to generate the crumbs (removing the built-in and replacing with the custom one below in the layout):
namespace Uprated\Theme\Block\Html;
class UpratedBreadcrumbs extends \Magento\Framework\View\Element\Template
{
/**
* Current template name
*
* #var string
*/
public $crumbs;
protected $_template = 'html/breadcrumbs.phtml';
protected $_urlInterface;
protected $_objectManager;
protected $_repo;
public function __construct(
\Magento\Backend\Block\Template\Context $context,
\Magento\Framework\UrlInterface $urlInterface,
\Magento\Framework\ObjectManagerInterface $objectManager,
array $data = [])
{
$this->_urlInterface = $urlInterface;
$this->_objectManager = $objectManager;
$this->_repo = $this->_objectManager->get('Magento\Cms\Model\PageRepository');
$this->getCrumbs();
parent::__construct($context, $data);
}
public function getCrumbs() {
$baseUrl = $this->_urlInterface->getBaseUrl();
$fullUrl = $this->_urlInterface->getCurrentUrl();
$urlPart = explode('/', str_replace($baseUrl, '', trim($fullUrl, '/')));
//Add in the homepage
$this->crumbs = [
'home' => [
'link' => $baseUrl,
'title' => 'Go to Home Page',
'label' => 'Home',
'last' => ($baseUrl == $fullUrl)
]
];
$path = '';
$numParts = count($urlPart);
$partNum = 1;
foreach($urlPart as $value)
{
//Set the relative path
$path = ($path) ? $path . '/' . $value : $value;
//Get the page
$page = $this->getPageByIdentifier($path);
if($page) {
$this->crumbs[$value] = [
'link' => ($partNum == $numParts) ? false : $baseUrl . $path,
'title' => $page['title'],
'label' => $page['title'],
'last' => ($partNum == $numParts)
];
}
$partNum++;
}
}
protected function getPageByIdentifier($identifier) {
//create the filter
$filter = $this->_objectManager->create('Magento\Framework\Api\Filter');
$filter->setData('field','identifier');
$filter->setData('condition_type','eq');
$filter->setData('value',$identifier);
//add the filter(s) to a group
$filter_group = $this->_objectManager->create('Magento\Framework\Api\Search\FilterGroup');
$filter_group->setData('filters', [$filter]);
//add the group(s) to the search criteria object
$search_criteria = $this->_objectManager->create('Magento\Framework\Api\SearchCriteriaInterface');
$search_criteria->setFilterGroups([$filter_group]);
$pages = $this->_repo->getList($search_criteria);
$pages = ($pages) ? $pages->getItems() : false;
return ($pages && is_array($pages)) ? $pages[0] : [];
}
Then used a slightly modified .phtml template to display them:
<?php if ($block->crumbs && is_array($block->crumbs)) : ?>
<div class="breadcrumbs">
<ul class="items">
<?php foreach ($block->crumbs as $crumbName => $crumbInfo) : ?>
<li class="item <?php /* #escapeNotVerified */ echo $crumbName ?>">
<?php if ($crumbInfo['link']) : ?>
<a href="<?php /* #escapeNotVerified */ echo $crumbInfo['link'] ?>" title="<?php echo $block->escapeHtml($crumbInfo['title']) ?>">
<?php echo $block->escapeHtml($crumbInfo['label']) ?>
</a>
<?php elseif ($crumbInfo['last']) : ?>
<strong><?php echo $block->escapeHtml($crumbInfo['label']) ?></strong>
<?php else: ?>
<?php echo $block->escapeHtml($crumbInfo['label']) ?>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
Working fine for me in 2.1