It sometimes happens that you want to publish a Joomla module in a custom position on a Virtuemart page, or perhaps you only want the module to appear on specific pages, such as the product details or category page. For example, you have a custom HTML module that gives some information about shipping, and you just want to display it on the product details page. The normal Joomla method of assigning a module page is to use the menu assignment, but this is not possible in our example, because a Virtuemart product details page will not normally correspond to a Joomla menu item. So how to do it? It turns out that actually there is more than one approach to solving this problem.
Sometimes you may want to display a module on the product details page for a specific product. In this case, probably the best solution is to use the Joomla LoadModule content plugin, which comes installed with Joomla (we have a tutorial on how to do this here). You will need to turn on the 'enable Joomla plugin' in the Virtuemart shop configuration in order to do this. Virtuemart will support content plugins in several types of content: product (long) descriptions, also the category and manufacturer descriptions, plus the vendor terms of service, store description and legal info. In all these cases you use the standard embedding code added to the text where you want the module to appear:-
{loadposition positionname} or {loadmodule modulename}
However if you want the module to appear on the details page for every product in your store, this method could rapidly become very tedious, if you have a lot of products, which brings us to our second method.
This second method is more complicated, it involves creating a custom module position within the Joomla template, then assigning the module to this position in the Joomla module manager. I will explain this using a specific example: suppose we want to add a custom module to the product short description when it is displayed on the product details page for every product.
Creating a custom module position is quite easy. You open up your module in the Joomla module manager, and type its name in the position box, for example "custom-pos-1" - the name can be anything that you choose as long as it does not conflict with the existing position names. Note that it is also a good idea to assign your module to all Joomla pages in the menu assignment, this will ensure that the module actually appears when you create a place in the template for your custom position to appear.
Now you need some code that will render the module position inside a template. If you want to create a custom module position inside a normal Joomla template index.php file you can use the following:-
<jdoc:include type="modules" name="custom-pos-1" />
This will create a position called "custom-pos-1". Note that this is not PHP code, so it must be outside any PHP tags. Unfortunately this code will not work inside a Virtuemart template, and may not work with other extension templates. However there is some PHP code that you can use which has an equivalent effect:-
<?php $modules = JModuleHelper::getModules('custom-pos-1'); foreach($modules as $mod) { echo JModuleHelper::renderModule($mod); } ?>
It's a bit more long-winded, but the advantage is that it should work anywhere, with any extension template.
The final thing that you need to do - and this is probably the hardest part - is to track down where the actual template is that you will be modifying by adding the code.Virtuemart stores all its templates in the folder components/com_virtuemart/views. You will see that the folders inside are named for the pages, and within each of these folders is a folder called tmpl, which actually contains the templates. So with our product details example, the template is in the folder components/com_virtuemart/views/productdetails/tmpl/. The actual template is split into several files: the main template file is called default.php, while there are sub-templates for the images, add-to-cart functions, custom fields and so on.
Now you need to find the actual template code you will be modifying. Luckily the code is fairly well annotated with comments, so it is normally possible to tell what each bit actually does. In our example case, the code that generates the product short description is in the default.php template file and looks something like this:-
<?php // Product Short Description
if (!empty($this->product->product_s_desc)) { ?> <div class="product-short-description"> <?php echo nl2br($this->product->product_s_desc); ?> </div> <?php
} // Product Short Description END
Now we can add our code to generate the custom module position:-
<?php // Product Short Description
if (!empty($this->product->product_s_desc)) { $modules = JModuleHelper::getModules('custom-pos-1'); foreach($modules as $mod) { echo JModuleHelper::renderModule($mod); } ?> <div class="product-short-description"> <?php echo nl2br($this->product->product_s_desc); ?> </div> <?php
} // Product Short Description END
So far we have looked at where Virtuemart stores its templates. If you are using a standard Joomla template, such as the Beez template distributed with the Joomla core, these will be the relevant templates to look at. However, even if these are the relevant templates for your site, it is a good idea to use template overriding rather than modifying the Virtuemart templates directly, this will prevent your modified code from being lost if you update your Virtuemart version.
If you are using a commercial e-commerce template for your site, it is likely that the Virtuemart templates will already be overridden in your site template. If so, these overriding templates will be in the folder
templates/{mytemplate_name}/html/com_virtuemart/
where {mytemplate_name} stands for the actual name of your template. You will see that this folder contains sub-directories that correspond to the view names (category, productdetails etc): within these sub-directories the actual templates are stored. These will be the templates that you actually need to modify. If there are no overriding template then you can create your own by creating the relevant folder and copying to it the Virtuemart template that you want to modify. Note that you only need to override the templates that you actually want to modify. So in our example you would copy your modified default.php file to:-
templates/{mytemplate_name}/html/com_virtuemart/productdetails/default.php
This technique will work well for many cases, but it does require some basic confidence with coding. Also what about more complex cases, for example suppose you want to display a module on the product details page, but only if the product is in certain categories? Or if the customer is not logged into the site? It will require more complex coding logic. It is for these cases that we developed our VM Modcontroller module.
This module can be used to apply logic to control the display of Joomla modules on Virtuemart pages. It can restrict the display by category or manufacturer, shopper group, whether the user is logged in or not, whether the protocol is http: or https. The documentation explains more about the available options, while you can obtain the module here.
The VM Modcontroller module works by checking whether the logical conditions are met for rendering the module that you want displayed, and then either rendering the module or suppressing the output, depending on the conditions.
Note that you can combine using the VM Modcontroller module with the 2nd method described above. For example you could create a custom module position on the Virtuemart product details page, then use the VM Modcontroller module to restrict the display to particular product categories, or to show only when the customer is not logged into the site. The result can be a very sophisticated degree of control over module display.