Skip to content
This repository has been archived by the owner on Sep 16, 2021. It is now read-only.

Added expression provider #18

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Added expression provider #18

wants to merge 1 commit into from

Conversation

dantleech
Copy link
Member

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
Copy link
Member Author

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
Copy link

👎

@dantleech
Copy link
Member Author

@henrikbjorn can you elaborate? :)

@henrikbjorn
Copy link

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
Copy link
Member

wouterj commented Dec 4, 2014

@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
Copy link

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
Copy link
Member Author

@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
Copy link

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
Copy link
Member Author

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
Copy link

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
Copy link
Member Author

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
Copy link

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:

  • "/posts" is a string
  • slugify is a method
  • subject.title is a field (method) of the Document

:

@dantleech
Copy link
Member Author

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
Copy link
Member Author

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
Copy link
Member

wouterj commented Jan 20, 2015

I'm a bit -1 on that:

  • Annotations, if implemented, are already quite straightforward and self-explaining.
  • It adds yet another way of configuring RA, we should keep as less ways as possible.
  • You'll have to use + "/" + many times, which I don't really like

@dantleech dantleech self-assigned this Mar 11, 2015
@wouterj
Copy link
Member

wouterj commented Aug 23, 2015

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.

@wouterj wouterj removed the review label Jan 3, 2017
@dbu
Copy link
Member

dbu commented Aug 2, 2017

should we drop this?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants