?
avatar jjnxpct
jjnxpct
9 Jul 2015

Steps to reproduce the issue

  1. Add this to a template... +++++++ $menu = JFactory::getApplication()->getMenu(); if ($menu->getActive() == $menu->getDefault()) { $onhome = 1; } else {$onhome = 0;} +++++++ ... to detect if a visitor is on the home page.
  2. Create a link (in an article) to an other article.

Expected result

Click on the link and the value of '$onhome' on the linked article page should be 0.

Actual result

Click on the link and the value of '$onhome' on the linked article page is actually 1.

System information (as much as possible)

Joomla 3.4.3
JCE ditor (to create the link)
Linux / Apache
PHP 5.4.42

Additional comments

The link create in JCE editor is the non-sef link.
When using the direct URL to the article &onhome is 0.
For example: http://www.DOMAIN.nl/index.php?option=com_content&view=article&id=511
But when opening the sef-url:
http://www.DOMAIN.nl/15-name/511-articletitle
$onhome is 1.

I'm not actually sure if this is new or a bug. But why is $menu->getActive() the same as $menu->getDefault() on a non-sef URL and not on a SEF URL?

avatar jjnxpct jjnxpct - open - 9 Jul 2015
avatar brianteeman
brianteeman - comment - 9 Jul 2015

Did you try the code here in the docs

https://docs.joomla.org/How_to_determine_if_the_user_is_viewing_the_front_page
On 9 Jul 2015 2:41 pm, "jjnxpct" notifications@github.com wrote:

Steps to reproduce the issue

  1. Add this to a template... +++++++ $menu = JFactory::getApplication()->getMenu(); if ($menu->getActive() == $menu->getDefault()) { $onhome = 1; } else {$onhome = 0;} +++++++ ... to detect if a visitor is on the home page.
  2. Create a link (in an article) to an other article.

Expected result

Click on the link and the value of '$onhome' on the linked article page
should be 0.
Actual result

Click on the link and the value of '$onhome' on the linked article page is
actually 1.
System information (as much as possible)

Joomla 3.4.3
JCE ditor (to create the link)
Linux / Apache
PHP 5.4.42
Additional comments

The link create in JCE editor is the non-sef link.
When using the direct URL to the article &onhome is 0.
For example:
http://www.DOMAIN.nl/index.php?option=com_content&view=article&id=511
But when opening the sef-url:
http://www.DOMAIN.nl/15-name/511-articletitle
$onhome is 1.

I'm not actually sure if this is new or a bug. But why is
$menu->getActive() the same as $menu->getDefault() on a non-sef URL and not
on a SEF URL?


Reply to this email directly or view it on GitHub
#7393.

avatar jjnxpct
jjnxpct - comment - 9 Jul 2015

Hi! that is actually the code I am using (almost...). This part :
#####
$menu->getActive() == $menu->getDefault()
#####
should do the trick, but on the sef url - article WITHOUT menu item (article link of bloglink) - the $menu ID is the default menu id.

avatar smz
smz - comment - 9 Jul 2015

@brianteeman
I have the strong feeling that @jjnxpct code is exactly what suggested in that page (for non-multilingual sites).

In my experience that's not enough and there are cases not accounted for (depending if you are in SEF mode or not).

For something more extensive (for multilingual) you can have a look at my PR #7286 in helper.php, lines 69-73. This is meant for multilingual but it should work for non-multilingual too (but I haven't tested it in that context)

avatar smz
smz - comment - 9 Jul 2015

@jjnxpct was faster! :smile:

avatar smz
smz - comment - 9 Jul 2015

@jjnxpct actually (and unhappily from my POW) what you call "a bug" is a Joomla! feature: $menu->getActive() returns the "nearest" menu item to your displayed page, which in this case is the home page. What you did is correct but I'm afraid you forgot some possiblity...

Try putting a couple of print_r() for the active and current link...

avatar jjnxpct
jjnxpct - comment - 9 Jul 2015

For a site I am working on now I reached my goal in a different way:
######
$JoomlaView = JRequest::getVar('view');
if ($JoomlaView == "featured") { $onhome = 1; } else {$onhome = 0;}
#######
Since the 'home' menu item on my sit is of the type 'featured' and the homepage actually does not use the featured articles. So in this case that works.

Just to provide someone with an alternative ;-)

avatar smz
smz - comment - 9 Jul 2015

... well... that's a hack! :stuck_out_tongue_winking_eye:

avatar smz
smz - comment - 9 Jul 2015

Uninterested advice: if what you're trying to achieve is to display some module on the true home page only, try NoNumber's Advanced Modules Manager....

avatar jjnxpct
jjnxpct - comment - 9 Jul 2015

@smz : active and current link are the same on the non-sef URL. Because there is no menu item linking to the article and also no blog page. In that case I think this would not have been a problem.

avatar smz
smz - comment - 9 Jul 2015

ah, yes! you're right and that page is wrong! For getting the current link use:

$current_link = JUri::getInstance()->toString(array('path', 'query'));

avatar jjnxpct
jjnxpct - comment - 9 Jul 2015

@smz : Most of my homepages (custom made) are mostly a collection of modules. Not component area. I always use the $onhome variable in my template index.php to determine what to present to the visitor. Maybe there are better ways to do this, but it worked for me so far ;-)

avatar jjnxpct
jjnxpct - comment - 9 Jul 2015

@smz : This works:
######
$current_link = JUri::getInstance()->toString(array('path', 'query'));
if ($current_link == "/") { $onhome = 1; } else {$onhome = 0;}
######
Thanks!
Hope this is a more robust way of doing this...

avatar smz
smz - comment - 9 Jul 2015

it works but is not exhausitve: look at those lines in my PR for a more exhaustive solution...

avatar smz
smz - comment - 9 Jul 2015

At PLT: although "not a bug", I think this issue is typical, in the sense that it puts in evidence the lack a public method to tell if we are on a true home page or not: what do you think about adding such a method (In JUri, JRoute, ore somewhere else...)?

Edit: and https://docs.joomla.org/How_to_determine_if_the_user_is_viewing_the_front_page should be updated with working code...

avatar jjnxpct
jjnxpct - comment - 9 Jul 2015

Who is PLT? (newbie question probably...) I think it's a good suggestion.

avatar mbabker
mbabker - comment - 9 Jul 2015

Well, in theory, that's what JMenuSite::getDefault() should be doing based on the available menu data (since that ultimately defines your homepage). So what exactly are you looking for in a method to differentiate between the "true" home page and the default menu item (which our system uses as the home page)?

avatar smz
smz - comment - 9 Jul 2015

Michael, as evidenced by this issue pages that do not have an associated menu item are seen as the home page if you don't dig a bit deeper...

Same issue for publishing modules, which, amongst other things, brought to the birth of Advanced Modules Manger by @nonumber ...

avatar jjnxpct
jjnxpct - comment - 9 Jul 2015

If an article is opened and it is NOT linked to the default menu item I would expect the getDefault not to return the id of the default (home) menu item.

avatar brianteeman
brianteeman - comment - 9 Jul 2015

It has always been the architecture that an item without an itemid used the
homepage.

avatar mbabker
mbabker - comment - 9 Jul 2015

@jjnxpct - If getDefault() isn't returning the default menu item ID, then what should it be doing? That seems like a logic flaw. If you said that about getActive(), you'd start getting somewhere, but then there's the issue to address of what do you use if you can't use the default?

@smz - Well, that's the system behavior. If there isn't a menu item defined somewhere (the request, a plugin, anything), then we use the default data (it's like that in a lot of places). So I'm still confused on how you would differentiate between the "true" home page and a page that's just using the default menu item data. Short of URL parsing (which is questionable at best since / can equal index.php?option=com_content&view=article&id=1 or /component/content/article/1) or checking every variable of the menu item's non-SEF route, there isn't much that can be done in a logical manner. Ya, I get it, the current system is a bit weak, but what you're suggesting in some ways is that the default item data no longer applies as the default when the requested page doesn't match the explicitly configured default (home) page. That's why I'm confused; what's the behavior that we're intending to reach here?

avatar smz
smz - comment - 9 Jul 2015

@jjnxpct

No: it is correct that getDefault returns the home page menu id.

What isn't correct is that $menu->getActive() returns the home page menu id, but we cannot change this for B/C (Backward Compatibility), and hence the need of an ad-hoc method...

avatar smz
smz - comment - 9 Jul 2015

@mbabker have look at my code in #7286 to tell if a page is the true home page or not...

avatar jjnxpct
jjnxpct - comment - 9 Jul 2015

@mbabker : I was wrong. I meant 'getActive not 'getDefault'...

avatar mbabker
mbabker - comment - 9 Jul 2015

I don't get what you're trying to do in #7286 honestly, the first thing that really comes to mind is why on earth does this have to check if you're on the homepage (the "real" homepage versus default menu item).

There are valid cases where this should be detected I guess. What I don't think is valid (and this is what I'm interpreting in the comments) is changing the system behavior so that a URL that doesn't have a menu item specified in some way doesn't use the default menu item configuration. Otherwise, why on earth would that be the default item?

avatar brianteeman
brianteeman - comment - 9 Jul 2015

Any change in the existing behaviour will break existing web sites. That is
not acceptable

avatar smz
smz - comment - 9 Jul 2015

@mbabker there are many, many cases where knowing if you are on the true home page is useful:

in @jjnxpct case is for publishing modules on the real home page only.

in #7286 (Language Switcher) is to normalize the (true) home page links to either:

  • '/' . $language->sef . '/' (SEF)
  • '/index.php?lang=' . $language->sef; (non-SEF)
avatar smz
smz - comment - 9 Jul 2015

@brianteeman NOBODY wants to change existing behavior...

avatar jjnxpct
jjnxpct - comment - 9 Jul 2015

@mbabker : This works for me:

######
$app = JFactory::getApplication();
$menu = $app->getMenu();
$current_link = JUri::getInstance()->toString(array('path', 'query'));
$active = $menu->getActive();
$active_link = JRoute::_($active->link . '&Itemid=' . $active->id, false);
######

Is this a more robust way then:

######
$current_link = JUri::getInstance()->toString(array('path', 'query'));
if ($current_link == "/") { $onhome = 1; } else {$onhome = 0;}
######

?

avatar smz
smz - comment - 9 Jul 2015

@jjnxpct wait... I'm writing the code... :smile:

avatar mbabker
mbabker - comment - 9 Jul 2015

JRoute::_() should be able to do the link normalization based on your SEF configuration, if it isn't managing that correctly there's a bug in the routing API and that isn't something you should be working around at a lower level.

JMenu::getActive() returns all the data you need to check the URL to determine if you are on the default page and it is the "true" home page. Personally, I would not do my check based on the actual URL but rather the converted system parameters. In the object getActive() returns, I'd use the component and query keys to start with, first check if the component matches the expectation and if so start checking the query params. The data is there for someone to check with, IMO this doesn't need to be an API endpoint.

avatar jjnxpct
jjnxpct - comment - 9 Jul 2015

@mbabker : I'm not that technical ;-) So there could be a bug when getActive() is equal to getDefault() when the URL we are on is a 'non-menu-item-linked' article?

avatar smz
smz - comment - 9 Jul 2015

This should work (untested...):

<?php
/**
 * Tells if a page is the true home page
 *
 * @return  boolean
 */
public static function isTrueHomePage() {

    $app = JFactory::getApplication();
    $menu = $app->getMenu();
    $active = $menu->getActive();
    $lang_code = JFactory::getLanguage();
    $languages = JLanguageHelper::getLanguages('lang_code');
    $is_home = false;

    if ($active)
    {
        $active_link = JRoute::_($active->link . '&Itemid=' . $active->id, false);
        $current_link = JUri::getInstance()->toString(array('path', 'query'));

        $is_home = ($active->home
            && ($current_link == $active_link
                || $current_link . 'index.php' == $active_link
                || $current_link == '/index.php?lang=' . $languages[$lang_code]->sef
                || $current_link == $active_link . '/'));

    }

    return ($is_home)
}

avatar mbabker
mbabker - comment - 9 Jul 2015

@smz - You're URL parsing, IMO bad idea. All the data is in the object returned by JMenu::getActive(); THAT is what you should be validating.

@jjnxpct - No, there is no bug. The default menu item is just that; the system default. It is commonly associated with the site's home page, but in reality it applies to much more (there's a reason the selector in the menu item edit page is called "Default Page").

So, if you have a scenario where a page is using the default menu item and you want to check if it is the "true" home page, you can do something like this (untested but conceptually should work):

$app = JFactory::getApplication();
$activeMenu = $app->getMenu()->getActive();
$defaultMenu = $app->getMenu()->getDefault();
$isHomepage = false;

// Extra checks if active menu item is default
if ($activeMenu->id === $defaultMenu->id) {
    // Check if the active component matches
    if ($app->input->getCmd('option') == $activeMenu->component) {
        // Check the query vars and match them
        $varsMatch = true;

        while ($varsMatch) {
            foreach ($activeMenu->query as $key => $value) {
                if ($app->input->get($key) != $value) {
                    $varsMatch = false;
                }
            }
        }

        $isHomepage = $varsMatch;
    }
}
avatar smz
smz - comment - 9 Jul 2015

@smz - You're URL parsing, IMO bad idea. All the data is in the object returned by JMenu::getActive(); THAT is what you should be validating.

Unhappily I don't think it is all there... URL parsing is a necessity, IMHO

But I'll look at your code....

avatar smz
smz - comment - 9 Jul 2015

@mbabker

from a cursory look, couldn't be cases where the home page is not com_content and this could fail? What about possible &task in the home page?

I know URL parsing is not elegant, but we are talking about just the home page and there shouldn't be so many cases...

avatar smz
smz - comment - 9 Jul 2015

... and URL parsing is already in the language filter for generating rel=alternate links (...ok I coded that, so maybe same mistake... :smile: ) and it seems to work flawlessly...

avatar mbabker
mbabker - comment - 9 Jul 2015

I'm not checking com_content explicitly. So yes, there's a bug in my code in that getActive() returns null in some cases. So, with my code you'd check for that condition, then when you get into my if conditionals, it first checks the component defined in the menu item (the option query var used by the system) to see if that matches, then if that does, we loop over all of the query vars defined by the menu item and compare them to the variables defined in our JInput object. If ALL of those items match, it is safe to assume that we are on the "true" home page.

From a practical test, with the homepage configured as com_content article ID 1, the URL /component/content/article/1 (which is not the homepage URL) returns true because it is the real configured homepage (take SEO opinions elsewhere on this, it is doing exactly what I want it to do). The URL /component/content/article/2 returns false on the homepage check because it is not the article that is specified.

Revised code snippet:

$app = JFactory::getApplication();
$activeMenu = $app->getMenu()->getActive();
$isHomepage = false;

// Extra checks if active menu item is default
if (!$activeMenu) {
    // Check the data from the default menu item to decide if we are on the user specified home page.
    $defaultMenu = $app->getMenu()->getDefault();

    // Check if the active component matches
    if ($app->input->getCmd('option') == $defaultMenu->component) {
        // Check the query vars and match them
        $varsMatch = true;

        foreach ($defaultMenu->query as $key => $value) {
            if ($varsMatch) {
                if ($app->input->get($key) != $value) {
                    $varsMatch = false;
                }
            }
        }

        $isHomepage = $varsMatch;
    }
}

FWIW, this is the data dump from getDefault() for the default page configured as a single article.
screen shot 2015-07-09 at 11 17 40 am

avatar Bakual
Bakual - comment - 9 Jul 2015

Isn't the real issue, that you have an URL without a valid Itemid? Only then it will fall back to the default (homepage).
Fix your menu system or fix the code that produces the URL and the issue is gone.

avatar smz
smz - comment - 9 Jul 2015

be it your code, @mbabker, my code, or somebody's else code (I really don't care...) I think we need that method and, a) language filter and b) language switcher, are two core places where that would be much needed...

avatar mbabker
mbabker - comment - 9 Jul 2015

It doesn't need to be an API endpoint. Anyone can implement that code in any condition today. The fact that we actually have so many cases where we're being forced to check this tells me we have a metric crapton of bugs that need to be addressed; actions should not be so dependent on the user being at the "true" home page and it is a major fail that we have allowed code to reach this point.

avatar PhilETaylor
PhilETaylor - comment - 10 Jul 2015

Are we over complicating things? Doesnt this still work (from 2012 so who knows)?
https://www.phil-taylor.com/2012/02/02/how-to-find-out-if-you-are-on-the-homepage-of-joomla-2-5/

avatar smz
smz - comment - 10 Jul 2015

Unhappily not, Phil, it doesn't work (and probably didn't work at 2.5 times as well) unless you put some (IMHO unrealistic) constrains on how one should design his/her menu system.

avatar PhilETaylor
PhilETaylor - comment - 10 Jul 2015

ah I see you are on the Article URL and not the Menu URL - different things :)

avatar smz
smz - comment - 10 Jul 2015

Yeap! :stuck_out_tongue_winking_eye:

avatar smz
smz - comment - 10 Jul 2015

Historical note by someone who wasn't there at the times (so take it with due caution..): it maybe could had worked at Mambo times when (if I'm not mistaken) a menu entry was automatically created for every content (articles, at least) created...

avatar brianteeman
brianteeman - comment - 10 Jul 2015

You are mistaken.

avatar smz
smz - comment - 10 Jul 2015

I said that.... take it with due caution... :smile:

But wasn't there something like that at the times, Brian? Totally mistaken?

avatar brianteeman
brianteeman - comment - 10 Jul 2015

Totally miataken

avatar smz
smz - comment - 10 Jul 2015

OK, point taken! :smile:

I was pretty sure that in a discussion sometime ago about adding this feature to Joomla, somebody said this was there (at least as an option) at Mambo (or was it J! 1.0...) times.

But for sure you're a much more reliable source than me on this matter!

avatar brianteeman
brianteeman - comment - 10 Jul 2015

What they are referring to is a quick link in the article edit page to create a single article menu item

avatar smz
smz - comment - 10 Jul 2015

Ah, ok, so not automatically, but ready at hand... got it! Thanks!

avatar wilsonge
wilsonge - comment - 8 May 2016

I'm going to close this PR as there is not much more to be said/done here.

avatar wilsonge wilsonge - change - 8 May 2016
Status New Closed
Closed_Date 0000-00-00 00:00:00 2016-05-08 16:27:46
Closed_By wilsonge
avatar wilsonge wilsonge - close - 8 May 2016

Add a Comment

Login with GitHub to post a comment