Symfony2 Service reference from mustache - php

i have a mustache template that has the following line
{{{widgets.service_name.js.footer}}}
i found the corresponding service defined in a symfony2 bundle
service_name:
class: A\B\C\D\EventListener\AssetsListener
arguments:
- #templating
- %a.b.timestamp%
- %kernel.environment%
tags:
- { name: kernel.event_listener, event: kernel.response, method: injectAsset, priority: -255}
Is there a mustache specific meaning in .js.footer (prefix to the symfony2 service name) i am unable to find any reference related to this.
Anyone could provide some pointers i would greatly appreciate it.
Thanks

Dots in mustache tags are equivalent to either array access, properties or method calls. So this:
{{{widgets.service_name.js.footer}}}
Means something like this:
$widgets['service_name']['js']['footer'];
$widgets['service_name']->js->footer;
$widgets['service_name']->js()->footer();
… or some combination of the above. Which it actually translates to depends on what the service is, what public methods or properties it exposes, and what they return.
Here's more on Mustache dot notation, and on variable resolution in Mustache.php.

Related

Symfony 6 - Routes with Attribute Annoation - How to pass route name via variable?

I am currently working on a symfony 6 project and use the attribute annotation for the routes directly inside the controller.
Example:
#[Route('/new', name: 'country_new', methods: ['GET', 'POST'])]
Now I would like to pass a part of the name of the route via a variable like:
private $routeName = "country";
#[Route('/', name: $this->routeName.'_index', methods: ['GET'])]
However this is not working and I get the following error:
"Compile Error: Constant expression contains invalid operations"
Do you have an idea if this is even possible and if so how I can achieve this?
This is not specific to Symfony, actually, but to PHP attributes in general. Per the documentation:
Arguments to attributes can only be literal values or constant expressions
However, as it relates to Symfony, if you are looking to just prefix all of the routes in a given controller, you can put a Route attribute on the class itself, too.

Getting the file_locator service in symfony2 custom router

I want to create a custom route loader as instructed in http://symfony.com/doc/current/cookbook/routing/custom_route_loader.html.
What I have to do is read the read the routes from an xml file (not in "symfony xml" format) and create the according route collection.However I want to do that using the '#' directive.as in:
xmlRoutes:
resource: '#FooBarBundle/Resources/routes.xml'
But in order to resolve the path to routes.xml I need the 'file_locator' service from the container.is it possible to access services in a custom router class.if not, how can I make a symfony\Component\Config\FileLocator to resolve that path?
Yes you could access the file_locator as it's a service. What you need to do is make your custom_route_loader a service itself (I dind't read the cookbook you linked but I'm pretty sure that they would advice to define it as a service) and inject the file_locator service into it.
So basically you'll do something like
#config.yml
[...]
services:
yourbundlename.custom_route_loader:
class: Path\To\Your\Bundle\CustomRouteLoader
arguments: [ #file_locator ]
And into you CustmRouteLoaderClass
#Path\To\Your\Bundle\CustomRouteLoader
class CustomRouteLoader
{
public function __construct(Symfony\Component\HttpKernel\Config\FileLocator $file_locator) {
$this->file_locator = $file_locator;
[...]
}
[...]
}

Auto Routing Bundle - and parameters? (Symfony CMF)

I was successful with getting Symfony CMF and Auto Routing Bundle (and a custom contoller) to load documents in the following manner (path):
.../category/article-name
This works fine. But I need something like this, easily achieved by standard Symfony2:
.../category/article-name/{page}
Where page is passed to a controller as a parameter,
eg. $page = 2 -> controller processes content of the Article document to display only given page
or $page = null -> (so no {page} parameter at all) - as above, but displayed is page default that is 1
How to make routing-auto bundle of the Symfony CMF to use parameters in routes?
So that the basic path is exactly as it is configured as in this Auto Routing Bundle configuration, but additionally I can use parameters passed to a controller, so that additional decisions can be made upon them. Any hints? Thanks!
My config for auto routing:
MyApp\MyCmsBundle\Document\Article:
content_path:
#fixed path of all categories and therefore articles
articles_categories_path:
provider: [specified, { path: /cms/routes }]
exists_action: use
not_exists_action: throw_exception
#category path
category_path:
provider: [content_method, { method: getRouteNodeCategory }]
exists_action: use
not_exists_action: throw_exception
#article name
content_name:
provider: [content_method, { method: getTitle }]
exists_action: [auto_increment, { pattern: -%d }]
not_exists_action: create
MyApp\MyCmsBundle\Document\ArticlesCategory:
content_path:
#fixed path of all categories and therefore articles
articles_categories_path:
provider: [specified, { path: /cms/routes }]
exists_action: use
not_exists_action: throw_exception
#category name
content_name:
provider: [content_method, { method: getTitle }]
exists_action: use
not_exists_action: create
getRouteNodeCategory() of the Article Document just returns a parents (i.e. category) name. Here's part of this document content:
public function getRouteNodeCategory()
{
return $this->parent->getTitle();
}
This is not currently possible in the RoutingAutoBundle but it could be easily implemented.
The RoutingAutoBundle creates Route documents which extend the CMF's Route object. These Route objects do support variable patterns which allow you to specify dynamic paramters:
https://github.com/symfony-cmf/RoutingBundle/blob/1.2/Model/Route.php#L53
So we would just need to extend the mapping to include details on dynamic (variable) parameters in the URL.
Note also that the a new version of the routing auto bundle will soon be released which features a much better configuration format.
If you could create an issue detailing your use case, we will try and implement it for the 1.0 release.

Symfony 2 #Route annotation case-sensitive

I'm trying to create a url with annotations of the route.
The problem is that I can write any URL large, small or different.
#Route("/{staat}/", name="showStaats",requirements={"location" = "berlin|bayern|brandenburg"})
This URL can be accessed both from www.example.com/berlin and under www.example.com/Berlin.
I would, however, that it is attainable only under www.example.com/berlin.
Answering the question "How to make case-insensitive routing requirement":
You can add case-insensitive modifier to requirement regexp like so:
(?i:berlin|bayern|brandenburg)
You have "/{staat}/", but your requirements set "location" = ..., these should match, so maybe that's the cause of your problem.
If you don't want to hardcode the list of states in your route, you could inject a service containter parameter with a list of states. Just see How to use Service Container Parameters in your Routes in the documentation for how to do that.
If you just want to check, whether that state is all lower-cased you could try the following requirement:
staat: "[a-z-]+"
This should match only lowercase characters and dash (e.g. for "sachsen-anhalt"). But I'm not entirely sure if this will work as the router's regex-detection is a bit quirky.
You could also create a custom Router Loader which will create routes programmatically, e.g. by fetching the list of states from a database or file.
edit:
As I wrote in my comment I would add the list of params as a Service Container parameter, e.g. %my_demo.states% containing a list of states. I'm not sure however if this will work with annotations. So here is a quick workaround how to get it working.
In your app/config/config.yml you append the %my_demo.states% parameter:
my_demo:
states: ["berlin", "brandenburg", "sachsen-anhalt", ... ]
In your app/config/routing.yml there should be something like this:
my_demobundle:
resource: "#MyDemoBundle/Controller/"
prefix: /
type: annotation
The type: annotation and #MyDemoBundle is the relevant part. Add the following route before this one, to make sure it takes precedence:
showStaats:
path: /{state}
defaults: { _controller: MyDemoBundle:State:index }
requirements:
state: %my_demo.states%
This will add a route which will apply before your annotations using the list of states as parameters. This is a bit crude, as you are mixing yml/annotation-based routing, but it's imo still better than cramming a list of 16 states in the annotation, not to mention its easier to maintain.

Removing Symfony2 scope widening notice

I'm trying to speed up my stack by removing references to the service container where possible. In this case I only need the request:
email_error_message:
class: Core\MyBundle\Services\Email\ErrorMessage
arguments: [ #request, %params ]
However, that throws a scope widening issue. I'm not concerned with refactoring the code for now, I just wish to get rid of the warning by adding strict = true. But I can't seem to get the YAML syntax right:
email_error_message:
class: Core\MyBundle\Services\Email\ErrorMessage
arguments:
- { type: service, id: request, strict: false }
- %params%
This isn't working though. Any ideas?
EDIT
I realise I could change the scope of this service to request, but that isn't an option in this case.
You want to restrict the scope of the service to the request scope, since you need to make sure you're passed the right Request instance - if you are using the service from within a subrequest for example, or whether through the main request. Adjust your service config to:
services:
email_error_message:
class: Core\MyBundle\Services\Email\ErrorMessage
scope: request
arguments: [ #request, %params% ]
See the docs for more details.
Edit as per your question edit, you're not able to change the scope. In which case, your syntax should be as follows:
services:
email_error_message:
class: Core\MyBundle\Services\Email\ErrorMessage
arguments: [ #request=, %params% ]
with the appended = symbol. Note that I've not seen this referenced anywhere, and it's from digging around in the code for the DI container ;-)

Categories