Magento 2
We display product prices both with and without tax in frontend.
By default minimum price and old price is rendered including tax but I have to display minimal price WITHOUT tax.
Any ideas where or how to can change this?
There's no perfect way to do it, best solution I have found is to override the template where the price rendering is happening and use the base amount instead of full amount for "As low as".
My/Theme/Magento_Catalog/templates/product/price/amount/default.phtml
<?php
/**
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
// #codingStandardsIgnoreFile
?>
<?php /** #var \Magento\Framework\Pricing\Render\Amount $block */ ?>
<?php
if ($block->getDisplayLabel() != 'As low as') {
$price = $block->getDisplayValue();
}
else {
$price = $block->getAmount()->getBaseAmount();
}
?>
<span class="price-container <?php /* #escapeNotVerified */ echo $block->getAdjustmentCssClasses() ?>"
<?php echo $block->getSchema() ? ' itemprop="offers" itemscope itemtype="http://schema.org/Offer"' : '' ?>>
<?php if ($block->getDisplayLabel()): ?>
<span class="price-label"><?php /* #escapeNotVerified */ echo $block->getDisplayLabel(); ?></span>
<?php endif; ?>
<span <?php if ($block->getPriceId()): ?> id="<?php /* #escapeNotVerified */ echo $block->getPriceId() ?>"<?php endif;?>
<?php echo($block->getPriceDisplayLabel()) ? 'data-label="' . $block->getPriceDisplayLabel() . $block->getPriceDisplayInclExclTaxes() . '"' : '' ?>
data-price-amount="<?php /* #escapeNotVerified */ echo $price; ?>"
data-price-type="<?php /* #escapeNotVerified */ echo $block->getPriceType(); ?>"
class="price-wrapper <?php /* #escapeNotVerified */ echo $block->getPriceWrapperCss(); ?>"
<?php echo $block->getSchema() ? ' itemprop="price"' : '' ?>>
<?php /* #escapeNotVerified */ echo $block->formatCurrency($price, (bool)$block->getIncludeContainer()) ?>
</span>
<?php if ($block->hasAdjustmentsHtml()): ?>
<?php echo $block->getAdjustmentsHtml() ?>
<?php endif; ?>
<?php if ($block->getSchema()): ?>
<meta itemprop="priceCurrency" content="<?php /* #escapeNotVerified */ echo $block->getDisplayCurrencyCode()?>" />
<?php endif; ?>
</span>
Related
I'm doing slick slider with ul li, and it doesn't work well.
What i mean is it take 2-5 second to load succesfully the slider (some time it take more than that). In that loading time, it look like this:
https://i.stack.imgur.com/kdte5.png
So here is the normal ul li, with out slick slider.
https://i.stack.imgur.com/ebF9m.png
And here is what after i put slick slider in:
https://i.stack.imgur.com/kdte5.png
Sorry because i cant post the direct image in here. I don't have enough reputaion to do that.
So here is the code:
<?php
/**
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
// #codingStandardsIgnoreFile
?>
<?php
/**
* Template for displaying products list widget
*
* #var $block \Gssi\ProductsSlider\Block\Product\ProductsList
*/
?>
<?php if ($exist = ($block->getProductCollection() && $block->getProductCollection()->getSize())):?>
<?php
$type = 'widget-product-grid';
$mode = 'grid';
$image = 'new_products_content_widget_grid';
$title = $block->getTitle() ? __($block->getTitle()) : '';
$items = $block->getProductCollection()->getItems();
$showWishlist = true;
$showCompare = true;
$showCart = true;
$templateType = \Magento\Catalog\Block\Product\ReviewRendererInterface::DEFAULT_VIEW;
$description = false;
?>
<div class="block widget block-products-list <?php /* #escapeNotVerified */ echo $mode; ?>">
<?php if ($title):?>
<div class="block-title">
<strong><?php /* #escapeNotVerified */ echo $title; ?></strong>
</div>
<?php endif ?>
<div class="block-content">
<?php /* #escapeNotVerified */ echo '<!-- ' . $image . '-->' ?>
<div class="products-<?php /* #escapeNotVerified */ echo $mode; ?> <?php /* #escapeNotVerified */ echo $mode; ?>">
<ul class="slick-custom product-items <?php /* #escapeNotVerified */ echo $type; ?>">
<?php $iterator = 1; ?>
<?php foreach ($items as $_item): ?>
<?php /* #escapeNotVerified */ echo($iterator++ == 1) ? '<li class="product-item">' : '</li><li class="product-item">' ?>
<div class="product-item-info">
<a href="<?php /* #escapeNotVerified */ echo $block->getProductUrl($_item) ?>" class="product-item-photo">
<?php echo $block->getImage($_item, $image)->toHtml(); ?>
</a>
<div class="product-item-details">
<strong class="product-item-name">
<a title="<?php echo $block->escapeHtml($_item->getName()) ?>"
href="<?php /* #escapeNotVerified */ echo $block->getProductUrl($_item) ?>"
class="product-item-link">
<?php echo $block->escapeHtml($_item->getName()) ?>
</a>
</strong>
<?php
echo $block->getProductPriceHtml($_item, $type);
?>
<?php if ($templateType): ?>
<?php echo $block->getReviewsSummaryHtml($_item, $templateType) ?>
<?php endif; ?>
<?php if ($showWishlist || $showCompare || $showCart): ?>
<div class="product-item-actions">
<?php if ($showCart): ?>
<div class="actions-primary">
<?php if ($_item->isSaleable()): ?>
<?php if ($_item->getTypeInstance()->hasRequiredOptions($_item)): ?>
<button class="action tocart primary"
data-mage-init='{"redirectUrl":{"url":"<?php /* #escapeNotVerified */ echo $block->getAddToCartUrl($_item) ?>"}}'
type="button" title="<?php /* #escapeNotVerified */ echo __('Add to Cart') ?>">
<span><?php /* #escapeNotVerified */ echo __('Add to Cart') ?></span>
</button>
<?php else: ?>
<?php
$postDataHelper = $this->helper('Magento\Framework\Data\Helper\PostHelper');
$postData = $postDataHelper->getPostData($block->getAddToCartUrl($_item), ['product' => $_item->getEntityId()])
?>
<button class="action tocart primary"
data-post='<?php /* #escapeNotVerified */ echo $postData; ?>'
type="button" title="<?php /* #escapeNotVerified */ echo __('Add to Cart') ?>">
<span><?php /* #escapeNotVerified */ echo __('Add to Cart') ?></span>
</button>
<?php endif; ?>
<?php else: ?>
<?php if ($_item->getIsSalable()): ?>
<div class="stock available"><span><?php /* #escapeNotVerified */ echo __('In stock') ?></span></div>
<?php else: ?>
<div class="stock unavailable"><span><?php /* #escapeNotVerified */ echo __('Out of stock') ?></span></div>
<?php endif; ?>
<?php endif; ?>
</div>
<?php endif; ?>
<?php if ($showWishlist || $showCompare): ?>
<div class="actions-secondary" data-role="add-to-links">
<?php if ($this->helper('Magento\Wishlist\Helper\Data')->isAllow() && $showWishlist): ?>
<a href="#"
data-post='<?php /* #escapeNotVerified */ echo $block->getAddToWishlistParams($_item); ?>'
class="action towishlist" data-action="add-to-wishlist"
title="<?php /* #escapeNotVerified */ echo __('Add to Wish List') ?>">
<span><?php /* #escapeNotVerified */ echo __('Add to Wish List') ?></span>
</a>
<?php endif; ?>
<?php if ($block->getAddToCompareUrl() && $showCompare): ?>
<?php $compareHelper = $this->helper('Magento\Catalog\Helper\Product\Compare');?>
<a href="#" class="action tocompare"
data-post='<?php /* #escapeNotVerified */ echo $compareHelper->getPostDataParams($_item);?>'
title="<?php /* #escapeNotVerified */ echo __('Add to Compare') ?>">
<span><?php /* #escapeNotVerified */ echo __('Add to Compare') ?></span>
</a>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
</div>
<?php echo($iterator == count($items)+1) ? '</li>' : '' ?>
<?php endforeach ?>
</ul>
</div>
<?php echo $block->getPagerHtml() ?>
</div>
</div>
<script>
require([
'jquery',
'slick'
], function ($) {
$(document).ready(function () {
$('.slick-custom').slick({
slidesToShow: 5,
speed: 300,
autoplay: true
});
});
});
</script>
<?php endif;?>
I've try put this in slick slider option, but doesn't work at all:
slide: 'li',
track: function() { return $(this).children('product-item'); },
EDIT 1:
After 6 hours looking for the answer, i've found the reason (or atleast i thing its the reason :D ).
Okay, so i guest its because Magento wasn't load the javascript in time. I mean it take a while to load this slick slider javascript.
Right now, it take about 1-2 seconds for slick slider called successfully. And in that 1-2 seconds, it will render that problem out (just like in picture 2).
Ok so the problem is still there, if you guys have any suggestion, please tell me. Thanks alot :)
EDIT 2:
I'm follow #HoangHieu solution, but doesn't seem to work
Here is what i've done :
<div class="products-<?php /* #escapeNotVerified */ echo $mode; ?> <?php /* #escapeNotVerified */ echo $mode; ?>" data-mage-init='{ "slick": {} }'>
<ul class="slick-custom product-items <?php /* #escapeNotVerified */ echo $type; ?>">
// some li
<li>...</li>
</ul>
</div>
I've added data-mage-init='{ "slick": {} }' in the . I called "slick" because that is what i define slickSlider in requirejs-config.js
var config = {
map: {
'*': {
slick: 'Gssi_ProductsSlider/js/lib/slick',
}
}
};
EDIT 3:
Okay so here is what i've done til now after #HoangHieu solution:
<ul class="slick-custom product-items <?php /* #escapeNotVerified */ echo $type; ?>" data-mage-init='{ "callSlick": {} }'>
//some li
</ul>
call-slick.js
define(['jquery', 'slick'], function ($) {
"use strict";
return function (config, element) {
let defaultConfig = {
infinite: true,
slidesToShow: 4,
speed: 300,
autoplay: true,
arrows: false,
dots: false,
responsive: [
{
breakpoint: 1024,
settings: {
slidesToShow: 4
}
},
{
breakpoint: 600,
settings: {
slidesToShow: 3
}
},
{
breakpoint: 480,
settings: {
slidesToShow: 2
}
}
]
};
$(element).slick($.extend({}, defaultConfig, config));
};
});
requirejs-config.js
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
var config = {
map: {
'*': {
slick: 'Gssi_ProductsSlider/js/lib/slick',
callSlick: 'Gssi_ProductsSlider/js/call-slick'
}
}
};
Some widget will load after the page loaded. By if you search in HTML about <!-- BLOCK -- that is https://devdocs.magento.com/guides/v2.1/extension-dev-guide/cache/page-caching/private-content.html
Flow here
Html loaded --> KnoutJs UIComponent get Prefix BLOCK to load --> Load Block HTML using AJAX --> Append to BODY.
that means you can't apply Slick Slider by using simple ways. Using Component instead
<div data-mage-init="{'slickSlider':{}}">
<ul>
<li></li>
</ul>
</div>
See more here: https://devdocs.magento.com/guides/v2.0/javascript-dev-guide/javascript/js_init.html
Update 2: I think you didn't read my related documents. I will give you an example.
1: My Product List Widget Template.
<ol class="product-items <?= /* #escapeNotVerified */ $type ?>" data-mage-init='{"callSlick":{}}'>
<?php $iterator = 1; ?>
<?php foreach ($items as $_item): ?>
<?= /* #escapeNotVerified */ ($iterator++ == 1) ? '<li class="product-item">' : '</li><li class="product-item">' ?>
<div class="product-item-info">
<a href="<?= /* #escapeNotVerified */ $block->getProductUrl($_item) ?>" class="product-item-photo">
<?= $block->getImage($_item, $image)->toHtml() ?>
</a>
<div class="product-item-details">
<strong class="product-item-name">
<a title="<?= $block->escapeHtml($_item->getName()) ?>"
href="<?= /* #escapeNotVerified */ $block->getProductUrl($_item) ?>"
class="product-item-link">
<?= $block->escapeHtml($_item->getName()) ?>
</a>
</strong>
</div>
</div>
<?= ($iterator == count($items)+1) ? '</li>' : '' ?>
<?php endforeach ?>
</ol>
Requiejs-config.js
var config = {
map: {
'*': {
slickSlider: 'Magento_Catalog/js/slick', //Slick slider libary
callSlick: 'Magento_Catalog/js/call-slick'
}
}
};
call-slick.js
/**
* Created by Hidro Le.
* Job Title: Magento Developer
* Date: 27/08/2018
* Time: 10:16
*/
define(['jquery', 'slickSlider'], function ($) {
"use strict";
return function (config, element) {
let defaultConfig = {
infinite: true,
slidesToShow: 3,
slidesToScroll: 3
};
$(element).slick($.extend({}, defaultConfig, config));
};
});
**Update 2: ** The result exactly example.
Update 3: If you are work with your team. Please recheck page Style Sheet, Create new page content with an empty layout to make sure didn't have any custom CSS affected on your code.
This is driving me nuts, I created a module with a helper:
namespace MyNamespace\MyModule\Helper;
class Data extends \Magento\Framework\App\Helper\AbstractHelper
{
protected $registry;
public function __construct
(
\Magento\Framework\Registry $registry,
\Magento\Eav\Api\AttributeSetRepositoryInterface $attributeSet
) {
$this->registry = $registry;
$this->attributeSet = $attributeSet;
}
public function getTitle()
{
$this->product = $this->registry->registry('product');
$product_name = $this->product->getName();
$attributeSetRepository = $this->attributeSet->get($this->product->getAttributeSetId());
if ($attributeSetRepository->getAttributeSetName() == "Default Engine Component"){
$engine = $this->product->getAttributeText('engine_select');
if (!is_array($engine)){
return "$engine $product_name";
}
}
return $product_name;
}
}
...and this works as it should. Then I added the following to:
/app/design/frontend/vendor/theme/Magento_Catalog/layout/catalog_product_view.xml
<referenceBlock name="page.main.title">
<action method="setPageTitle">
<argument name="title" xsi:type="helper" helper="MyNamespace\MyModule\Helper\Data::getTitle"></argument>
</action>
</referenceBlock>
...but it changes nothing on the product page. I know it's getting called as I can echo out the vars and they show at the top of the page, but it seems that the XML isn't doing what I hoped it would.
Anyone got any ideas?
So, tried multiple variations of achieving what I wanted but in the end, I created a template under Magento_Catalog/templates/product (in my theme), which was based of the magento-theme title.phtml and then modified the page.main.title block in the catalog_product_view layout file.
The template code may look a bit odd (getAttribute and then getAttributeText) but there's no error handling for getAttributeText and with getAttribute, if an attribute has multiple values, it's returned in a string, not an array like getAttributeText. It would have been nicer if I could have made sure the value was always present by checking which attribute set was being used but although getAttributeSetId is part of the product model, it's not available in the product/view interceptor and tbh, I've given up on trying to figure out how all that works!
Anyway, this has taken far more hours than I'd care to admit to figure out so here's the code, hope it helps someone!
Template:
<?php
$product = $block->getProduct();
$product_name = $product->getName();
$attr_exists = $product->getResource()->getAttribute('attr_code');
$title = $product_name;
$cssClass = $block->getCssClass() ? ' ' . $block->getCssClass() : '';
if ($attr_exists){
$attr_name = $product->getAttributeText('attr_code');
if (!is_array($attr_name)){
$title = "$attr_name $product_name";
}
}
?>
<?php if ($title): ?>
<div class="page-title-wrapper<?= /* #escapeNotVerified */ $cssClass ?>">
<h1 class="page-title"
<?php if ($block->getId()): ?> id="<?= /* #escapeNotVerified */ $block->getId() ?>" <?php endif; ?>
<?php if ($block->getAddBaseAttributeAria()): ?>
aria-labelledby="<?= /* #escapeNotVerified */ $block->getAddBaseAttributeAria() ?>"
<?php endif; ?>>
<?= /* #escapeNotVerified */ $title ?>
</h1>
<?= $block->getChildHtml() ?>
</div>
<?php endif; ?>
Layout:
<block name="page.main.title" class="Magento\Catalog\Block\Product\View" template="Magento_Catalog::product/product-h1.phtml" />
Is it possible to reuse somehow magentos 2 add to cart form in a custom module? I have in tab all child products of current product and I want to allow customers to add to cart products so thats how looks my code at this status
<?php
if ($currentProduct = $block->getCurrentProduct()) {
$variants = $block->getVariants($currentProduct);
if($variants) { ?>
<ul id="product-variants">
<?php foreach ($variants as $_product) : ?>
<li>
<form>
<?php echo $_product->getName(); ?>
SKU: <?php echo $_product->getSku(); ?>
Brutto: <?php echo $_product->getPrice(); ?>
<input type="text" placeholder="Stück">
<button>Add to cart</button>
</form>
</li>
<?php endforeach; ?>
</ul>
<?php };
}
?>
you can add button in custom phtml file as follow, I have done this in custom module
In your block file
use Magento\Catalog\Block\Product\ListProduct;
<?php
public function __construct(
\Magento\Backend\Block\Template\Context $context,
\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
\Magento\Catalog\Block\Product\ListProduct $listProductBlock,
array $data = []
) {
parent::__construct($context, $data);
$this->_productCollectionFactory = $productCollectionFactory;
$this->listProductBlock = $listProductBlock;
}
public function getProductCollection()
{
/** #var $collection \Magento\Catalog\Model\ResourceModel\Product\Collection */
$collection = $this->_productCollectionFactory->create()->addAttributeToSelect('*')->load();
return $collection;
}
public function getAddToCartPostParams($product)
{
return $this->listProductBlock->getAddToCartPostParams($product);
}
?>
get productlist in view file
<?php
const PARAM_NAME_BASE64_URL = 'r64';
const PARAM_NAME_URL_ENCODED = 'uenc';
use Magento\Framework\App\Action\Action;
$_productCollection = $block->getProductCollection();
?>
<?php foreach ($_productCollection as $_product): ?>
<?php $postParams = $block->getAddToCartPostParams($_product); ?>
<?php echo $_product->getName()?>
<form data-role="tocart-form" action="<?php /* #escapeNotVerified */ echo $postParams['action']; ?>" method="post">
<input type="hidden" name="product" value="<?php /* #escapeNotVerified */ echo $postParams['data']['product']; ?>">
<input type="hidden" name="<?php /* #escapeNotVerified */ echo Action::PARAM_NAME_URL_ENCODED; ?>" value="<?php /* #escapeNotVerified */ echo $postParams['data'][Action::PARAM_NAME_URL_ENCODED]; ?>">
<?php echo $block->getBlockHtml('formkey')?>
<?php $storeManager = \Magento\Framework\App\ObjectManager::getInstance()->get('Magento\Store\Model\StoreManagerInterface'); ?>
<button type="submit"
title="<?php echo $block->escapeHtml(__('Add to Cart')); ?>"
class="action tocart primary">
<span><?php /* #escapeNotVerified */ echo __('Add to Cart') ?></span>
</button>
</form>
<?php endforeach;?>
I trying use zend paginator in my project.
And i have problem-when i trying use paginator in news controller, i have links in paginator on index controller!
<?php
class NewsController extends Zend_Controller_Action
{
/**
*
* #var Model_News_Gateway
*/
protected $_newsGateway;
protected $_newsPerPage = 10;
public function init()
{
$this->_newsGateway = new Model_News_Gateway();
}
public function indexAction()
{
$crit = new ExtZF_Model_Criteria();
$crit->addWhere('active', true);
$crit->addDescOrderBy('publish_date');
$paginator = new Zend_Paginator($this->_newsGateway->getPaginatorAdapter($crit));
$paginator->setCurrentPageNumber($this->_getParam('page', 0));
$paginator->setItemCountPerPage($this->_newsPerPage);
$this->view->paginator = $paginator;
}
In view
$this->paginationControl($this->paginator, 'Sliding', '_partials/paginator/default.phtml');
And in default
<?php if ($this->pageCount && count($this->pagesInRange) > 1): ?>
<!--noindex-->
<div class="paginationControl">
(<?= $this->firstItemNumber ?>-<?= $this->lastItemNumber?>/<?= $this->totalItemCount ?>)
<?php if (isset($this->previous)): ?>
<a href="<?php echo $this->url(array('page' => $this->previous)); ?>">
< <?= $this->translate('previous') ?>
</a> |
<?php else: ?>
<span class="disabled">< <?= $this->translate('previous') ?></span> |
<?php endif; ?>
<?php foreach ($this->pagesInRange as $page): ?>
<?php if ($page != $this->current): ?>
<a href="<?php echo $this->url(array('page' => $page)); ?>">
<?php echo $page; ?>
</a> |
<?php else: ?>
<?php echo $page; ?> |
<?php endif; ?>
<?php endforeach; ?>
<?php if (isset($this->next)): ?>
<a href="<?php echo $this->url(array('page' => $this->next)); ?>">
<?= $this->translate('next') ?> >
</a>
<?php else: ?>
<span class="disabled"><?= $this->translate('next') ?> ></span>
<?php endif; ?>
</div>
<!--/noindex-->
<?php endif; ?>
I am trying use one default paginator for don't same controllers, but i always have links in paginator like /index/index/page/2.
I need links like /news/index/page/2
But i always have links /index/index/page/2
And i in news controller now. I don't understand why it don't work.
<?
//Ужасный хак, мне стыдно за него
$controller = Zend_Controller_Front::getInstance()->getRequest()->getControllerName();
function replaceController ($search, $replace, $text)
{
$pos = strpos($text, $search);
$secondPos =strpos ($text, $search, $pos+1);
if ($secondPos !== false) {
return $pos !== false ? substr_replace($text, $replace, $pos, strlen($search)) : $text;
} else {
return $text;
}
}
?>
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