【问题标题】:Joomla component routerJoomla 组件路由器
【发布时间】:2017-07-21 08:30:28
【问题描述】:

我正在尝试按照此文档页面上的说明进行操作,但我似乎遗漏了一些东西: https://docs.joomla.org/Supporting_SEF_URLs_in_your_component

需要修正的URI是:index.php?com_component&view=legal&page=customermasteragreement

看起来路由功能应该很简单,但是页面只是显示默认而不是子视图。

这是我当前的代码:

function ComponentBuildRoute(&$query)
{
    $segments = array();
        if (isset($query['view'])) {
            $segments[] = $query['view'];
            unset($query['view']);
       }
        if (isset($query['page'])) {
            $segments[] = $query['page'];
            unset($query['page']);
    }

    return $segments;
}

function ComponentParseRoute($segments)
{
       $vars = array();
       switch($segments[0])
       {
               case 'legal':
                       $vars['view'] = 'legal';
                       break;
               case 'customermasteragreement':
                       $vars['page'] = 'customermasteragreement';
                       break;

       }

       return $vars;
}

更新 此代码用于显示子页面,但它给了我一个类似的 URI:legal-agreements/legal?page=customermasteragreement

class ComponentRouter extends JComponentRouterBase {

    public function build(&$query) {
        $segments = array();
        $view = null;

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

            unset($query['view']);
        }

        if (isset($query['id'])) {
            if ($view !== null) {
                $segments[] = $query['id'];
            } else {
                $segments[] = $query['id'];
            }

            unset($query['id']);
        }

        return $segments;
    }


    public function parse(&$segments) {

        $vars = array();

        // View is always the first element of the array
        $vars['view'] = array_shift($segments);

        return $vars;
    }
}

编辑 2

如果有帮助,这是我的模型和视图

models/legal.php

// import Joomla modelitem library
jimport('joomla.application.component.modelitem');

class ComponentModelLegal extends JModelItem {
    public function __construct($config = array())
            {
       JLoader::register('ComponentHelper', JPATH_COMPONENT_ADMINISTRATOR . '/helpers/component.php');
       parent::__construct($config);
            }

    /**
     * 
     * @return string
     */
    public function getLegal() {
        $app = JFactory::getApplication();
        $page = $app->input->get('page', '', 'STRING');

        if ($page) {
            ComponentHelper::add('type', $page);   //This is an API request to an external service, returning JSON formatted data
            $legal = ComponentHelper::getData('commons/legal-agreements.json', TRUE);


            if (isset($legal[0]['status'])) {
                JError::raiseError(400, $legal[0]['ERROR']);
                return false;
            } else {
                if (!isset($this->legal)) {
                    $this->legal = $legal;
                }
                return $this->legal;
            }
        }
    }

}

views/legal/view.html.php

class ComponentViewLegal extends JViewLegacy {
    function display($tpl = null) {
        // Assign data to the view
        $this->legal = $this->get('legal');

        // Check for errors.
        if (count($errors = $this->get('Errors'))) {
            JLog::add(implode('<br />', $errors), JLog::WARNING, 'jerror');
            return false;
        }

        // Display the view
        parent::display($tpl);
    }
}

views/legal/tmpl/default.php

$page = JRequest::getVar('page');
$pages = array(
    'resellermasteragreement',
    'customermasteragreement',
    'resellerdomainagreement',
    'customerdomainagreement',
    'resellerwebserviceagreement',
    'customerwebserviceagreement',
    'resellerdigicertagreement',
    'customerdigicertagreement',
    'registraragreement',
    'customerhostingproductagreement',
    'resellerhostingproductagreement'
);

    ?>
    <div class="col-lg-12">
        <?php 
        echo in_array($page, $pages) ? $this->loadTemplate('legal') : $this->loadTemplate('home');
        ?>
    </div>

views/legal/tmpl/default_legal.php

$page = JRequest::getVar('page');

echo nl2br(htmlspecialchars($this->legal[$page]['defaultagreement'], ENT_NOQUOTES, "UTF-8"));
?>
<a type="button" class="btn btn-primary" href="<?php echo JROUTE::_("index.php?option=com_component&view=legal"); ?>">Back</a>

编辑 3 这是有效的,因为我没有从菜单项直接导航到页面。有一个顶级菜单,然后是一个页面,一个指向协议的链接。我对每个项目都有一个隐藏菜单,但这不是我关注的链接。

$app = JFactory::getApplication()->getMenu();
$customermaster = $app->getItems( 'link', 'index.php?option=com_component&view=legal&page=customermasteragreement', true );
JRoute::_('index.php?Itemid='.$customermaster->id); 

【问题讨论】:

    标签: php joomla joomla3.0


    【解决方案1】:

    您有一个view,但当您捕获view 参数时,您实际上并没有正确设置page 参数,但是您将page 视为另一种观点的王者。你可以试试这个并检查它是否有效:

    function [componentname]ParseRoute($segments)
    {
        $vars = array();
        switch($segments[0])
        {
            case 'legal':
                $vars['view'] = 'legal';
                $vars['page'] = $segments[1];
                break;
        }
    
        return $vars;
    }
    

    此外,函数ComponentBuildRouteComponentParseRoute 必须以您的组件名称而不是Component 开头。

    编辑

    [componentname]BuildRoute[componentname]ParseRoute 已被弃用,您应该保留扩展 JComponentRouterBase 的类,就像在更新的第二个示例中一样。在这里试试这个,看看它是否有效:

    class ComponentRouter extends JComponentRouterBase {
    
        public function build(&$query) {
            $segments = array();
            $view = null;
    
            if (isset($query['view'])) {
                $segments[] = $query['view'];
                $view = $query['view'];
    
                unset($query['view']);
            }
    
            if (isset($query['page'])) {
                $segments[] = $query['page'];
                unset($query['page']);
            }
    
            return $segments;
        }
    
        public function parse(&$segments) {
    
            $vars = array();
    
            // View is always the first element of the array
            $vars['view'] = array_shift($segments);
            if(count($segments) > 0)
                $vars['page'] = array_shift($segments);
    
            return $vars;
        }
    }
    

    编辑 2

    我有一个测试 Joomla 3 站点,其中包含一个名为 Ola 的简单组件。

    非 SEO 组件 URL:http://j3.dev.lytrax.net/index.php?option=com_ola&page=test_page&view=ola

    在Router类添加到router.php之前由JRoute生成的URL:http://j3.dev.lytrax.net/index.php/component/ola/?page=test_page&view=ola

    JRoute::_('index.php?option=com_ola&amp;page=test_page&amp;view=ola');在创建router.php并使用上面的Router类后返回的SEO URL:http://j3.dev.lytrax.net/index.php/component/ola/ola/test_page

    如果您访问这些链接,您会发现一切正常,您甚至可以看到调用组件OlapageviewJRoute 结果。

    【讨论】:

    • 除非我的组件名称是“组件”。 :)
    • @JamesShaver 当然。我只是写这个来澄清正确的名称需要在类/函数的开头。请尝试我更新的课程,看看它是否如您所愿。
    • 现在出现 404 错误:未找到视图 [名称、类型、前缀]:视图、html、componentView。
    • 它对我有用。我创建了一个名为 Ola 的测试组件,并添加了一个简单的默认视图、一个页面参数和路由,与我在答案中的完全一样。您是否包含index.php 来测试 SEO URL?
    • 我会接受你的回答,因为我的下一个问题似乎与路由器无关。谢谢!
    【解决方案2】:

    除非我完全误解了 Joomla(我已经用它开发了四五年),否则没有实施“子视图”概念。我认为尝试使用这个想法会给你带来麻烦。

    我很惊讶使用可视化调试器的想法如此不受欢迎。 让自己像 Netbeans 一样(还有其他的),设置本地 Web 和数据库服务器,然后观察代码运行。非常(嗯,相对非常)很快,您就会开始理解结构是如何连接在一起的。

    您可以在视图中放置代码,以获取您设置的额外参数并相应地显示或隐藏内容,但没有“子视图”。

    【讨论】:

    • 实际上我确实使用过 NetBeans,以及 PHPStorm 和 Visual Studio Code。在这种情况下,子视图只是带有 JRequest::getVar('page') 开关的普通视图。从那里加载另一个文件只是将其查找为 $this->loadTemplate('legal')
    • 查看 com_content 或 com_newsfeeds。他们都有相同的概念。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-15
    • 1970-01-01
    • 2015-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多