Q - How to display frontend menu in Joomla 5 custom component ?

Moderator: mindphp

Raja Pdl
PHP VIP Members
PHP VIP Members
โพสต์: 2241
ลงทะเบียนเมื่อ: 27/05/2024 9:50 am

Q - How to display frontend menu in Joomla 5 custom component ?

โพสต์ที่ยังไม่ได้อ่าน โดย Raja Pdl »

In my Joomla 5 custom component, I have created an XML file for the frontend menu for the component as well as follows.

example - components/com_hello/tmpl/tests/default.xml

โค้ด: เลือกทั้งหมด

<?xml version="1.0" encoding="UTF-8"?>
<metadata>
	<layout title="COM_HELLO_TEST_LIST">
		<message>
			<![CDATA[COM_HELLO_TEST_LIST_DESC]]>
		</message>
	</layout>
</metadata>
And when I set up frontend menu item, it displays on the frontend as follows:

โค้ด: เลือกทั้งหมด

Deprecated: htmlspecialchars(): Passing null to parameter #1 ($string) of type string is deprecated in my_project_path\modules\mod_menu\tmpl\default_component.php on line 72
Hello
I can't make changes to Joomla core files like mod_menu. I need to fix this only within my component. How can I fix it?
MindPHP Assistant

Re: Q - How to display frontend menu in Joomla 5 custom component ?

โพสต์ที่ยังไม่ได้อ่าน โดย MindPHP Assistant »

The warning you're seeing is due to passing a `null` value to the `htmlspecialchars()` function somewhere in your component or the way it's being processed by Joomla. This usually happens when the data expected isn't available or has not been set properly.

Here’s a step-by-step guide to resolve the issue within your component:

1. **Check Your XML Definitions**: Ensure that all required fields are properly defined and have default values if necessary. Check that your language constants `COM_HELLO_TEST_LIST` and `COM_HELLO_TEST_LIST_DESC` are defined in your language files.

2. **Review Language Files**: Make sure that there are no missing language strings. Sometimes a missing language string can cause null values. Check your language files in `language/en-GB/en-GB.com_hello.ini` (or equivalent for your language) and ensure `COM_HELLO_TEST_LIST` and `COM_HELLO_TEST_LIST_DESC` are defined.

โค้ด: เลือกทั้งหมด

ini
   COM_HELLO_TEST_LIST="Test List Title"
   COM_HELLO_TEST_LIST_DESC="Description for Test List"
   
3. **Default Values in Code**: If your component is expecting data from the XML file or language strings, make sure it has fallback values in case they are not set. For example, when retrieving language strings in PHP, you can use:

โค้ด: เลือกทั้งหมด

php
   $title = JText::_('COM_HELLO_TEST_LIST');
   if (empty($title)) {
       $title = 'Default Title';
   }
   
4. **Inspect Component Rendering**: Check how the menu items or component content are being rendered. Ensure that you are not passing null values to functions expecting strings. You can add checks like:

โค้ด: เลือกทั้งหมด

php
   $safeString = !empty($variable) ? htmlspecialchars($variable, ENT_QUOTES, 'UTF-8') : '';
   
5. **Menu Item Parameters**: When creating menu items for your component, make sure all required fields are filled out and valid in the Joomla menu manager.

6. **Debugging Output**: Add some temporary debugging output in your component's view or template to log or display values being used. This can help identify where the null values are coming from.

7. **Update Joomla and Extensions**: Make sure your Joomla installation and all extensions are updated to the latest version. Sometimes, these issues can be resolved by fixes in newer versions.

By following these steps, you should be able to pinpoint where the `null` value is coming from and prevent the warning from appearing.
Raja Pdl
PHP VIP Members
PHP VIP Members
โพสต์: 2241
ลงทะเบียนเมื่อ: 27/05/2024 9:50 am

Re: Q - How to display frontend menu in Joomla 5 custom component ?

โพสต์ที่ยังไม่ได้อ่าน โดย Raja Pdl »

MindPHP Assistant เขียน: 02/01/2025 12:14 am The warning you're seeing is due to passing a `null` value to the `htmlspecialchars()` function somewhere in your component or the way it's being processed by Joomla. This usually happens when the data expected isn't available or has not been set properly.

Here’s a step-by-step guide to resolve the issue within your component:

1. **Check Your XML Definitions**: Ensure that all required fields are properly defined and have default values if necessary. Check that your language constants `COM_HELLO_TEST_LIST` and `COM_HELLO_TEST_LIST_DESC` are defined in your language files.

2. **Review Language Files**: Make sure that there are no missing language strings. Sometimes a missing language string can cause null values. Check your language files in `language/en-GB/en-GB.com_hello.ini` (or equivalent for your language) and ensure `COM_HELLO_TEST_LIST` and `COM_HELLO_TEST_LIST_DESC` are defined.

โค้ด: เลือกทั้งหมด

ini
   COM_HELLO_TEST_LIST="Test List Title"
   COM_HELLO_TEST_LIST_DESC="Description for Test List"
   
3. **Default Values in Code**: If your component is expecting data from the XML file or language strings, make sure it has fallback values in case they are not set. For example, when retrieving language strings in PHP, you can use:

โค้ด: เลือกทั้งหมด

php
   $title = JText::_('COM_HELLO_TEST_LIST');
   if (empty($title)) {
       $title = 'Default Title';
   }
   
4. **Inspect Component Rendering**: Check how the menu items or component content are being rendered. Ensure that you are not passing null values to functions expecting strings. You can add checks like:

โค้ด: เลือกทั้งหมด

php
   $safeString = !empty($variable) ? htmlspecialchars($variable, ENT_QUOTES, 'UTF-8') : '';
   
5. **Menu Item Parameters**: When creating menu items for your component, make sure all required fields are filled out and valid in the Joomla menu manager.

6. **Debugging Output**: Add some temporary debugging output in your component's view or template to log or display values being used. This can help identify where the null values are coming from.

7. **Update Joomla and Extensions**: Make sure your Joomla installation and all extensions are updated to the latest version. Sometimes, these issues can be resolved by fixes in newer versions.

By following these steps, you should be able to pinpoint where the `null` value is coming from and prevent the warning from appearing.

It is not related to language strings. Language values are defined.


In which component-related file can I check the following?

โค้ด: เลือกทั้งหมด

   $safeString = !empty($variable) ? htmlspecialchars($variable, ENT_QUOTES, 'UTF-8') : '';
ภาพประจำตัวสมาชิก
tsukasaz
PHP VIP Members
PHP VIP Members
โพสต์: 23621
ลงทะเบียนเมื่อ: 18/04/2012 9:39 am

Re: Q - How to display frontend menu in Joomla 5 custom component ?

โพสต์ที่ยังไม่ได้อ่าน โดย tsukasaz »

For issues related to the Link, try checking the parts related to the Route.

File: [Admin] com_example/services/provider.php

In this file, has the Route class been registered?

โค้ด: เลือกทั้งหมด

$container->registerServiceProvider(new RouterFactory('\\Joomla\\Component\\Example'));
If it does, the website's frontend must also have a Route file.

File: [Site] com_example/src/Service/Router.php
The last bug isn't fixed until the last user is dead. (Sidney Markowitz, 1995)
Raja Pdl
PHP VIP Members
PHP VIP Members
โพสต์: 2241
ลงทะเบียนเมื่อ: 27/05/2024 9:50 am

Re: Q - How to display frontend menu in Joomla 5 custom component ?

โพสต์ที่ยังไม่ได้อ่าน โดย Raja Pdl »

tsukasaz เขียน: 02/01/2025 3:22 pm For issues related to the Link, try checking the parts related to the Route.

File: [Admin] com_example/services/provider.php

In this file, has the Route class been registered?

โค้ด: เลือกทั้งหมด

$container->registerServiceProvider(new RouterFactory('\\Joomla\\Component\\Example'));
If it does, the website's frontend must also have a Route file.

File: [Site] com_example/src/Service/Router.php
The route is registered in administrator/components/com_example/services/provider.php

โค้ด: เลือกทั้งหมด

public function register(Container $container)
	{
		$container->registerServiceProvider(new MVCFactory('\\Joomla\\Component\\Example'));
		$container->registerServiceProvider(new ComponentDispatcherFactory('\\Joomla\\Component\\Example'));
		$container->registerServiceProvider(new RouterFactory('\\Joomla\\Component\\Example'));
		
		--------------
Could you please provide sample codes for [Site] com_example/src/Service/Router.php ?
ภาพประจำตัวสมาชิก
tsukasaz
PHP VIP Members
PHP VIP Members
โพสต์: 23621
ลงทะเบียนเมื่อ: 18/04/2012 9:39 am

Re: Q - How to display frontend menu in Joomla 5 custom component ?

โพสต์ที่ยังไม่ได้อ่าน โดย tsukasaz »

Raja Pdl เขียน: 05/01/2025 11:32 pm Could you please provide sample codes for [Site] com_example/src/Service/Router.php ?
This sample from com_banners
/components/com_banners/src/Service/Router.php

โค้ด: เลือกทั้งหมด

<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_banners
 *
 * @copyright   (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

namespace Joomla\Component\Banners\Site\Service;

use Joomla\CMS\Component\Router\RouterBase;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Routing class from com_banners
 *
 * @since  3.3
 */
class Router extends RouterBase
{
    /**
     * Build the route for the com_banners component
     *
     * @param   array  $query  An array of URL arguments
     *
     * @return  array  The URL arguments to use to assemble the subsequent URL.
     *
     * @since   3.3
     */
    public function build(&$query)
    {
        $segments = [];

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

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

        foreach ($segments as &$segment) {
            $segment = str_replace(':', '-', $segment);
        }

        return $segments;
    }

    /**
     * Parse the segments of a URL.
     *
     * @param   array  $segments  The segments of the URL to parse.
     *
     * @return  array  The URL attributes to be used by the application.
     *
     * @since   3.3
     */
    public function parse(&$segments)
    {
        $vars  = [];

        foreach ($segments as &$segment) {
            $segment = preg_replace('/-/', ':', $segment, 1);
        }
        unset($segment);

        // View is always the first element of the array
        $count = \count($segments);

        if ($count) {
            $count--;
            $segment = array_shift($segments);

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

        if ($count) {
            $segment = array_shift($segments);

            if (is_numeric($segment)) {
                $vars['id'] = $segment;
            }
        }

        return $vars;
    }
}
Joomla Routing : https://manual.joomla.org/docs/general- ... s/routing/
The last bug isn't fixed until the last user is dead. (Sidney Markowitz, 1995)
Raja Pdl
PHP VIP Members
PHP VIP Members
โพสต์: 2241
ลงทะเบียนเมื่อ: 27/05/2024 9:50 am

Re: Q - How to display frontend menu in Joomla 5 custom component ?

โพสต์ที่ยังไม่ได้อ่าน โดย Raja Pdl »

tsukasaz เขียน: 06/01/2025 1:45 pm This sample from com_banners
/components/com_banners/src/Service/Router.php

โค้ด: เลือกทั้งหมด

<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_banners
 *
 * @copyright   (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

namespace Joomla\Component\Banners\Site\Service;

use Joomla\CMS\Component\Router\RouterBase;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Routing class from com_banners
 *
 * @since  3.3
 */
class Router extends RouterBase
{
    /**
     * Build the route for the com_banners component
     *
     * @param   array  $query  An array of URL arguments
     *
     * @return  array  The URL arguments to use to assemble the subsequent URL.
     *
     * @since   3.3
     */
    public function build(&$query)
    {
        $segments = [];

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

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

        foreach ($segments as &$segment) {
            $segment = str_replace(':', '-', $segment);
        }

        return $segments;
    }

    /**
     * Parse the segments of a URL.
     *
     * @param   array  $segments  The segments of the URL to parse.
     *
     * @return  array  The URL attributes to be used by the application.
     *
     * @since   3.3
     */
    public function parse(&$segments)
    {
        $vars  = [];

        foreach ($segments as &$segment) {
            $segment = preg_replace('/-/', ':', $segment, 1);
        }
        unset($segment);

        // View is always the first element of the array
        $count = \count($segments);

        if ($count) {
            $count--;
            $segment = array_shift($segments);

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

        if ($count) {
            $segment = array_shift($segments);

            if (is_numeric($segment)) {
                $vars['id'] = $segment;
            }
        }

        return $vars;
    }
}
Joomla Routing : https://manual.joomla.org/docs/general- ... s/routing/

By using the sample code from com_banners and replacing it with my component name, this bug was resolved.
Thank you very much.
ตอบกลับโพส
  • Similar Topics
    ตอบกลับ
    แสดง
    โพสต์ล่าสุด

ผู้ใช้งานขณะนี้

สมาชิกกำลังดูบอร์ดนี้: ไม่มีสมาชิกใหม่ และบุคลทั่วไป 1