Display multiple products on same page in Magento - php

I have a module that responds to an Ajax request. I'm attempting to have it render multiple products and get the resulting HTML. My controller is code is below. I hard coded the IDs for testing purposes.
$id = 52986;
foreach ($ids as $id) {
Mage::helper('catalog/product')->initProduct($id, $this);
$this->loadLayout();
$output[] = $this->getLayout()->getOutput();
Mage::unregister('current_product');
Mage::unregister('product');
}
print_r($output);
I assumed each product rendering in a foreach would independently render each one (i.e. A 'new' layout would be created for each render). Clearly I don't fully understand how the layout system works. Thus I have two questions.
1) How can I get the rendered HTML of each product?
2) Why doesn't rendering the layout work the way I expect it to?
For related info, this is the layout XML I'm using
<?xml version="1.0"?>
<layout version="0.1.0">
<shopthelook_ajax_index>
<update handle="catalog_product_view" />
<remove name="html_calendar" />
<reference name="root" output="toHtml">
<action method="setTemplate"><template>shopthelook/wrapper.phtml</template></action>
</reference>
<reference name="product.info">
<action method="setTemplate"><template>catalog/product/view.phtml</template></action>
</reference>
<reference name="product.info.media">
<action method="setTemplate"><template>catalog/product/view/media.phtml</template></action>
</reference>
<reference name="product.info.options.configurable">
<action method="setTemplate"><template>catalog/product/view/type/options/configurable.phtml</template></action>
</reference>
</shopthelook_ajax_index>
</layout>

First of all, update your layout xml file:
<?xml version="1.0"?>
<layout>
<shopthelook_ajax_index>
<remove name="right"/>
<remove name="left"/>
<reference name="content">
<block type="shopthelook_ajax/response" template="shopthelook_ajax/response.phtml" />
</reference>
</shopthelook_ajax_index>
</layout>
It basically tells Magento to add new output (block) to your controller. Now you need to create this block class in your module (app/code/local/Shopthelook/Ajax/Block/Response.php):
class Shopthelook_Ajax_Block_Response
extends Mage_Core_Block_Template
{
public function getCollection()
{
$productIds = array(52986, 52987, 52988);
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->addAttributeToFilter('entity_id', array('in' => $productIds));
$collection->addAttributeToSelect('*');
return $collection;
}
}
and create a template file (app/design/frontend/base/default/template/shopthelook_ajax/response.phtml:
<?php $_collection = $this->getCollection(); ?>
<ul class="products">
<?php foreach ($_collection as $_product) { ?>
<li>
<span class="product-name"><?php echo $_product->getName() ?></span>
...
</li>
<?php } ?>
</ul>
After this just update your controller to render its layout:
public function ajaxAction()
{
$this->loadLayout()->renderLayout();
}
The action will load merged layout xml file and find the handles depending on your module/controller/action name (in your case shopthelook_ajax_index). Then it will create and render your block using selected template. In the template getCollection method is called which creates a collection of selected products.
Not sure if the code is 100% correct because I can't test it at the moment but the architecture & principles should be OK.

Related

magento2 Element 'referenceContainer': The attribute 'name' is required but missing

<referenceBlock name="breadcrumbs" remove="true" />
<referenceContainer name="page.top">
<block class="Burstonline\EverCrumbs\Block\Evercrumbs" name="crumbs" as="crumbs" template="Magento_Catalog::breadcrumbs.phtml" />
</referenceContainer>
magento 2 breadcrumbs show error
1 exception(s):
Exception #0 (Magento\Framework\Config\Dom\ValidationException): Element 'referenceContainer': The attribute 'name' is required but missing.
Line: 1557
Exception #0 (Magento\Framework\Config\Dom\ValidationException): Element 'referenceContainer': The attribute 'name' is required but missing.
Line: 1557
Hi #aaron seems like you tried to remove breadcrumbs and add your custom breadcrumbs, in order to solve this issue, You have to change referenceBlock to and referenceContainer.
<referenceContainer name="breadcrumbs" remove="true" />
this will fix your error.

Passing empty model to vue type casting error

I have empty object ($attributes array is empty) and i pass it to component in blade like:
<example :box="{{ $box }}" > </example>
My props in component are:
box: {
type: Object,
required: true
},
I got an error Invalid prop: type check failed for prop "box". Expected Object, got Array.
But if I do e.g. $box->id = null in Controller everything is OK. Is there another way to solve this, not adding extra code?
EDIT:
controllers action has:
return view( 'my_view' )->with('box', new Box());
In html output I get :box="[]". And if I set $box->id = null output is like :box="{"id":null}"
Blade template:
<example :box="{{ json_encode($box) }}" > </example>
component vue:
<template>
<div>
{{box}}
</div>
</template>
<scipt>
export default{
props['box']
}
</script>
I think you can define default value of props.
Please check Vue.js Document: Props.

How to get value of passed parameter in controller by Block in magento?

I have passes value from controller like
{{block type="test/test" name="test123" catstatus="xyz" template="storelocator/abc.phtml" }}
i am trying to get value of catstatus on abc.phtml page by
$this->getData('catstatus');
i am able to get this on the phtml page
but I am not getting blankstring when get this value on my indexcontroller.php
Please suggest a possible solution.
Please refer below code
//Loading current layout
$this->loadLayout();
//Creating a new block
$block = $this->getLayout()->createBlock(
'Mage_Core_Block_Template',
'test_block_name',
array('template' => 'page/html/testblock.phtml')
);
$this->getLayout()->getBlock('content')->append($block);
//Now showing it with rendering of layout
$this->renderLayout();

removing footer from specific view in ZF2

How can I remove just the footer from a specific view in ZF2. I have tried
$View->setTerminal(true);
return $view;
but it makes the links in the top nav bar inactive. Thanks
You could change your base layout for that particular action.
for example, your main layout may be like this example:
layout.phtml
<?php echo $this->doctype(); ?>
<html lang="en">
<head>
<?php echo $this->headTitle($this->translate('TITLE'))->setSeparator(' - ')->setAutoEscape(false) ?>
</head>
<body>
....
<?php echo $this->partial('footer') ?>
</body>
</html>
You can simple make a duplicate layout, but without the footer partial included (or how ever you are including the footer partial/view etc)
you would then tell your action to use a different base layout:
Controller.php
public function testAction()
{
/**
* Now we use the base with no footer
*/
$this->layout('layout/no-footer-layout');
// identical to below, a shortcut
//$this->layout()->setTemplate('layout/no-footer-layout');
return new ViewModel(array(/** etc **/));
}

Is there a way to have a navigation entry with no link in zend navigation?

I'm sure my question is pretty straight forward, and I've been looking for an answer to this, but I can't seem to make it work. I want to do something like this:
<?xml version="1.0" encoding="UTF-8"?>
<configdata>
<dashboard>
<label>Dashboard</label>
<controller>dashboard</controller>
<action>index</action>
<module>global</module>
</dashboard>
<bills>
<label>Bills</label>
<pages>
<create-bill>
<label>Create New Bill</label>
<controller>bill</controller>
<action>create</action>
<module>global</module>
</create-bill>
</pages>
</bills>
</configdata>
Please note that in the <bills> section, I want to have a category with just a label, that way when I add styling later, I can hover over "Bills" and "Create New Bill" and other links will be shown, but clicking on "Bills" shouldn't do anything because it's just a category header.
I hope that makes sense.
You must specify a type for your page otherwise Zend_Navigation will throw an exception. In cases like yours I always use a Zend_Navigation_Page_Uri as page type and specify its uri to #. To apply this to your config file you could do this
<bills>
<label>Bills</label>
<uri>#</uri>
<pages>
<create-bill>
<label>Create New Bill</label>
<controller>bill</controller>
<action>create</action>
<module>global</module>
</create-bill>
</pages>
</bills>
The generated markup still contains a link but it will not point anywhere.
Moreover, since you need to bind some javascript to it in order to show the menu, you could even disable it by returning false in the click handler for that links.
In order to attach javascript callbacks (or some css) to that kind of link you may find useful to attach a class to those links. Within the same configuration file, you could with this code
<bills>
<label>Bills</label>
<uri>#</uri>
<class>fakelink</class>
<pages>
<create-bill>
<label>Create New Bill</label>
<controller>bill</controller>
<action>create</action>
<module>global</module>
</create-bill>
</pages>
</bills>
In this case the generated markup would be
<li class="fakelink>
Bills
<ul>submenu here</ul>
</li>
and you could easily select that kind of links with a javascript library. For example with jQuery you could do this:
$(function() { $('.fakelinks > a').click(function () { return false; }); });
There is actually another way to solve this.
You can set custom properties on all Zend_Navigation_Page just by defining extra configuration options in your xml/array/...
Then by using a dedicated partial to render your menu/breadcrumbs you can perfectly skip rendering the <a> tag or render a completely different markup based on these properties.
<!-- ... -->
<page1>
<label>Page 1</label>
<uri>page1</uri>
<link>false</link> <!-- Custom property -->
<pages>
<page1_1>
<label>Page 1.1</label>
<uri>page1/page1_1</uri>
</page1_1>
<page1_2>
<label>Page 1.2</label>
<uri>page1/page1_2</uri>
</page1_2>
<page1_3>
<label>Page 1.3</label>
<uri>page1/page1_3</uri>
</page1_3>
</pages>
</page1>
<!-- ... -->
Note: I'm using the breadcrumbs example here but most of the Navigation View_Helpers have a setPartial() method, including the menu helper.
Then in your view script or layout you just specify that your breadcrumbs helper needs to use a partial.
<?php
echo $this->navigation()->breadcrumbs()->setPartial('my_breadcrumbs.phtml');
And in your partial you loop over the pages in year breadcrumb trail and check the custom properties for each page.
<?php
foreach($this->pages as $page)
{
$properties = $page->getCustomProperties();
// Check if we need to render the link tag
if($properties['link'] !== false){
echo '<a href="' . $page->getHref() . '">';
}
// Render the label
echo $page->getLabel();
// And check if we need to render the closing tag
if($properties['link'] !== false){
echo '</a>';
}
}
Note: By using a partial you'll lose some default functionality of the Breadcrumb View_Helper like setLinkLast, setSeparator, ... but these shouldn't pose too much of a problem.
If you're happy for your category labels to be spans then just specifying an empty URI will do the job. Zend_View_Helper_Navigation_Menu::htmlify() is what renders a Zend_Navigation_Page:
/**
* Returns an HTML string containing an 'a' element for the given page if
* the page's href is not empty, and a 'span' element if it is empty
*
* Overrides {#link Zend_View_Helper_Navigation_Abstract::htmlify()}.
*
* #param Zend_Navigation_Page $page page to generate HTML for
* #return string HTML string for the given page
*/
public function htmlify(Zend_Navigation_Page $page)
Example output:
<ul class="navigation">
<li>
<span id="menu-staff">Staff</span>
<ul>
<li>
Book Holiday
</li>
<li>
View Booked and Remaining Holiday
</li>
</ul>
</li>
</ul>
I went about it in a different way:
nav:
User:
label: Account Services
uri: #fakeUri
Then in my template code:
<?php foreach ($navSettings as $navSetting): ?>
<?php if ('#fakeUri' === $navSetting->getUri()): ?>
<?php echo $navSetting->getLabel() ?>
<?php else: ?>
<a href="<?php echo $navSetting->getUri() ?>"><?php echo $navSetting->getLabel()) ?>
<?php endif ?>
<?php endforeach ?>
<page_bills>
<label>Bills</label>
<type>uri</type>
<pages>
</pages>
</page_bills>

Categories