Joomla 组件路由器
Joomla component router
我正在尝试按照此文档页面上的说明进行操作,但我似乎遗漏了一些东西:
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
这是有效的,因为我没有直接从菜单项导航到页面。有一个顶级菜单,然后是协议的 link 页面。每个项目都有一个隐藏菜单,但那不是我关注的 link。
$app = JFactory::getApplication()->getMenu();
$customermaster = $app->getItems( 'link', 'index.php?option=com_component&view=legal&page=customermasteragreement', true );
JRoute::_('index.php?Itemid='.$customermaster->id);
除非我完全误解了 Joomla(我已经用它开发了四五年),否则没有 "sub-view" 概念得到实施。我认为尝试使用这个想法会给您带来麻烦。
令我震惊的是,使用可视化调试器的想法如此不受欢迎。
给自己找个类似 Netbeans 的东西(也有其他的),设置本地 Web 和数据库服务器,然后观看代码 运行。很快(好吧,相对来说)你就会开始理解这个结构是如何联系在一起的。
您可以在您的视图中放置代码,以获取您设置的额外参数并相应地显示或隐藏内容,但没有 "sub-view"。
你有一个 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;
}
此外,函数 ComponentBuildRoute
、ComponentParseRoute
必须以您的组件名称开头,而不是 Component
。
编辑
[componentname]BuildRoute
和 [componentname]ParseRoute
已弃用,您应该坚持扩展 JComponentRouterBase
的 class,因为您在更新的第二个示例中有它。在这里试试这个,看看它是否有效:
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
URL 由 JRoute
在路由器 class 添加到 router.php
之前生成:http://j3.dev.lytrax.net/index.php/component/ola/?page=test_page&view=ola
SEO URL 在创建 router.php
并使用上面的路由器 class 后由 JRoute::_('index.php?option=com_ola&page=test_page&view=ola');
返回:http://j3.dev.lytrax.net/index.php/component/ola/ola/test_page
如果您访问这些链接,您会看到一切正常,您甚至可以看到调用组件 [=22] 的 page
、view
和 JRoute
结果=].
我正在尝试按照此文档页面上的说明进行操作,但我似乎遗漏了一些东西: 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 这是有效的,因为我没有直接从菜单项导航到页面。有一个顶级菜单,然后是协议的 link 页面。每个项目都有一个隐藏菜单,但那不是我关注的 link。
$app = JFactory::getApplication()->getMenu();
$customermaster = $app->getItems( 'link', 'index.php?option=com_component&view=legal&page=customermasteragreement', true );
JRoute::_('index.php?Itemid='.$customermaster->id);
除非我完全误解了 Joomla(我已经用它开发了四五年),否则没有 "sub-view" 概念得到实施。我认为尝试使用这个想法会给您带来麻烦。
令我震惊的是,使用可视化调试器的想法如此不受欢迎。 给自己找个类似 Netbeans 的东西(也有其他的),设置本地 Web 和数据库服务器,然后观看代码 运行。很快(好吧,相对来说)你就会开始理解这个结构是如何联系在一起的。
您可以在您的视图中放置代码,以获取您设置的额外参数并相应地显示或隐藏内容,但没有 "sub-view"。
你有一个 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;
}
此外,函数 ComponentBuildRoute
、ComponentParseRoute
必须以您的组件名称开头,而不是 Component
。
编辑
[componentname]BuildRoute
和 [componentname]ParseRoute
已弃用,您应该坚持扩展 JComponentRouterBase
的 class,因为您在更新的第二个示例中有它。在这里试试这个,看看它是否有效:
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
URL 由 JRoute
在路由器 class 添加到 router.php
之前生成:http://j3.dev.lytrax.net/index.php/component/ola/?page=test_page&view=ola
SEO URL 在创建 router.php
并使用上面的路由器 class 后由 JRoute::_('index.php?option=com_ola&page=test_page&view=ola');
返回:http://j3.dev.lytrax.net/index.php/component/ola/ola/test_page
如果您访问这些链接,您会看到一切正常,您甚至可以看到调用组件 [=22] 的 page
、view
和 JRoute
结果=].