sonata-project / SonataPageBundle

This bundle provides a Site and Page management through container and block services
https://docs.sonata-project.org/projects/SonataPageBundle
MIT License
219 stars 210 forks source link

host_with_path with dynamic page. #1474

Closed mesiarm closed 2 years ago

mesiarm commented 2 years ago

I want create sites for diferent locales (example.com/page, example.com/en/page) so I am using host_with_path multisite option. But dynamic page (example.com/project/{slug}) stopped working and when visiting example.com/project/example it redirects back to example.com. When I added dynamic page to ignore_uri_patterns, it works, but blocks in global page doesn´t work.

mesiarm commented 2 years ago

When I try debug method matchRequest in Sonata\PageBundle\Site\BaseSiteSelector $site->getRelativePath() returns "/" sprintf('@^(%s)(/.*|$)@', $site->getRelativePath()) returns "@^(/)(/.*|$)@", and $requestPathInfo contains "/project/example/". Preg_match doesn´t match anything. Is regex correct?

protected function matchRequest(SiteInterface $site, Request $request)
    {
        $results = [];

        // we read the value from the attribute to handle fragment support
        $requestPathInfo = $request->get('pathInfo', $request->getPathInfo());

        if (!preg_match(sprintf('@^(%s)(/.*|$)@', $site->getRelativePath()), $requestPathInfo, $results)) {
            return false;
        }

        return $results[2];
    }
eerison commented 2 years ago

Hey @mesiarm I use multi site in my project too, but for dynamically routes, I create an action in a controller (a normal symfony's action) to manager this route! But I guess it's not the best approach, later I found that is possible to use Hybrid or Dynamic pages, look here: https://docs.sonata-project.org/projects/SonataPageBundle/en/3.x/reference/introduction/#a-page

But there isn't too much doc about this, I guess you need to check in the code how it works, But if it works for you provide some Pull request improving the documentation about this please, maybe it can help others.

eerison commented 2 years ago

When I try debug method matchRequest in Sonata\PageBundle\Site\BaseSiteSelector $site->getRelativePath() returns "/" sprintf('@^(%s)(/.*|$)@', $site->getRelativePath()) returns "@^(/)(/.*|$)@", and $requestPathInfo contains "/project/example/". Preg_match doesn´t match anything. Is regex correct?

protected function matchRequest(SiteInterface $site, Request $request)
    {
        $results = [];

        // we read the value from the attribute to handle fragment support
        $requestPathInfo = $request->get('pathInfo', $request->getPathInfo());

        if (!preg_match(sprintf('@^(%s)(/.*|$)@', $site->getRelativePath()), $requestPathInfo, $results)) {
            return false;
        }

        return $results[2];
    }

have you tried to use Hybrid or Dynamic routes?

mesiarm commented 2 years ago

When I try debug method matchRequest in Sonata\PageBundle\Site\BaseSiteSelector $site->getRelativePath() returns "/" sprintf('@^(%s)(/.*|$)@', $site->getRelativePath()) returns "@^(/)(/.*|$)@", and $requestPathInfo contains "/project/example/". Preg_match doesn´t match anything. Is regex correct?

protected function matchRequest(SiteInterface $site, Request $request)
    {
        $results = [];

        // we read the value from the attribute to handle fragment support
        $requestPathInfo = $request->get('pathInfo', $request->getPathInfo());

        if (!preg_match(sprintf('@^(%s)(/.*|$)@', $site->getRelativePath()), $requestPathInfo, $results)) {
            return false;
        }

        return $results[2];
    }

have you tried to use Hybrid or Dynamic routes?

I created App Project Detail page with /project/{slug} page and then created ProjectController with detail action and route setting:

<?php

namespace App\Controller;

use App\Entity\Project;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class ProjectController extends AbstractController
{
    /**
     * @Route("/project/{slug}", name="app_project_detail")
     * @ParamConverter("project", options={"mapping": {"slug": "slug"}})
     */
    public function detail(Project $project): Response
    {
        return $this->render('project/detail.html.twig', [
            'test' => 'test',
            'project' => $project,
        ]);
    }
}
haivala commented 2 years ago

Just to mention that I have done something like this: https://github.com/sonata-project/SonataPageBundle/issues/1368

eerison commented 2 years ago

Just to mention that I have done something like this: #1368

Hi @haivala thanks for share your issue here :)

But definitely we need more documentation about this, should be really good if someone that used this can provide some doc, unfortunately I didn't test this functionality yet.

But @mesiarm if you want to test this solution and add some doc, it will be really good :)

mesiarm commented 2 years ago

https://github.com/sonata-project/SonataPageBundle/issues/752 - simmilar issue. Dynamic page should be definitely better documented, how to use it, maybe someone, who used this functionality in his/her projects could provide more information. I will try to look at source code to understand it better.

mesiarm commented 2 years ago

"@^(/)(/.*|$)@" regex in matchRequest in Sonata\PageBundle\Site\BaseSiteSelector causes / as default site relative path is not supported.

mesiarm commented 2 years ago

So if default site relative path cannot be / - is it bug or is it intended?

eerison commented 2 years ago

So if default site relative path cannot be / - is it bug or is it intended?

Can't it be "/" or "/-"? If you mean it can't be "/-" then I would say it's intend, Because this slug/url is more or less wrong?🤔

Or is it missing the locale like "/de-en"?

mesiarm commented 2 years ago

I mean only / (without dash). I wanted to use / for default site and /en for English site.

eerison commented 2 years ago

I mean only / (without dash). I wanted to use / for default site and /en for English site.

Well if you can't use with / and /en ,I would say it's a bug 🤔, what do you think?

I use this functionality but with multisite

mesiarm commented 2 years ago

Just to clarify: /en works, /anything works, but / doesn´t. Regex is sprintf('@^(%s)(/.*|$)@', $site->getRelativePath())

eerison commented 2 years ago

Just to clarify: /en works, /anything works, but / doesn´t. Regex is sprintf('@^(%s)(/.*|$)@', $site->getRelativePath())

I guess you can create a site with relativePath = null

mesiarm commented 2 years ago

Just to clarify: /en works, /anything works, but / doesn´t. Regex is sprintf('@^(%s)(/.*|$)@', $site->getRelativePath())

I guess you can create a site with relativePath = null

I think it wouldn´t match mentioned regex which is in method matchRequest in Sonata\PageBundle\Site\BaseSiteSelector

mesiarm commented 2 years ago

correction - I tried it with null and it works (probably due $request->setPathInfo($pathInfo ?: '/'); in Sonata\PageBundle\Site\HostPathSiteSelector) . It should be corrected in documentation https://docs.sonata-project.org/projects/SonataPageBundle/en/3.x/reference/getting_started/ because there is stated default site /, but in CreateSiteCommand it is converted to empty string ($site->setRelativePath('/' === $values['relativePath'] ? '' : $values['relativePath']);) It works, because Sonata\PageBundle\Site\HostPathSiteSelector accepts falsy values, but it is confusing, when creating sites manually.

eerison commented 2 years ago

correction - I tried it with null and it works (probably due $request->setPathInfo($pathInfo ?: '/'); in Sonata\PageBundle\Site\HostPathSiteSelector) . It should be corrected in documentation https://docs.sonata-project.org/projects/SonataPageBundle/en/3.x/reference/getting_started/ because there is stated default site /, but in CreateSiteCommand it is converted to empty string ($site->setRelativePath('/' === $values['relativePath'] ? '' : $values['relativePath']);) It works, because Sonata\PageBundle\Site\HostPathSiteSelector accepts falsy values, but it is confusing, when creating sites manually.

But the question is, is it the correct way 👀 , I don't know why the doc says that the default value is /, it's strange :/

mesiarm commented 2 years ago

correction - I tried it with null and it works (probably due $request->setPathInfo($pathInfo ?: '/'); in Sonata\PageBundle\Site\HostPathSiteSelector) . It should be corrected in documentation https://docs.sonata-project.org/projects/SonataPageBundle/en/3.x/reference/getting_started/ because there is stated default site /, but in CreateSiteCommand it is converted to empty string ($site->setRelativePath('/' === $values['relativePath'] ? '' : $values['relativePath']);) It works, because Sonata\PageBundle\Site\HostPathSiteSelector accepts falsy values, but it is confusing, when creating sites manually.

But the question is, is it the correct way 👀 , I don't know why the doc says that the default value is /, it's strange :/

Yes, any falsy value in relativePath works, / doesn´t work.

eerison commented 2 years ago

correction - I tried it with null and it works (probably due $request->setPathInfo($pathInfo ?: '/'); in Sonata\PageBundle\Site\HostPathSiteSelector) . It should be corrected in documentation https://docs.sonata-project.org/projects/SonataPageBundle/en/3.x/reference/getting_started/ because there is stated default site /, but in CreateSiteCommand it is converted to empty string ($site->setRelativePath('/' === $values['relativePath'] ? '' : $values['relativePath']);) It works, because Sonata\PageBundle\Site\HostPathSiteSelector accepts falsy values, but it is confusing, when creating sites manually.

But the question is, is it the correct way 👀 , I don't know why the doc says that the default value is /, it's strange :/

Yes, any falsy value in relativePath works, / doesn´t work.

well in this case we should provide a fix for this! like doesn't accept "/" in relativePath we could use symfony assert for this

eerison commented 2 years ago

Yeah I checked now and in the project that I'm working it's null

jordisala1991 commented 2 years ago

Does #1606 fix this issue?