Dominus77 / yii2-advanced-start

Yii2 Start Project Advanced Template
https://dominus77.github.io/yii2-advanced-start/
MIT License
23 stars 12 forks source link

UrlManager issue #16

Closed polinwei closed 6 years ago

polinwei commented 6 years ago

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>',

            ]
        );
Dominus77 commented 6 years ago

Hi!

'blogs' => 'blog/post/index',
//'blogs/detail' => 'blog/post/detail',
'blogs/<_a:[\w\-]+>/<id:\d+>'=>'blog/<_c>/<_a>',
Dominus77 commented 6 years ago
// 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>',
            ]
        );
polinwei commented 6 years ago

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',
Dominus77 commented 6 years ago

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

Dominus77 commented 6 years ago

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

polinwei commented 6 years ago

I use blogs in frontend , blog in the backend

polinwei commented 6 years ago

model: Post

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

on Control : PostController

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

url

Dominus77 commented 6 years ago

You looked? http://www.yiiframework.com/doc-2.0/guide-runtime-routing.html#url-rules

polinwei commented 6 years ago

Yes

Dominus77 commented 6 years ago

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

Dominus77 commented 6 years ago

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

Dominus77 commented 6 years ago

/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?

Dominus77 commented 6 years ago

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

polinwei commented 6 years ago

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]);
    }
Dominus77 commented 6 years ago

Yes!

polinwei commented 6 years ago

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>',

    ]
);
polinwei commented 6 years ago

Thanks . I am learning a lot.

polinwei commented 6 years ago

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?

Dominus77 commented 6 years ago

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

polinwei commented 6 years ago

Thanks