1

I'm using Joomla 3.9 and had someone previously code in the ability to use the Joomla article title as the <title> tags ( browser title )

This works well using a current placeholder, for example the title of the Joomla article reads " {%country_name%} cheap vacations "

The article is sort of a template for these pages....

I've now added a new placeholder called {%placeholder_nicktitle%} - it's using the Joomla language override.

This is the code I used to create the placeholder

$placeholder_nicktitle = JText::_('titlenick_'.strtoupper(str_replace('-','_',$var['country'])));
    if($placeholder_nicktitle === 'titlenick_'.strtoupper(str_replace('-','_',$var['country'])) || !$placeholder_nicktitle) $placeholder_nicktitle = '';



     $article->text = JString::str_ireplace("{%placeholder_nicktitle%}", $placeholder_nicktitle, $article->text);

Now, when I use the placeholder {%placeholder_nicktitle%} in the article body, it shows up fine on the page.

The Question

When I add the placeholder in the title ,for example "{%placeholder_nicktitle%} cheap vacations" it doesnt work . (You'll literally see the text {%placeholder_nicktitle%} in the browser/page title ). The placeholder {%country_name%} works fine in joomla article title.

I'm assuming I need to code something into the Joomla core or article tmpl so it understands the new placeholder?

My view.html.php page found in /components/com_content/views/article

<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_content
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * HTML Article View class for the Content component
 *
 * @since  1.5
 */
class ContentViewArticle extends JViewLegacy
{
    protected $item;

    protected $params;

    protected $print;

    protected $state;

    protected $user;

    /**
     * Execute and display a template script.
     *
     * @param   string  $tpl  The name of the template file to parse; automatically searches through the template paths.
     *
     * @return  mixed  A string if successful, otherwise an Error object.
     */
    public function display($tpl = null)
    {
        $app        = JFactory::getApplication();
        $user       = JFactory::getUser();
        $dispatcher = JEventDispatcher::getInstance();

        $this->item  = $this->get('Item');
        $this->print = $app->input->getBool('print');
        $this->state = $this->get('State');
        $this->user  = $user;

        // Check for errors.
        if (count($errors = $this->get('Errors')))
        {
            JError::raiseWarning(500, implode("\n", $errors));

            return false;
        }

        // Create a shortcut for $item.
        $item            = $this->item;
        $item->tagLayout = new JLayoutFile('joomla.content.tags');

        // Add router helpers.
        $item->slug        = $item->alias ? ($item->id . ':' . $item->alias) : $item->id;
        $item->catslug     = $item->category_alias ? ($item->catid . ':' . $item->category_alias) : $item->catid;
        $item->parent_slug = $item->parent_alias ? ($item->parent_id . ':' . $item->parent_alias) : $item->parent_id;

        // No link for ROOT category
        if ($item->parent_alias === 'root')
        {
            $item->parent_slug = null;
        }

        // TODO: Change based on shownoauth
        $item->readmore_link = JRoute::_(ContentHelperRoute::getArticleRoute($item->slug, $item->catid, $item->language));

        // Merge article params. If this is single-article view, menu params override article params
        // Otherwise, article params override menu item params
        $this->params = $this->state->get('params');
        $active       = $app->getMenu()->getActive();
        $temp         = clone $this->params;

        // Check to see which parameters should take priority
        if ($active)
        {
            $currentLink = $active->link;

            // If the current view is the active item and an article view for this article, then the menu item params take priority
            if (strpos($currentLink, 'view=article') && strpos($currentLink, '&id=' . (string) $item->id))
            {
                // Load layout from active query (in case it is an alternative menu item)
                if (isset($active->query['layout']))
                {
                    $this->setLayout($active->query['layout']);
                }
                // Check for alternative layout of article
                elseif ($layout = $item->params->get('article_layout'))
                {
                    $this->setLayout($layout);
                }

                // $item->params are the article params, $temp are the menu item params
                // Merge so that the menu item params take priority
                $item->params->merge($temp);
            }
            else
            {
                // Current view is not a single article, so the article params take priority here
                // Merge the menu item params with the article params so that the article params take priority
                $temp->merge($item->params);
                $item->params = $temp;

                // Check for alternative layouts (since we are not in a single-article menu item)
                // Single-article menu item layout takes priority over alt layout for an article
                if ($layout = $item->params->get('article_layout'))
                {
                    $this->setLayout($layout);
                }
            }
        }
        else
        {
            // Merge so that article params take priority
            $temp->merge($item->params);
            $item->params = $temp;

            // Check for alternative layouts (since we are not in a single-article menu item)
            // Single-article menu item layout takes priority over alt layout for an article
            if ($layout = $item->params->get('article_layout'))
            {
                $this->setLayout($layout);
            }
        }

        $offset = $this->state->get('list.offset');

        // Check the view access to the article (the model has already computed the values).
        if ($item->params->get('access-view') == false && ($item->params->get('show_noauth', '0') == '0'))
        {
            $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error');
            $app->setHeader('status', 403, true);

            return;
        }

        /**
         * Check for no 'access-view' and empty fulltext,
         * - Redirect guest users to login
         * - Deny access to logged users with 403 code
         * NOTE: we do not recheck for no access-view + show_noauth disabled ... since it was checked above
         */
        if ($item->params->get('access-view') == false && !strlen($item->fulltext))
        {
            if ($this->user->get('guest'))
            {
                $return = base64_encode(JUri::getInstance());
                $login_url_with_return = JRoute::_('index.php?option=com_users&view=login&return=' . $return);
                $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'notice');
                $app->redirect($login_url_with_return, 403);
            }
            else
            {
                $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error');
                $app->setHeader('status', 403, true);

                return;
            }
        }

        /**
         * NOTE: The following code (usually) sets the text to contain the fulltext, but it is the
         * responsibility of the layout to check 'access-view' and only use "introtext" for guests
         */
        if ($item->params->get('show_intro', '1') == '1')
        {
            $item->text = $item->introtext . ' ' . $item->fulltext;
        }
        elseif ($item->fulltext)
        {
            $item->text = $item->fulltext;
        }
        else
        {
            $item->text = $item->introtext;
        }

        $item->tags = new JHelperTags;
        $item->tags->getItemTags('com_content.article', $this->item->id);

        if ($item->params->get('show_associations'))
        {
            $item->associations = ContentHelperAssociation::displayAssociations($item->id);
        }

        // Process the content plugins.
        JPluginHelper::importPlugin('content');
        $dispatcher->trigger('onContentPrepare', array ('com_content.article', &$item, &$item->params, $offset));

        $item->event = new stdClass;
        $results = $dispatcher->trigger('onContentAfterTitle', array('com_content.article', &$item, &$item->params, $offset));
        $item->event->afterDisplayTitle = trim(implode("\n", $results));

        $results = $dispatcher->trigger('onContentBeforeDisplay', array('com_content.article', &$item, &$item->params, $offset));
        $item->event->beforeDisplayContent = trim(implode("\n", $results));

        $results = $dispatcher->trigger('onContentAfterDisplay', array('com_content.article', &$item, &$item->params, $offset));
        $item->event->afterDisplayContent = trim(implode("\n", $results));

        // Escape strings for HTML output
        $this->pageclass_sfx = htmlspecialchars($this->item->params->get('pageclass_sfx'));

        $this->_prepareDocument();

        parent::display($tpl);
    }

    /**
     * Prepares the document.
     *
     * @return  void
     */
    protected function _prepareDocument()
    {
        $app     = JFactory::getApplication();
        $menus   = $app->getMenu();
        $pathway = $app->getPathway();
        $title   = null;

        /**
         * Because the application sets a default page title,
         * we need to get it from the menu item itself
         */
        $menu = $menus->getActive();

        if ($menu)
        {
            $this->params->def('page_heading', $this->params->get('page_title', $menu->title));
        }
        else
        {
            $this->params->def('page_heading', JText::_('JGLOBAL_ARTICLES'));
        }

        $title = $this->params->get('page_title', '');

        $id = (int) @$menu->query['id'];

        // If the menu item does not concern this article
        if ($menu && (!isset($menu->query['option']) || $menu->query['option'] !== 'com_content' || $menu->query['view'] !== 'article'
            || $id != $this->item->id))
        {
            // If a browser page title is defined, use that, then fall back to the article title if set, then fall back to the page_title option
            $title = $this->item->params->get('article_page_title', $this->item->title ?: $title);

            $path     = array(array('title' => $this->item->title, 'link' => ''));
            $category = JCategories::getInstance('Content')->get($this->item->catid);

            while ($category && (!isset($menu->query['option']) || $menu->query['option'] !== 'com_content' || $menu->query['view'] === 'article'
                || $id != $category->id) && $category->id > 1)
            {
                $path[]   = array('title' => $category->title, 'link' => ContentHelperRoute::getCategoryRoute($category->id));
                $category = $category->getParent();
            }

            $path = array_reverse($path);

            foreach ($path as $item)
            {
                $pathway->addItem($item['title'], $item['link']);
            }
        }

        // Check for empty title and add site name if param is set
        if (empty($title))
        {
            $title = $app->get('sitename');
        }
        elseif ($app->get('sitename_pagetitles', 0) == 1)
        {
            $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title);
        }
        elseif ($app->get('sitename_pagetitles', 0) == 2)
        {
            $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename'));
        }

        if (empty($title))
        {
            $title = $this->item->title;
        }

        $this->document->setTitle($title);

        if ($this->item->metadesc)
        {
            $this->document->setDescription($this->item->metadesc);
        }
        elseif ($this->params->get('menu-meta_description'))
        {
            $this->document->setDescription($this->params->get('menu-meta_description'));
        }

        if ($this->item->metakey)
        {
            $this->document->setMetadata('keywords', $this->item->metakey);
        }
        elseif ($this->params->get('menu-meta_keywords'))
        {
            $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords'));
        }

        if ($this->params->get('robots'))
        {
            $this->document->setMetadata('robots', $this->params->get('robots'));
        }

        if ($app->get('MetaAuthor') == '1')
        {
            $author = $this->item->created_by_alias ?: $this->item->author;
            $this->document->setMetaData('author', $author);
        }

        $mdata = $this->item->metadata->toArray();

        foreach ($mdata as $k => $v)
        {
            if ($v)
            {
                $this->document->setMetadata($k, $v);
            }
        }

        // If there is a pagebreak heading or title, add it to the page title
        if (!empty($this->item->page_title))
        {
            $this->item->title = $this->item->title . ' - ' . $this->item->page_title;
            $this->document->setTitle(
                $this->item->page_title . ' - ' . JText::sprintf('PLG_CONTENT_PAGEBREAK_PAGE_NUM', $this->state->get('list.offset') + 1)
            );
        }

        if ($this->print)
        {
            $this->document->setMetaData('robots', 'noindex, nofollow');
        }
    }
}

I also read the solution may be in the default.php template file found in templates/yoo_avion/html/com_content/article

<?php


// include config and layout
$base = dirname(dirname(dirname(__FILE__)));
include($base.'/config.php');
include($warp['path']->path('layouts:'.preg_replace('/'.preg_quote($base, '/').'/', '', __FILE__, 1)));

Update

templates/yoo_avion/html/plg_mvcoverride/com_acme/view.html.php

I was thinking perhaps my placeholder needs to be added here somehow?

    function setTitle($title, $params=NULL)
{

    JFactory::getLanguage()->load('com_acme.keywords');
    JFactory::getLanguage()->load('com_acme.description');

    $document = JFactory::getDocument();

    $keywords = JText::_(JString::str_ireplace('TITLE_COVERAGE', 'KEY_COVERAGE', $title));
    $description = JText::_(JString::str_ireplace('TITLE_COVERAGE', 'DESC_COVERAGE', $title));

     $title=JText::_($title);

    $placeHolders = array(
        'country' => $this->requestCountry ? $this->country->country_name : NULL,
        'city' => $this->requestCity ? $this->city->city_name : NULL,
    );

    $search = array();
    $replace = array();

    foreach($placeHolders as $placeHolder => $text)
        if($text){
            array_push($search, '{%'.$placeHolder.'%}');
            array_push($replace, $text);
        }

    $keywords = $document->getMetadata('keywords').$keywords;
    $description = $document->getMetadata('description').$description;

    $document->setTitle(JString::str_ireplace($search, $replace, $title));

    $document->setMetadata('keywords', JString::str_ireplace($search, $replace, $keywords));
    $document->setMetadata('description', JString::str_ireplace($search, $replace, $description));
}
1
  • I'm all ears to any ideas, I've since updated the question too.
    – Nick
    Dec 17, 2021 at 15:35

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.