Jump to content


Photo

How To Add Your Own Tags To Templates


  • Please log in to reply
1 reply to this topic

#1 David Frost

David Frost

    Avactis Support Engineer

  • Administrators
  • PipPipPipPip
  • 144 posts

Posted 16 April 2010 - 03:41 PM

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 view

Everything 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 attribute

Once 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 renderer

OK, 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 template

Now 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.html

What 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 End

That'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!
David
Avactis Support Team

#2 lowcost

lowcost

    Novice

  • Members
  • PipPip
  • 21 posts

Posted 13 February 2011 - 06:33 AM

Doesn't work for me. I tried this in page.template.tpl.html <body class="<?php CategoryName( getLocal_RootCategoryClass() ); ?>"> And thus the page stops rendering at the first quote.