1

I am using Joomla 4.2.1. I installed custom component which is previously used into Joomla 3.10.11.

I create a menu item with view from this component.

On Joomla 3.10.11 it works fine

for example : http://mylocal.local/index.php/kurse-nach-datum

But

on Joomla 4.2.1 it create url with view name

For example : http://mylocal.local/index.php/kurse-nach-datum/courses

kurse-nach-datum is the Alias of link

and link is index.php?option=com_course&view=courses

Router.php

<?php

/**
 * @version     3.4.0
 * @package     com_course
 * @copyright   Copyright (C) 2015. All rights reserved.
 * @license
 * @author      -
 */
// No direct access
defined('_JEXEC') or die;

/**
 * @param   array   A named array
 * @return  array
 */
function CourseBuildRoute(&$query) {
    $segments = array();

    if (isset($query['task'])) {
        $segments[] = implode('/', explode('.', $query['task']));
        unset($query['task']);
    }
    if (isset($query['view'])) {
        $segments[] = $query['view'];
        unset($query['view']);
    }
    if (isset($query['id'])) {
        $segments[] = $query['id'];
        unset($query['id']);
    }

    return $segments;
}

/**
 * @param   array   A named array
 * @param   array
 *
 * Formats:
 *
 * index.php?/course/task/id/Itemid
 *
 * index.php?/course/id/Itemid
 */
function CourseParseRoute($segments) {
    $vars = array();
    // view is always the first element of the array
    $vars['view'] = array_shift($segments);

    while(!empty($segments)) {

        $segment = array_pop($segments);
        if (is_numeric($segment)) {
            $vars['id'] = $segment;
        } else {
            $vars['task'] = $vars['view'] . '.' . $segment;
        }
    }

    return $vars;
}
4
  • This should be handled by your component's router. How is it implemented? Can you post the code?
    – Sharky
    Sep 19 at 7:08
  • @Sharky i added my router.php to my question. Sep 20 at 7:13
  • As an aside, isn't implode('/', explode('.', $query['task'])) the same as str_replace('.', '/', $query['task']))?
    – mickmackusa
    Sep 22 at 21:53
  • 1
    @mickmackusa yes, you are right. Thanks for pointing out. Sep 23 at 6:28

1 Answer 1

1

There have been many changes in routing in J4. One in particular is that URLs containing only menu item ID (e.g. index.php?Itemid=145) now have all menu query parameters appended before being passed to component router. In J3, only component was added. This is an issue for you because your router unconditionally appends the view to the path:

if (isset($query['view'])) {
    $segments[] = $query['view'];
    unset($query['view']);
}

This isn't entirely correct even for J3, since building the link with correct item ID:

index.php?option=com_courses&view=course&Itemid=145

results in URL containing the view after menu alias:

index.php/[menu-alias]/course

To solve the issue you essentially need to add logic to handle URLs with and without menu item IDs. So that the view is added to the path only when needed. Instead of writing this code yourself, you could convert your old router to a rule-based router, i.e. by extending Joomla\CMS\Component\Router\RouterView. The included core rules should already handle this.

Also, in case you're getting 404 errors in your component, it's probably because your parse function has incorrect function signature. $segments argument should be passed by reference because the modification made to it matter.

function CourseParseRoute(&$segments) {

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.