Yii2: yii\web\UrlManager does'nt make user-friendly urls - php

Here's urlManager configs:
return [
'class' => \yii\web\UrlManager::class,
'enablePrettyUrl' => true,
'showScriptName' => false,
'baseUrl' => '',
'rules' => [
'page/<id:[\\w-_]+>' => 'page/index',
],
];
Here's urlManager using:
$menuItems = [
[
'label' => 'Home',
'url' => Yii::$app->urlManager->createAbsoluteUrl(['/page']),
],
[
'label' => 'About',
'url' => Yii::$app->urlManager->createAbsoluteUrl(['/page', 'id' => 'about']),
],
[
'label' => 'Contact',
'url' => Yii::$app->urlManager->createAbsoluteUrl(['/page', 'id' => 'contact']),
],
];
And here's results from browser:
http://localhost/page?id=about
http://localhost/page?id=contact
What's wrong in my code?

You need to use exact route when creating URLs:
$menuItems = [
[
'label' => 'Home',
'url' => Yii::$app->urlManager->createAbsoluteUrl(['/page']),
],
[
'label' => 'About',
'url' => Yii::$app->urlManager->createAbsoluteUrl(['/page/index', 'id' => 'about']),
],
[
'label' => 'Contact',
'url' => Yii::$app->urlManager->createAbsoluteUrl(['/page/index', 'id' => 'contact']),
],
];

Related

Extend an assiociative Array with variable

can someone help me, how I can extend an assiociative array with a variable?
I have a loop (foreach):
foreach($this->getWarehouseListForm() as $wareHouse) {
$wareHouseList[] =
[
"title" => "wareHouse[105]",
"form" => [
"storeId[105]" => [
"type" => "inputText",
"options" => [
"name" => "TSL",
],
],
],
];
}
And I want to extend a object like this:
"sections" => [
[
"title" => 'Schuhe24Assistant.ftpServerTitle',
"description" => 'Schuhe24Assistant.ftpServerDescription',
"form" => [
"ftpServer" => [
'type' => 'text',
'defaultValue' => 'ftp.hisasp2.com',
'options' => [
'name' => 'Schuhe24Assistant.ftpServer',
'required' => true,
]
],
"ftpUser" => [
'type' => 'text',
'defaultValue' => 'username',
'options' => [
'name' => 'Schuhe24Assistant.ftpUser',
'required' => true,
]
],
"ftpPassword" => [
'type' => 'text',
'defaultValue' => 'password',
'options' => [
'name' => 'Schuhe24Assistant.ftpPassword',
#'isPassword' => true,
'required' => true,
],
],
"deleteFiles" => [
'type' => 'toggle',
'defaultValue' => true,
'options' => [
'name' => 'Schuhe24Assistant.deleteFiles',
],
],
],
],
], $wareHouseList
But this code produces nothing (no error output) and the structure check fails in this case. If I remove the variable, the structure check is OK.
Can someone help me out?
Kind regards
Henning
Push your $wareHouseList array into the $sections array in the following ways
$sections['wareHouseList'] = $wareHouseList
It should be working.

urlManager for module Yii2

I've got a basic Yii2 project, in which i created a separate module "rest". I have set up urlManager in config/web.php file. It works fine for common url, but it seems to me it is not working with url starting with my module name: rest/.. I have actionAuth() in AuthController in my rest module, and it is accessible with this url: test.ru/auth/auth. But i want it to be accessible with this url:test.ru/auth. I tried to write like this in web.php :
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => 'rest\auth',
'extraPatterns' => [
'POST /' => 'auth',
],
'pluralize' => false,
],
],
],
But it does not work(not found error in browser).
I also tried like this:
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => 'rest\auth',
'extraPatterns' => [
'POST rest/auth' => 'auth',
],
'pluralize' => false,
],
],
],
It seems to me that urlManager does not want to work for module. Next i tried to write the same code in my Module.php in rest/ directory. But it produced many errors. I think because of the same error things like that dont work too:`
'class' => 'yii\rest\UrlRule',
'controller' => 'rest\city',
'extraPatterns' => [
'DELETE {id}' => 'delete',
],
`
So my question is: how to set up urlManager for module in Yii2? I need to configure HTTP DELETE method, post methods work without any settings in urlManager.
The whole web.php file:
<?php
$params = require(__DIR__ . '/params.php');
$config = [
'id' => 'basic',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'language' => 'ru',
'components' => [
'authManager' => [
'class' => 'yii\rbac\DbManager',
],
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => 'xxxxxxx',
'parsers' => [
'application/json' => 'yii\web\JsonParser',
]
],
'cache' => [
'class' => 'yii\caching\FileCache',
],
'user' => [
'identityClass' => 'app\models\User',
// 'loginUrl' => ['site/login'],
],
'errorHandler' => [
'errorAction' => 'site/error',
],
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
// send all mails to a file by default. You have to set
// 'useFileTransport' to false and configure a transport
// for the mailer to send real emails.
'useFileTransport' => true,
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'db' => require(__DIR__ . '/db.php'),
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => 'rest\user',
'except' => ['delete', 'create', 'update', 'index'],
'extraPatterns' => [
'GET all' => 'all',
]
],
[
'class' => 'yii\rest\UrlRule',
'controller' => 'rest\auth',
'extraPatterns' => [
'POST reg' => 'reg',
'POST auth' => 'auth',
'POST rest/auth' => 'auth',
],
'pluralize' => false,
],
[
'class' => 'yii\rest\UrlRule',
'controller' => 'rest\city',
'extraPatterns' => [
'DELETE {id}' => 'delete',
],
],
],
],
'i18n' => [
'translations' => [
'*' => [
'class' => 'yii\i18n\PhpMessageSource',
// 'basePath' => '#app/messages', // if advanced application, set #frontend/messages
'sourceLanguage' => 'en',
'fileMap' => [
//'main' => 'main.php',
],
],
],
],
],
'modules' => [
'admin' => [
'class' => 'app\modules\admin\Module',
],
'manager' => [
'class' => 'app\modules\manager\Module',
],
'rest' => [
'class' => 'app\modules\rest\Module',
],
'rbac' => [
'class' => 'mdm\admin\Module',
'controllerMap' => [
'assignment' => [
'class' => 'mdm\admin\controllers\AssignmentController',
/* 'userClassName' => 'app\models\User', */
'idField' => 'id',
'usernameField' => 'username',
],
],
'layout' => 'left-menu',
'mainLayout' => '#app/views/layouts/admin.php',
]
],
'aliases' => [
//'#mdm/admin' => 'app/mdm/admin',
],
'params' => $params,
];
if (YII_ENV_DEV) {
// configuration adjustments for 'dev' environment
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = [
'class' => 'yii\debug\Module',
// uncomment the following to add your IP if you are not connecting from localhost.
//'allowedIPs' => ['127.0.0.1', '::1'],
];
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
'class' => 'yii\gii\Module',
// uncomment the following to add your IP if you are not connecting from localhost.
//'allowedIPs' => ['127.0.0.1', '::1'],
];
}
return $config;
My Module.php code(commented code shows my attempt to write urlManager):
<?php
namespace app\modules\rest;
/**
* rest module definition class
*/
class Module extends \yii\base\Module
{
/**
* #inheritdoc
*/
public $controllerNamespace = 'app\modules\rest\controllers';
/**
* #inheritdoc
*/
public function init()
{
parent::init();
// custom initialization code goes here
\Yii::$app->user->enableSession = false;
$config = [
'components' => [
'basePath' => dirname(__DIR__),
// 'user' => [
// 'identityClass' => 'app\models\User',
// 'class' => 'app\models\User',
// 'enableSession' => false
// ],
// 'urlManager' => [
// 'enablePrettyUrl' => true,
// 'enableStrictParsing' => true,
// 'showScriptName' => false,
// 'rules' => [
// [
// 'class' => 'yii\rest\UrlRule',
// 'controller' => 'rest\city',
// 'extraPatterns' => [
// 'DELETE {id}' => 'delete',
// ],
// ],
// ],
// ],
'response' => [
'format' => \yii\web\Response::FORMAT_JSON,
'charset' => 'UTF-8',
'class' => 'yii\web\Response',
'on beforeSend' => function ($event) {
$response = $event->sender;
if(( $response->statusCode >= 200) && ( $response->statusCode < 300)) {
if(isset($response->data['_appErr'])) {
unset($response->data['_appErr']);
$response->data = [
'success' => false,
'error' => $response->data,
'data' => null,
];
} else {
$response->data = [
'success' => $response->isSuccessful,
'error' => null,
'data' => $response->data,
];
}
} else {
if($response->statusCode == 401) {
$response->data = [
'success' => false,
'error' => [
'code' => 9,
'message' => 'Unauthorized',
'user_msg' => 'You need to be authorized',
],
'data' => null,
];
}
// else {
// $response->data = [
// 'success' => false,
// 'error' => [
// 'code' => 1,
// 'message' => 'server has returned '.$response->statusCode.' error',
// ],
// 'data' => null,
// ];
// }
}
},
],
],
];
\Yii::configure(\Yii::$app, $config);
}
}
Try this:
namespace yii\rest;
class UrlRule extends Object implements UrlRuleInterface {
public function parseRequest($manager, $request) {
list($e1, $e2) = sscanf($request->getPathInfo(), '%[a-zA-Z]/%[a-zA-Z]');
if ($e1 === 'auth' && $e2 === '') {
return ['/auth/auth', $request->queryParams];
}
return false;
}
}
Use forward slash(/) while defining the controller value in the rules array.
This will work:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => 'rest/user',
'except' => ['delete', 'create', 'update', 'index'],
'extraPatterns' => [
'GET all' => 'all',
]
],
[
'class' => 'yii\rest\UrlRule',
'controller' => 'rest/auth',
'extraPatterns' => [
'POST reg' => 'reg',
'POST auth' => 'auth',
],
'pluralize' => false,
],
[
'class' => 'yii\rest\UrlRule',
'controller' => 'rest/city',
'extraPatterns' => [
'DELETE {id}' => 'delete',
],
],
]
Check out the documentation here: http://www.yiiframework.com/doc-2.0/guide-rest-versioning.html

YII2: How can I create a link/url in a Menu item to point to an external webpage instead of an action or view of my application

I am using the YII2 Menu Widget and did not find the solution to add attribute options like class , target on created link.
My code is below:
echo Menu::widget(
[
'options' => [
'class' => 'sidebar-menu'
],
'items' => [
[
'label' => Yii::t('backend', 'Admin'),
'url' => Yii::$app->homeUrl,
'icon' => 'fa-list-alt',
'options' => [
'class' => 'treeview',
],
'items' => [
[
'label' => Yii::t('backend', 'External link'),
'url' => 'http://google.com',
'icon' => 'fa-list-alt',
'options' => [
'target' => '_blank',
],
],
]
],
]
]
);
Option target is not added on generated link.
add the target like below through the template setting. The Options you have set in your code are the Html Options of the li element and not the link options.
'items' => [
[
'label' => Yii::t('backend', 'External link'),
'url' => 'http://google.com',
'icon' => 'fa-list-alt',
'template'=> '{label}',
],
]
Suggestions above do not seem to be working (in my case), an alternative solution is:
'linkOptions' => ['target' => '_blank']
For example
[
'url' => \Yii::$app->user->identity->getBlogLink(),
'linkOptions' => ['target' => '_blank'] ,
'label' => \Yii::t('app', 'Blog')
]
If you want to keep the icon in your menu:
'template'=> '{icon}{label}'
As regards the class you must specify it in the options key:
[
'label' => 'Debug',
'icon' => 'fa fa-dashboard',
'url' => ['/debug'],
'options' => ['class' => 'special'],
'template'=> '{icon}{label}',
],
gives the following menu:
<li class="special">
<a target="_blank" href="your_site_url_here/index.php?r=debug">
<i class="fa fa-dashboard"></i>
<span>Debug</span>
</a>
</li>
You can add any url. For Example,
echo Menu::widget([
'items' => [
['label' => 'Home', 'url' => ['http://www.google.com']],
['label' => 'About', 'url' => ['site/about']],
['label' => 'Contact', 'url' => ['site/contact']],
],
'options' => [
'class' => 'navbar-nav nav',
'id'=>'navbar-id',
'style'=>'font-size: 14px;',
'data-tag'=>'yii2-menu',
],
]);

Yii2 URL manager doesn't parse the rule

I'm trying to use Yii URL manager to rewrite URLs like /site/about?tab=value to site/about/value or site/value.
My rule /<tab:\w+>' => 'site/about doesn't work. Here is the full URL manager code:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' =>
[
'/' => 'site/index',
'/deals' => '/deal/deals',
'/<tab:\w+>' => 'site/about', //my rule
'/about' => 'site/about',
'/<action:[\-\w]+>' => 'site/<action>',
'/<module:\w+>' => '<module>/default/index',
'/<module:\w+>/<controller:\w+>/<id:\d+>' => '/<module>/<controller>/view',
'/<module:\w+>/<controller:\w+>/<id:\d+>/<action:[\-\w]+>/<entity_id:\d+>' => '/<module>/<controller>/<action>',
'/<module:\w+>/<controller:\w+>/<id:\d+>/<action:[\-\w]+>' => '/<module>/<controller>/<action>',
'/<controller:\w+>/<id:\d+>' => '<controller>/view',
'/<controller:\w+>/<id:\d+>/<action:[\-\w]+>/<entity_id:\d+>' => '<controller>/<action>',
'/<controller:\w+>/<id:\d+>/<action:[\-\w]+>' => '<controller>/<action>',
'/<controller:\w+>/<action:[\-\w]+>' => '<controller>/<action>',
'/<module:\w+>/<action:[\-\w]+>' => '<module>/default/<action>',
'/<module:\w+>/<controller:\w+>' => '<module>/<controller>/index',
],
And here is the widget code:
echo Nav::widget([
'items' => [
['label' => '1', 'url' => ['/site/about', 'tab' => '']],
['label' => '2', 'url' => ['/site/about', 'tab' => 'value']],
['label' => '3', 'url' => ['site/about', 'tab' => 'tariffs']],
['label' => '4', 'url' => ['site/about', 'tab' => 'team']],
['label' => '5', 'url' => ['site/about', 'tab' => 'documents']],
],
'options' => ['class' =>'nav-pills nav-stacked c-nav'],
]);
You should use named parameters, but you are naming the module/controller part.
You can only use these 3 reserved words:
module, controller, action
like the docs examples:
[
'<controller:(post|comment)>/<id:\d+>/<action:(create|update|delete)>' => '<controller>/<action>',
'<controller:(post|comment)>/<id:\d+>' => '<controller>/view',
'<controller:(post|comment)>s' => '<controller>/index',
]
But you are using <tab:\w+> that doesn't means anything for the rules section
Probably you could use:
'/site/about/<tab:\w+>' => 'site/about',
to catch URLs like:
web.com/site/about/bla
And then in the controller you could use the $tab variable like
namespace app\controllers;
class SiteController extends \yii\web\Controller {
public function actionAbout($tab)
{
return $this->renderContent("Hello $tab");
}
}
Hope this helps.
The problem was that some rules like /<controller:\w+>/<action:[\-\w]+>' => '<controller>/<action> and /<action:[\-\w]+>' => 'site/<action> were parsed earlier than mine, so I changed them.
Here is my solution:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' =>
[
'/' => 'site/index',
'<tab:(about)>' => 'site/about',
'/about/<tab:(about|value|documents|tariffs|team)>' => 'site/about',
'/<action:(index|login|logout|contact|signup|request-password-reset|reset-password|thank-for-register|connect-inviteduser)>' => 'site/<action>',
'/<controller:(deal)>/<action:\w>' => 'deal/<action>',
'/<module:(trades)>' => '<module>/default/index',
'/<module:(trades)>/<controller:\w+>/<id:\d+>' => '/<module>/<controller>/view',
'/<module:(trades)>/<controller:\w+>/<id:\d+>/<action:[\-\w]+>/<entity_id:\d+>' => '/<module>/<controller>/<action>',
'/<module:(trades)>/<controller:\w+>/<id:\d+>/<action:[\-\w]+>' => '/<module>/<controller>/<action>',
'/<controller:\w+>/<id:\d+>' => '<controller>/view',
'/<controller:\w+>/<id:\d+>/<action:[\-\w]+>/<entity_id:\d+>' => '<controller>/<action>',
'/<controller:\w+>/<id:\d+>/<action:[\-\w]+>' => '<controller>/<action>',
'/<module:(trades)>/<action:[\-\w]+>' => '<module>/default/<action>',
'/<module:(trades)>/<controller:\w+>' => '<module>/<controller>/index',
],
],
The widget code:
<?php
echo Nav::widget([
'items' => [
['label' => 'О проекте', 'url' => ['/site/about', 'tab' => 'about']],
['label' => '5 причин работать через портал', 'url' => ['/site/about', 'tab' => 'value']],
['label' => 'Продвижение и тарификация', 'url' => ['site/about', 'tab' => 'tariffs']],
['label' => 'Проектная команда', 'url' => ['site/about', 'tab' => 'team']],
['label' => 'Документы', 'url' => ['site/about', 'tab' => 'documents']],
],
'options' => ['class' =>'nav-pills nav-stacked c-nav'],
]);
?>
And the action code:
public function actionAbout($tab = 'about')
{
$this->layout = '/about';
$tab = $tab == 'about' ? 'index' : $tab;
if (Yii::$app->request->isAjax)
return $this->renderPartial('about/' . $tab);
else
return $this->render('about/' .$tab);
}

As in Yii 2.0 (Menu :: Widget ) use the span?

When I use the following code, the end result is " TEST " and should be "TEST" in the tags .
echo Menu::widget([
'options' => ['id' => 'navigate'],
'items' => [
[
'label' => '<span>TEST</span>',
'url' => ['#'],
],
['label' => '<span>TEST2</span>', 'url' => ['#']],
],
]);
I know I should use encodeLabel but does not work and returns an error. Can you do to help?
It works fine for me:
echo Menu::widget([
'options' => ['id' => 'navigate'],
'encodeLabels' => false,
'items' => [
[
'label' => '<span>TEST</span>',
'url' => ['#'],
],
['label' => '<span>TEST2</span>', 'url' => ['#']],
],
]);

Categories