Dominus77 / yii2-advanced-start

Yii2 Start Project Advanced Template

Home Page:https://dominus77.github.io/yii2-advanced-start/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

UrlManager issue

polinwei opened this issue · comments

Hi Sir:

The URL : http://myweb.com/blogs/detail?id=1 is workable , I want to show http://myweb.com/blogs/detail/1 .

Therefore, I add the url rule below. URL display is correct but when I click , I got Not Found (#404) .
Use the http://myweb.com/blogs/detail/1 is workable , How to fix it?

'blogs' => 'blog/post/index',
'blogs/detail' => 'blog/post/detail',
'<controller:\w+>/<id:\d+>'=>'<controller>/detail',

Full URL rule

        // Rules
        $app->getUrlManager()->addRules(
            [
                // blog frontend
                'blogs' => 'blog/post/index',
                'blogs/detail' => 'blog/post/detail',
                '<controller:\w+>/<id:\d+>'=>'<controller>/detail',

            	// blog backend
            	'blog/post' => 'blog/post/index',
                'blog/comment' => 'blog/comment/index',

                // CRUD 
                'blog/post/<id:\d+>/<_a:[\w\-]+>' => 'blog/post/<_a>',
            	'blog/post/<_a:[\w\-]+>' => 'blog/post/<_a>',
                'blog/comment/<id:\d+>/<_a:[\w\-]+>' => 'blog/comment/<_a>',
            	'blog/comment/<_a:[\w\-]+>' => 'blog/comment/<_a>',

            ]
        );

Hi!

'blogs' => 'blog/post/index',
//'blogs/detail' => 'blog/post/detail',
'blogs/<_a:[\w\-]+>/<id:\d+>'=>'blog/<_c>/<_a>',
// Rules
        $app->getUrlManager()->addRules(
            [
                // blog frontend
                'blogs' => 'blog/post/index',
                //'blogs/detail' => 'blog/post/detail',
                'blogs/<_a:[\w\-]+>/<id:\d+>'=>'blog/<_c>/<_a>',

            	// blog backend
            	//'blog/post' => 'blog/post/index',
                'blog/comment' => 'blog/comment/index',

                // CRUD 
                'blog/post/create' => 'blog/post/create',
                'blog/post/<id:\d+>/<_a:[\w\-]+>' => 'blog/post/<_a>',
                'blog/comment/create' => 'blog/comment/create',
                'blog/comment/<id:\d+>/<_a:[\w\-]+>' => 'blog/comment/<_a>',
            ]
        );

Hi Sir:
I tried. The URL will change to http://myweb.com/blogs/detail?id=1 , and still got Not Found (#404)

If I use the rule below, URL display is right , But it will direct to http://myweb.com/blogs/1 which got Not Found (#404) .
I manual type http://myweb.com/blogs/detail/1 is workable

'blogs' => 'blog/post/index',
'blogs/detail' => 'blog/post/detail',
'<controller:\w+>/<id:\d+>'=>'<controller>/detail',

http://myweb.com/blogs/detail?id=1
and
http://myweb.com/blog/detail?id=1
There is a difference?

'<controller:\w+>/<id:\d+>'=>'<controller>/detail',
Replaced by
'blogs/<_a:\w+>/<id:\d+>'=>'blog/<_c>/detail',
http://myweb.com/blogs/detail/1
Replaced by
'blogs/<id:\d+>'=>'blog/<controller>/detail',
http://myweb.com/blogs/1

To avoid confusion, delete all the rules and add one at a time

I use blogs in frontend , blog in the backend

model: Post

    public function getUrl()
    {
        return Yii::$app->urlManager->createUrl([
            'blogs/detail',
            'id'=>$this->id,
        ]);
    }

on Control : PostController

    public function actionDetail($id)
    {
 ...
}

url

Yes

Example Group Rule:

        $app->getUrlManager()->addRules(
            [
                // Group
                [
                    'class' => 'yii\web\GroupUrlRule',
                    'prefix' => 'blogs',                    
                    'rules' => [
                        'post/<id:\d+>/<_a:[\w\-]+>' => 'post/<_a>',                        
                    ],
                ],
                // Rules               
                '/blog/post/<id:\d+>/<_a:[\w\-]+>' => '/blog/post/<_a>',
            ]
        );

Create Url:

$url1 = Url::to(['/blog/post/view', 'id' => 1]);
$url2 = Url::to(['/blogs/post/view', 'id' => 1]);
VarDumper::dump($url1, 10, 1);
VarDumper::dump($url2, 10, 1);

Result:

'/blog/post/1/view' '/blogs/post/1/view' 

http://www.yiiframework.com/doc-2.0/yii-web-groupurlrule.html

If you use 1 URL for the backend and frontend
for example
$url1 = Url::to(['/blog/post/detail', 'id' => 1]);
But I want it to be displayed in different ways, then as an option you can use different Bootstrap.php
BootstrapFrontend.php
and
BootstrapBackend.php
with its rules.

What would not to repeat the code, redefine from the general Bootstrap.php

And connect to the frontend BootstrapFrontend.php
For backend BootstrapBackend.php

/modules/blog/BootstrapFrontend.php

<?php
namespace modules\blog;

class BootstrapFrontend extends Bootstrap {
    
    public function bootstrap($app)
    {
        $app->getUrlManager()->addRules(
            [
                // Rules frontend
                'blogs/<_a:[\w\-]+>/<id:\d+>'=>'blog/<_c>/<_a>', // http://myweb.com/blogs/detail/1
                //...
            ]
        );
        parent::bootstrap($app);
    }
}

/frontend/config/main.php

$config = [
    //...
    'bootstrap' => [
        'log',
        'modules\blog\BootstrapFrontend',
        //...
    ],
    //...
]

Similarly for the backend
/modules/blog/BootstrapBackend.php

<?php
namespace modules\blog;

class BootstrapBackend extends Bootstrap {
    
    public function bootstrap($app)
    {
        $app->getUrlManager()->addRules(
            [
                // Rules backend
                'blog/<_a:[\w\-]+>/<id:\d+>'=>'blog/<_c>/<_a>', // http://myweb.com/admin/blog/detail/1
                //...
            ]
        );
        parent::bootstrap($app);
    }
}

/backend/config/main.php

$config = [
    //...
    'bootstrap' => [
        'log',
        'modules\blog\BootstrapBackend',
        //...
    ],
    //...
]

Do this you mean it?

Why the controller blogs?

model: Post

    public function getUrl()
    {
        return Yii::$app->urlManager->createUrl([
            'blogs/detail',
            'id'=>$this->id,
        ]);
    }

Necessary:

    public function getUrl()
    {
        return Url::to(['/blog/post/detail', 'id' => $this->id]);
    }

Or

    public function getUrl()
    {
        return Yii::$app->urlManager->createUrl([
             '/blog/post/detail',
             'id'=>$this->id,
         ]);
    }

Rule:
'blogs/<_a:[\w\-]+>/<id:\d+>'=>'blog/<_c>/<_a>', // http://myweb.com/blogs/detail/1

Hi Sir:

I also found the root cause. The route is blog/post and action is detail . Like you said which should change Url : 'blog/detail' to '/blog/post/detail'

Am I right ?

    public function getUrl()
    {
        return Url::to(['/blog/post/detail', 'id' => $this->id]);
    }

and I found the rule should be below:

// Rules
$app->getUrlManager()->addRules(
	[                
		'blog' => 'blog/post/index',
		'blog/index' => 'blog/post/index',

		// CRUD & URL
		'blog/post/<id:\d+>/<_a:[\w\-]+>' => 'blog/post/<_a>',
		'blog/post/<_a:[\w\-]+>' => 'blog/post/<_a>',
		'blog/comment/<id:\d+>/<_a:[\w\-]+>' => 'blog/comment/<_a>',
		'blog/comment/<_a:[\w\-]+>' => 'blog/comment/<_a>',

	]
);

Thanks . I am learning a lot.

May I ask you another question ? I have a model: PostSearch . The URL:
http://myweb.com/blog/index?PostSearch[tags]=CKEditor
will pass the para: tags , value: CKEditor to PostSearch

If I want to show the URL: http://myweb.com/blog/post/search/tags/CKEditor , How to write the URL rules?

http://myweb.com/blog/index?PostSearch[tags]=CKEditor - This sending a parametr using the Get method
It is possible so: https://toster.ru/q/105057

Thanks