In gides about binding of Social Media Buttons and Breadcrumbs to certain pages of a Joomla-based website, only filtering by articles was considered. But what if you want to bind a module or other extension, and in general - any piece of code to the selected categories, components and their specific pages, or even to all listed at once? You may say that the modules are already linked to menu items, and in case of using more advanced module manager (eg, Advanced Module Manager) - even to categories, articles, users, components, etc. This is true; but to output module with different settings on the corresponding pages, you will have to create its multiple copies, linked to these pages. For example, on this website the Recent Comments module displays a list of comments made to articles of only those categories and components whose pages output this instance of module. Since the structure of the site is quite extensive, and besides, the site is multilingual, number of copies of the module exceeds 10. It's pretty inconvenient.

The proposed solution is intended to provide a flexible and contextual content output based on specified criteria. Coding knowledge is desirable, but I will try to give exact recommendations for its implementation, which will allow less qualified Joomla users to also utilize this methodology. In addition, in a separate article I have described the structure of internal links within Joomla site, which is designed to facilitate the understanding of the algorithm. Let's do it!

I have written a function and called it content_filter. The function code is below in clickable drop-down code block.

Description and code of the function content_filter

The function declaration is as follows:

function content_filter($exception_articles,
                        $exception_categories = null,
                        $exception_category_views = null,
                        $exception_components = null)

Arguments:

The first three are plain one-dimensional arrays of type:

array($value1, $value2, ...)

Array elements:

  • $exception_articles - identifiers of individual articles;
  • $exception_categories - identifiers of categories for individual article pages;
  • $exception_category_views - identifiers of categories for pages of articles which are related to these categories and presented as list or blog.

These three arrays deal with articles and categories of the base Joomla component - com_content. Component's name - the option key, and the view - key of the same name are both not included in the arrays explicitly. The value of the first key is implied, and the view is automatically detected.

But the fourth array $exception_components can be used to control the output of pages of other components that have the same keys as com_content has. These keys are specified explicitly:

array(
  array(name => $name1 [, view => $view1][, catid => $catid1][, $id => $id1]),
  array(name => $name2 [, view => $view2][, catid => $catid2][, $id => $id2]),
  ...
)

Each element is an array of type key => value that is related to particular parameter of a certain component. Keys of these internal arrays correspond to parameters in the query string of internal link to component's specific page.

Each argument-array can be set to null, meaning that the function will not filter the contents of the corresponding pages. The same applies to the fourth array's elements.

Filling of the arguments in the content_filter function call is further illustrated in detail by code examples.

The return value of the function is true if the shown page corresponds to the value of at least one element of any of four arrays-arguments.

Function content_filter source code

function content_filter($exception_articles,
                        $exception_categories = null,
                        $exception_category_views = null,
                        $exception_components = null) {
  global $cf_option, $cf_view, $cf_art_cat_id, $cf_cat_id;
 
  //1. if current page is category or article in com_content
  if ($cf_option == 'com_content') {
    if ($cf_view == 'article') {
      // $cf_cat_id is category ID; $cf_art_cat_id is article ID
      //1.1 check article exceptions
      if (isset($exception_articles)) {
        for ($i=0, $n=sizeof($exception_articles); $i<$n; $i++) {
          if ($cf_art_cat_id == $exception_articles[$i])
            return true;
        }
      }
      //1.2 check category exceptions for article view
      if (isset($exception_categories)) {
        for ($i=0, $n=sizeof($exception_categories); $i<$n; $i++) {
          if ($cf_cat_id == $exception_categories[$i])
            return true;
        }
      }
    }
    //1.3 check category exceptions for category view
    // $cf_art_cat_id is category ID
    elseif ($cf_view == 'category' && isset($exception_category_views)) {
      for ($i=0, $n=sizeof($exception_category_views); $i<$n; $i++) {
        if ($cf_art_cat_id == $exception_category_views[$i])
          return true;
      }
    }
  }
  //2. check components
  // $cf_cat_id is component category ID; $cf_art_cat_id is component ID
  if (isset($exception_components)) {
    for ($i=0, $n=sizeof($exception_components); $i<$n; $i++) {
      if ($cf_option == $exception_components[$i][name] &&
         (!isset($exception_components[$i][view]) ||
           $cf_view == $exception_components[$i][view]) &&
         (!isset($exception_components[$i][catid]) ||
           $cf_cat_id == $exception_components[$i][catid]) &&
         (!isset($exception_components[$i][id]) ||
           $cf_art_cat_id == $exception_components[$i][id]))
      return true;
    }
  }
  return false;
}

end faq

Placing function content_filter to a library and initializing global variables

Where this marvelous function should be placed? You can put it in a separate file or add it in one of the existing libraries. It is desirable that it was not a library of Joomla core; in this case, the update of the CMS may lead to manual restoring of the function. In my template, created originally in Artisteer, there is the file functions.php, which is included at the beginning of the template's index file:

<?php
defined('_JEXEC') or die;
 
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'functions.php';

I added the above code of the content_filter function just into functions.php library.

From the code can also be clear that the function uses 4 global variables corresponding to the parameters of the page displayed. It's done so in order not to initialize them each time in the case of multiple function calls at the same page. So their initialization is relocated to the index file of the active template. Open the file templates\[active_template]\index.php for editing, replacing before [active_template] with your folder name. Right after that line which connects the library containing our function, insert the initialization code of the global variables. As a result, the beginning of the code in the index.php file takes the following form:

<?php
defined('_JEXEC') or die;
 
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'functions.php';
 
//initialize global variables for content_filter()
global $cf_option, $cf_view, $cf_art_cat_id, $cf_cat_id;
 
$jinput = JFactory::getApplication()->input;
 
$cf_option = $jinput->getCmd('option');
$cf_view = $jinput->getCmd('view');
 
$temp = explode(':', $jinput->getCmd('id'));
$cf_art_cat_id = $temp[0] + 0;
 
$temp = $jinput->getInt('catid');
$cf_cat_id = $temp[0] + 0;

(Details about the formation of code which initializes the variables corresponding request keys, and also about the need to cut off tails-aliases from the values of some of them, you can read in the same guide of internal links' structure.)

Now the content_filter is included in the page code of your website. It's time to go to the examples of its call.

Examples of using the function content_filter

Example 1. Disable breadcrumbs on pages 404 for two languages, as well as on pages of search and authorization components. (In fact it's an enhanced version of the navigator filtering code from the corresponding article.)

if ($view->containsModules('breadcrumb') && 
    !content_filter(
      array(80, 448), //$exception_articles
      null,           //$exception_categories
      null,           //$exception_category_views
      array(
        array(name => 'com_users'),
        array(name => 'com_search')
      )               //$exception_components
    ) //!content_filter
  ) //if
    echo artxPost($view->position('breadcrumb'));

Example 2. Disabling the panel of social media buttons on the pages of articles related to category 1, as well as on the pages of categories 1, 3 and 6 in a view of list or blog.

<?php
if (
    !content_filter(
      null,          //$exception_articles
      array(1),      //$exception_categories
      array(1, 3, 6) //$exception_category_views
                     //$exception_components is null by default
    ) //!content_filter
  ) //if
?>
 
    <!-- скрипт вывода кнопок -->
 
<?php } ?>

Example 3. Display a banner only on pages of categories 6 and 7 of the JoomGallery component, as well as on the site map having id=4.

<?php
if (
    content_filter(
      null,          //$exception_articles
      null,          //$exception_categories
      null,          //$exception_category_views
      array(
        array(name => 'com_joomgallery', view => 'category', catid => 6),
        array(name => 'com_joomgallery', view => 'category', catid => 7),
        array(name => 'com_xmap', id => 4)
      )               //$exception_components
    ) //content_filter
  ) { //if
?>
 
    <!-- скрипт вывода баннера -->
 
<?php } ?>

In conclusion, let me note a few limitations when using the suggested version of the content_filter function.

  • Filter by featured articles is not included.
  • For the view of articles in a category (array $exception_category_views), the condition by additional key layout is not present. (As you remember, this key is responsible for displaying articles in one of two presentations of the category view - list or blog.)
  • The function does not handle those pages of components, whose parameters are different from the four basic ones. Like, for instance, in VitrueMart - controller and task. For such components, separate functions for processing of their pages output can be entered.

I created the function for myself, and all kinds of filters which it includes meet requirements in terms of selective output of the content on my website at the time of this writing. In the future, as the occurrence of similar problems in my practice, as well as the receipt of questions from curious readers of this site, I will continue writing articles dedicated to a detailed consideration of individual cases while using described technique.

Add comment


© 2011-2017 ogri.me
Use and reprint of the site materials are allowed and welcome. Direct indexable link to the used article or, at worst, to the site itself would be a good contribution to the author for his hard work.