how to call functions/methods within CMS block or page? - magento

We are trying to make all our blocks and pages static so that designer or anyone else can easily change the content or design of the website, however. There is a feature that uses our own custom module. So, the template that we want to make static is calling methods out of our custom block, for example,
<!--some html code-->
.....
<?php $this->helpMeBePartOfCMS(); ?>
.....
<!--some html code-->
How do i incorporate these method calls inside cms block or page?
Thank you

The CMS system makes it easy to include custom blocks (or widgets in Enterprise), but not so easy to make method calls. This is because the templates are never parsed as PHP, so you cannot just include a PHP tag.
Why don't you define a custom block to accomplish this? If that won't work, please provide a little more detail about what you're actually trying to include, so that we can troubleshoot further.
Hope that helps!
Thanks,
Joe
Since CMS block templates are not parsed as PHP code, there's no way to inject a call as you are describing. However, all classes descending from Mage_Core_Block_Abstract have the ability to call child and parent blocks. Use one of these methods to do what you are looking for from the block directly:
getParentBlock
getChild
getSortedChildren

there is a way that you call these php codes in any phtml file (create a new and save any where in your templates) then call that phtml file in your cms page as a block (which we usually do for calling blocks)

Related

How to include hooks in CMS pages?

I've created a custom hook, so that I can include my custom module in any .tpl file by a single line: {hook h='calcSubstrate'}.
However, I can't use it in CMS page, at least not by using the admin panel - including smarty code in a CMS page won't render, the code would appear just as it is, as a text: {hook h='calcSubstrate'}.
Alternatively, if that would be easier/faster - how can I choose on which pages my module would appear?
The editor for CMS page won't recognize any Smarty code. To include hooks in chosen articles/pages, I can think of two options:
Include the hook in the template (cms.tpl), and check for the id of the current page to conditionally display the module. The list of the page ids can be made as the module's configuration.
Build a module to add functionality similar to Wordpress's shortcode to the CMS content. I do this with module instead of overriding the CmsController class, hence I have to display the content with {$cms->content|module}. You can look at the simplified code here for inspiration: https://gist.github.com/tungd/cef0ca1ac1063c1ee90b. Of course you can make it more generic like Wordpress, by having only one Smarty modifier do_shortcode that does everything (just like Wordpress's do_shortcode function).
Last time I did this it was because my client want to put slideshows in some CMS pages, and I chose the second approach because it gives a lot of flexibility about when the module is displayed and where it is displayed between the content. For something else, for example Contact Form, or Map, this would be overkill and the first approach is better.

Calling Models in Magento Templates

I am currently working on integrating HTML cuts into Magento's template, however, I am just a little stumped on the structure of Magento itself. I want to list all of the categories inside a custom template in the 'navigation/left'.phtml file. The following accepted answer Magento: Display sub-category list seems to do what I need to do, however,I don't feel comfortable in calling a model inside of a view files as in MVC, which the accepted answer has done.
Is there a better way of putting this in another section of Magento, or perhaps a custom block which extends the Block_Catalog_Product_List class would be a better way of retrieving the categories?
Thanks
The simplest way to do it is to create a module with a helper inside it, that returns the data you need. Then in the template file call this:
$data = Mage::helper('myhelper')->getCategoryList();
//do your magic with $data
There is no point in overriding blocks unless there is no other solution.

Magento call block for specific product in list.phtml

I want to print some additional data for each product on list.phtml that will depend on the product. For example, print html with New and Sale labels for each product (this is just an example). I want to somehow separate logic from .phtml file and remain in phtml just a call for it. What is the best way to achieve it? Also I want to minimize overriding core files and make it more independent.
My ideas are:
Create my own block, create and call it in .phtml and pass there my
product with setData:
$this->getLayout()->createBlock("namespace/block")->
setTemplate("path/to/template")->setData('product', $_product)
and then call getProduct() inside my block .php file. But for some reasons that doesn't work.
The best-looking solution for me, but not sure if it's allowed. Create new block in layout files and call it with getChildHtml('block_name'). But I don't know how to pass there current product or how to make it to be able to access through $this inside my .php file.
Override product block and add my own methods like getRibbons(). The worst solution for me because this will requre html writing in .php block and will override core block.
I'm pretty new to magento, maybe I am missing some basic concepts?
Extend your Product Block PHP and add new methods you want in it. Then in your module.xml where you are referencing core Product Block, replace it with your newly created Block.
Now, from PHTML files you can easily call the PHP block's methods using $this

Magento - is a block always needed for a widget?

I just started to develop Magento widgets and thereby I came to this problem/question:
It is possible to tell a Magento widget not to use a block-class and directly render a template file?
Thanks a lot
Block is needed. If you don't want to create a new block, just give block type as cms/block. Remember, in your phtml template files, then you will not have your custom functions call by using $this (as $this references to Block).

how to apply css class on body tag using c# files

I'm using ASP.NET MVC3 with razor engine.I want to apply css class on body tag according to page call.
I want to add class name in child page and it will affect on layout page which has body tag.
and don't want to use jquery because it execute after page render.
How can i do this?
While you may have full control of the HTML a solution was what was needed so here is one ;-)
In the _layout.cshtml page
<body class="#RenderSection("BodyClass", false)">
This will look for a section in all the child pages but says don't worry if it can't find one
Then in your child views just do this
#section BodyClass {productList}
Keep it on one line and then the outputted HTML will look fine, also you can then build up the class names as well.
#section BodyClass {productList generic}
This idea goes perfect with DOM-Ready page specific code, why not checkout
http://paulirish.com/2009/markup-based-unobtrusive-comprehensive-dom-ready-execution/
Or my extended version here
https://github.com/AaronLayton/H5BP-Core
My way lets you do page specific code, but allows you to keep all of the Javascript in separate pages so each page becomes easily manageable. The final step would be to concatenate and minify all the JS into 1 file ;-)
Aaron's answer above works great for MVC 3, but I found that MVC 4 chokes on the single line section statement:
#section BodyClass {productList}
Instead, you need to use:
#section BodyClass {#("productList")}
First of all jQuery's .ready function executes after the DOM is available so it's the optimal moment to start interaction with your page's elements. ( http://api.jquery.com/ready/ ) If you experience a behavior that results in styles 'flicker' you may wan't to apply display:none to body element, and removing it after you css class has been applied.
but if you really don't want to use jQuery you should consider either making a variable to hold your css class name as a part of a viewmodel your controller will be sending to Views, or going with ViewBag.CssClass that should be declared in each of your controller's actions (or in base controller's OnActionExecuting method.
Thing to consider here is understanding and following MVC pattern, where View and Business Logic should be separated. So in my opinion you should rather avoid involving controllers in view building process.
It's much easier to simply put the following in your main layout
<body class="#ViewBag.BodyClass">
Then in the content pages put:
#{
ViewBag.BodyClass = "myClass";
}
Problem solved!

Resources