Hi everyone, today I will show you that there's actually nothing quantum-physical about the creation of your own Avactis template tag. Sometimes you're eager to include some info from Avactis database into a template but there's just no suitable tag around! And what you're supposed to do in this situation? Well, with a bit of luck, you can just add it to the system yourself and profit.
WARNING! This can bring down your live store!!! Always test it on your local copy first!!!As an example, let us make our brand new
NavigationBarCustom() show its root category name in its title instead of just static label. When we do that, we'll be able to easily insert a dozen of navigation bars into a page and they all will have different titles. Pretty cool huh?
1) Find the viewEverything you see on Avactis store pages is generated by so called
views. Views are basically PHP classes with a special structure. If you look at the contents of
avactis-system/modules directory, you will see a lot of folders. They even have understandable names! Those are the modules that are available to the system (that is, to you, as the store owner). And practically every module has a subfolder named
views. The subfolder contains PHP scripts that define classes for outputting the module contents in different situations and places.
Example:Module
related_products has two views:
- related_products_cz.php that displays the "Related Products" block below the main product info on the product details page, and
- rp_links_list_az.php that outputs the "Related Products" tab in Edit Product window in Admin Area.
So, where is
NavigationBarCustom's folder? Apparently it is somehow used for navigation among millions of products you're selling all around the world, and so it is logical to look for it in
catalog. But even if it wasn't that obvious, you could always ask your best friend:
Find in Files! Search for "NavigationBarCustom" as a whole word, case-sensitive, in
*.php files in
avactis-system folder including subfolders, and one of the matches will be "class NavigationBarCustom"—just what the doctor ordered.
2) Register the new attributeOnce you get into the view class, you're ready to hack. But wait! Even though you're only going to change one little template,
the whole application should actually be aware of the new tag to properly render it. So, in the function
output() (which is inevitably present in every view class), find the call of
$application->registerAttributes(). For example, that's how it looks in
avactis-system\modules\catalog\views\navigation-bar-custom-cz.php:
$application->registerAttributes(array('Local_NestedCategories'));
Looks like the view class is not going to use very much data in its output.
So, what you have to do now is just add
your tag of desire to the array:
$application->registerAttributes(array('Local_NestedCategories', 'Local_RootCID'));
You can actually put any name you like in there. And it shouldn't start from "Local_" at all, it is just a fancy sign of the fact that the tag will be used just in a single view/template, and it not planning to take over the world.
3) Write the rendererOK, now the application recognizes the new tag and when it suddenly encounters it in a template, it won't die with a FATAL ERROR on its face. But it still won't be able to render (provide some HTML for) it either, because, well, it doesn't know how!
So the next thing we should to is to go down the code and find a function named
getTag($tag), and inside the function we should find the
switch statement. That's where all the magic happens!
Here's how it looks in the same
avactis-system\modules\catalog\views\navigation-bar-custom-cz.php:
switch ($tag)
{
case 'Local_Items':
$value = $this->outputCatalogNavigatorTree();
break;
case 'Local_NestedCategories':
$value = $this->outputCatalogNavigatorTree($this->_Current_Category->getCategoryTagValue('id'));
break;
default:
list($entity, $tag) = getTagName($tag);
if ($entity == 'category' && is_object($this->_Current_Category))
{
$value = $this->_Current_Category->getCategoryTagValue($tag);
}
break;
}
Wow, that's a lot of code if you ask me! But don't worry, we don't need it all. What we really need is to
carefully add one more
case to the function—the
case that will be rendering our dear new tag:
switch ($tag)
{
case 'Local_Items':
$value = $this->outputCatalogNavigatorTree();
break;
case 'Local_NestedCategories':
$value = $this->outputCatalogNavigatorTree($this->_Current_Category->getCategoryTagValue('id'));
break;
case 'Local_RootCID':
$value = $this->settings['TREE_ROOT'];
break;
default:
list($entity, $tag) = getTagName($tag);
if ($entity == 'category' && is_object($this->_Current_Category))
{
$value = $this->_Current_Category->getCategoryTagValue($tag);
}
break;
}
The easiest way to add a new renderer for your tag is of course to copy-and-paste an existing
case-break block and then
carefully edit the expression assigned to
$value variable. Now
that's the place where you can release your full hacker potential and write any PHP you ever wanted to get that
$value (HTML string, actually). It is preferable, however, to keep it simple and fast, as this piece of code will be executed quite often.
In the example above, I just took an element of
$settings array that gets initialized earlier in the code. And most of the time that is enough: just look around the code and see what is made available for you, which variables you can read, which methods return the data you need for the tag.
4) Insert the new tag in the templateNow that the application knows about the tag and can render it, it's time to use it in a real-world template!
Open the template:
avactis-themes\system\catalog\navigation-bar-custom\default\navigation-container.tpl.htmlWhat is the code that outputs the block's title? It's pretty boring:
<h1><?php Label("CATALOG_CATALOG"); ?></h1>
Let us insert our brand new tag there and make it much more fun!
<h1><?php CategoryName( getLocal_RootCID() ); ?></h1>
That's it! Poor
CategoryName() put alone would have no idea which name to display, there's so much categories inside the navigation bar! And we just explicitly told it to display the name of the category which serves as the root of the current
NavigationBarCustom(). Yay!
Q: Hey, but what's that
get prefix for?
A: Well, without it, Local_RootCID() would just print out the numeric category ID on the page and CategoryName() still wouldn't get that ID and cry.
get prefix makes
any tag return a value instead of printing it.
The EndThat's it! Using this 4-step plan, you can add pretty much any missing tag to any template.
I hope you liked this tutorial and won't ask much questions about it all, but instead try to sort it out yourselves.
Happy hacking!