symfony-cmf / routing-auto

RoutingAuto component
https://cmf.symfony.com
Other
6 stars 11 forks source link

Added expression provider #18

Open dantleech opened 9 years ago

dantleech commented 9 years ago

This PR add a Symfony Expression Language provier.

This provides a very dynamic way to genereate URLs, for example:

stdClass:
    uri_schema: /{path}
    token_providers:
        path: [expression, { expression: 'parameter.cmf_routing.basepath + "/" + slugify(subject.title) }]

The expression language is not modified within the provider and it is up to the developer to provide a suitably featureful language to the provider. For example one which provides access to container parameters, a slugifier and the locale.

We could provide either a fully featured ExpressionLanguage in this component, or provide one which is composable somehow.

dantleech commented 9 years ago

So this would ultimately allow people to specify the entire auto route in Expression Language, e.g.

"/forum/" + locale + slugify(subject.forum.title) + "/posts/" + (substr(subject.parent.path, strlen(context.post_base_path))) + (slugify(subject.title)

Which could translate to:

/forum/de/my-forum/posts/foo/bar/subcategory/category/my-post

Whilst this is flexible it means we are adding arbitrary functions substr and strlen to meet our goal, and I wonder how many other functions we should have to add.

This solution ultimately represents to an alternative to TokenProvider classes so I also wonder how the two could live side-by-side.

henrikbjorn commented 9 years ago

:-1:

dantleech commented 9 years ago

@henrikbjorn can you elaborate? :)

henrikbjorn commented 9 years ago

One of the biggest thing with Symfony2 was killing the magic, and this goes the exact opposite direction. It introduces a language inside of a configuration file. Neither Scrutinizer or Blackfire knows how to run its cecks on it, also it will confuse users as what functions are used, where are they used. Also it cannot be proberly covered by tests by the end user.

Imo 10000% worse than using Annotations.

wouterj commented 9 years ago

@henrikbjorn that's more of an issue with the creation of the ExpressionLanguage component than an issue with implementing it in this bundle, isn't it?

I think it's great to have this provider. It would allow for a quick and nice way to solve more complex path providers.

Btw, providers can't also be checked by Scrutinizer and Blackfire and testing this provider thing is only done by acceptance/webtests, which are perfectly able to test this "magic".

petforsberg commented 9 years ago

Are we limited to use an Expression Language like this only within / with correspondance to Route Auto config, or is it more independent (so that I could use it anywhere else in my app)?

I mean, sometimes I'd like to have a way to "express" url, which then gives me info on what path-units it consists of. It'd be nice - since this is already implemented by you - to not create my own solution, which would duplicate the same functionality.

dantleech commented 9 years ago

@petforsberg you can use it at least in the Symfony service configuration: http://symfony.com/doc/current/book/service_container.html#using-the-expression-language

petforsberg commented 9 years ago

I meant rather using the exact functionality from the expression provider within Route Auto, but not within Route Auto config, but for my own purposes somewhere within an app? (In other words, is this expression functionality decoupled, or not really?)

dantleech commented 9 years ago

I just noticed this PR is incomplete (we do not add any functions to the expression language). But I guess it could be decoupled, what would your use case be?

petforsberg commented 9 years ago

What I'd need could be presented in a following way:

  1. I put somewhere globally (e.g. in config, service, or wherever else) an expressions of path-units, exactly just like they are configured by expression provider
  2. I create a service with a method getUrlInfo() or something like that, which depending on e.g. a class, field or anything else, returns an array with information on the path.
  3. When I need some (meta) info on an object's url, I call somewhere within my app that method.

Maybe even there's some method which do exactly like this within Route Auto?

(Ah, one more thing: the idea is to not necesserily match that configuration with the exact auto-creation routes by Route Auto - I mean, for example one object could have number (array) of potential paths).

Imagine a SEO tool, which contains information about number of possible paths for different objects or classes.

dantleech commented 9 years ago

Well, the DynamicRouter already allows you to retrieve the URL of an object, f.e. in a twig template {{ path(mycontent) }}.

If you wanted to retrieve all the routes associated with a content, you could do:

foreach ($content->getRoutes() as $route) {
    echo $dynamicRouter->generate($route); // /the/path/of/this/route
}

Your content just needs to have mapped the route referrers to a property

     /**
      * @PHPCR\Referrers(   
      *     referringDocument="Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\Route",
      *     referencedBy="content"
      * )
      */
     protected $routes;`

As detailed in the tutorial

Does that help?

petforsberg commented 9 years ago

I think we misunderstood :)

Yes I know about the url connected to object. I must have been unclear :)

To simplicize things: say I have a class (not object), and I need to retrieve saved somewhere meta-info (configuration) of the path creation, just like it is expressed by the expression provider, but not in Route Auto config file. Can I use some component or method of Route Auto to "parse" such config-lines, and if so, how could I do this?

Example: { expression: "/posts/" + (slugify(subject.title) }

in some my_config.yml file somewhere.

Info which I would need from this expression is meta-info, says that:

:

dantleech commented 9 years ago

You can use the ExpressionLanguage class to parse expressions. Check the documentation for that component. If this PR is merged then there will be an RoutingAuto ExpressionLanguage service which will understand the slugify method. You would then be able to do:

$el = $this->getContainer()->get('routing_auto.expressoin_language')
  ->evaluate($expressionString, array('subject' => $contentDocument));
dantleech commented 9 years ago

I wonder if this should be simply:

stdClass:
    uri_expession: container.parameter.foo + "/" + slufigy(object.name)

Where uri_expression is mutually exclusive with uri_schema. To me it doesn't make sense to mix expressions as the expression provider in itself can make the schema redundant.

This is also much more convenient for annotations.

wouterj commented 9 years ago

I'm a bit -1 on that:

wouterj commented 9 years ago

I think I actually don't see much usecase in this PR, now we have a container token provider. So I would vote to close this or at least skip for the 1.1 release, until we agree on the exact usecase/implementation of this feature.

dbu commented 7 years ago

should we drop this?