Add custom Sonata page route to the navbar - php

I've created a custom Sonata page
Simple route
medapp_adminStreamCommands:
path: /admin/stream
defaults: { _controller: MedAppBundle:VideoChat/VideoChat:adminStreamCommands }
Controller that returns the admin pool
public function adminStreamCommandsAction(Request $request)
{
return $this->render('#MedApp/AdminSonata/Stream/stream_commands.html.twig', array(
'admin_pool' => $this->get('sonata.admin.pool')));
}
Plain view template
{% extends '#MedApp/AdminSonata/standard_layout.html.twig' %}
{% block content %}
foobar
{% endblock content
This works, I can access it on my website with /admin/foo and I get a page which has the Sonata admin template with my 'foobar' content.
My question is, how can I add this route to the left and top navbar without having to modify the default template?
That is because the left menu is rendered by a KNP menu:
{% block side_bar_nav %}
{% if app.user and is_granted('ROLE_SONATA_ADMIN') %}
{{ knp_menu_render('sonata_admin_sidebar', {template: admin_pool.getTemplate('knp_menu_template')}) }}
{% endif %}
{% endblock side_bar_nav %}
And I somehow need to add my new page to be rendered by this menu.
Normally, a page is added through a service, but these are built on top of an entity:
servicename:
class: Bundle\Class
arguments: [~, Bundle\Entity\Entityname, ~]
tags:
- { name: sonata.admin, manager_type: orm, group: admin, label: CustomName}
My page is not using an entity, though, just static content or content that is not dependant on an entity.
I know already that I can modify the blocks that generate the menus, but I was thinking that the best way would be to add my class as a service tagged as sonata.admin that doesn't have an orm manager_type, in other words, is not an Entity. How can that be done?

You should override standard_layout and modify content of side_bar_nav block. This is simple and fast way. Or you can dig into sonata code to find how to inject something into admin_pool.dashboardgroups - have fun :)

I don't think that's possible, you have to create a new layout, copy the sonata admin layout and customize it to your need.
You can change the layout used by changing the yml configuration for sonata_admin (templates -> layout) or extending the SonataAdmin bundle and creating your own layout.html.twig.

Related

Symfony / Sonata Admin: List form on Edit form

I have a one (category) to many (product) relationship set up, and I'd like to have a list of products show up at the bottom of the edit category page.
It seems like this would be a common thing to do, but I haven't found any way to do it (or any examples of it). I have managed to get the product to display using sonata_type_collection but that gives me a whole edit form for the Product, when I really just want a list of products associated with the category.
Two questions here, really:
Is this possible?
Is it discouraged (which would explain the lack of examples)? If so, why?
The fastest way to do what you are looking for is overriding the edit template. At your admin serivce declaration you can do so:
services:
sonata.admin.mail:
class: %sonata.admin.category.class%
tags:
- { name: sonata.admin, manager_type: orm, group: "Categories", label: "Category" }
arguments:
- ~
- %skooli.category.class%
- ~
calls:
- [ setTemplate, ["edit", "AcmeAdminBundle:CategoryAdmin:edit.html.twig"] ]
Then, under AcmeBundle/Resources/views/CategoryAdmin/edit.html.twig you can have something like this:
{% extends 'SonataAdminBundle:CRUD:base_edit.html.twig' %}
{# Override any block from the parent view if necessary #}
{% block products %}
<ul>
{% for product in object.products%}
<li>{{ product.name }}</li>
{% endfor %}
</ul>
{% endblock products %}
In your original question you were talking about the edit template of the category. In your comment you want the list to appear in the show action.
The latter is easy. As soon as you add your relation to your showFields action they will be shown:
use Sonata\AdminBundle\Show\ShowMapper;
class CategoryAdmin extends Admin
{
protected function configureShowFields(ShowMapper $showMapper)
{
$showMapper
->add('products')
;
}
}
If you don't like the look you can create a custom template. This will work for show and edit:
https://sonata-project.org/bundles/admin/master/doc/reference/action_show.html#setting-up-a-custom-show-template-very-useful

Symfony2 fos login, register and forgot password in one view

I need to apply a purchased template to our dashboard. In this template, the login, register and forgot password forms are all under the same view, and switching between them using simple JQuery.
I have been looking for a nice, not-too-flashy way of combining all three forms into one, but I came up empty.
My standing options (as I see them), and why I don't like any of them:
Take the views from the fos bundle, copy them to /app/Resources/FOSUserBundle/views/, remove the {% extend %} part and {% include %} them in my own login view. Reason for dislike: to me this looks a little like a quick-n-dirty fix - "that part's not working? Let's break it off!" :)
Extend the fos bundle, accept an extra parameter in the LoginAction and RegisterAction, use {% render %} with parameters in my own login view. Reason for dislike: extending a whole bundle and modifying two different controllers just to change the way it renders feels like bad MVC.
XHR load everything. Reason for dislike: this approach makes sense when using inner pages, but for pages that reload anyway it just doesn't make sense.
TL;DR version: I'm looking for a non-hack way of including the login, register and forgot password form in one page.
Any help would be greatly appreciated!
I found a solution with which I am comfortable with for my current project. The advantages and disadvantages of the proposed solution upfront:
Advantages:
few LOC to implement
FOSUserBundle update proof (does not override the view scripts*)
Disadvantages:
performance overhead due to subrequests
only forms can be displayed, form submission (and subsequently error handling upon submission) will always go to the pages provided by FOSUserBundle
still feels like a quick-n-dirty fix, but better than other options
* only needs to override the layout.html.twig file
With that being said, here is what I have done:
Render the form in your template
Use embedded controllers to render the forms you need:
<div>
<h2>Login</h2>
{{ render(controller('FOSUserBundle:Security:login', { embeddedForm: true})) }}
</div>
<div>
<h2>Reset</h2>
{{ render(controller('FOSUserBundle:Resetting:request', { embeddedForm: true})) }}
</div>
Override FOSUserBundle layout
As I use the routes provided by the bundle, I had to override the FOSUserBundle layout template file to extend the standard layout of my application. As the overriden FOSUserBundle layout file extends the main applications layout file the layout would be repeated for each call {{ render ... }}. To prevent that, we need to dynamically disarm the extended layout file. Here is what the overriden layout file looks like:
{# app/Resources/FOSUserBundle/views/layout.html.twig #}
{% if app.request.get('embeddedForm') %}
{% set layout = 'AcmeBundle::layout-content.html.twig' %}
{% else %}
{% set layout = 'AcmeBundle::layout.html.twig' %}
{% endif %}
{% extends layout %}
{% block content %}
{% block fos_user_content %}{% endblock %}
{% endblock %}
Create the AcmeBundle::layout-content.html.twig file
This layout should only render the content block of the FOSUserBundle view scripts and is such short and simple:
{# src/Acme/DemoBundle/Resources/views/layout-content.html.twig #}
{% block content %}{% endblock %}
Now the forms will render nicely with all dependencies (CSRF and so forth). Submitting the form will however take you to the FOSUserBundle actions.
Alternative solution:
This answer describes how to manually implement the forms and link them to the FOSUserBundle controller.

"Unable to generate a URL for the named route

Ive just started playing with symfony2 and im working on adding url etc.
I cant seem to get my twig template to pick up on my function when passed its name using #Route.
Any ideas why?
Controller:
/**
* #Route("/cube/{number}", name="get_cubed")
*/
public function indexAction($number)
{
$cube = $number * $number * $number;
return $this->render('NumberCubedBundle:Default:index.html.twig',
array('number' => $number, 'cube' => $cube)
);
}
My Twig File:
{% extends '::base.html.twig' %}
{% block title %}Cube Number Generator{% endblock %}
{% block body %}
{{ number }}^3 = {{ cube }}
Cube 40
{% endblock %}
The Error:
An exception has been thrown during the rendering of a template ("Unable to generate a URL for the named route "get_cubed" as such route does not exist.") in NumberCubedBundle:Default:index.html.twig at line 5.
Any help would be massively appreciated.
Thanks
EDIT: why the annotation didn't work
Most probably you didn't include Sensio's vendor bundle as explained in annotation routing and sensio framwork EXTRA bundle.
The default routing mechanism uses the routing file (routing.yml) which does not need the extra bundle.
The routing through annotations, on the other hand, are considered an additional feature that is not always desired and thus has been extracted to a separate and optional bundle.
You need to configure the route in the routing file:
app/config/routing.yml
Define the route get_cubed using the standard Symfony 2 routing syntax.
Much like this:
get_cubed:
path: /cube/{number}
defaults: { _controller: NumberCubedBundle:Default:index }
requirements:
number: \d+
Now you should be able to get the page with the route:
.../app_dev.php/cube/40
The Solution for pattern annotation is:
on app/config/routing.yml add :
tuto_produit_bundle:
resource: "#ProduitBundle/Controller/"
type: annotation
prefix: /cat
and o URL:
http://localhost/produits/Symfony/web/app_dev.php/cat/{adresse}/{route action}
like http://localhost/vente%20produits/Symfony/web/app_dev.php/cat/categorie/

ezpublish/symfony renders 404 in Smarty, everything else in Twig

On my eZ publish 5 site I have all my templates in Twig, in the vendor/ezsystems/demobundle/EzSystems/DemoBundle/Resources/views/ subfolders. They are all being used throughout my whole site, no problems there. With one exception: 404 pages. If I go to mysite/nonexistingurl, it gives me a kernel (20) / Error page, with status 404. The template being used for this is the 20.tpl somewhere in eZ publish/symfony, I don't want that, I want to use my own Twig template for this.
How can I achieve this? I added a vendor/ezsystems/demobundle/EzSystems/DemoBundle/Resources/views/Exception/error.html.twig page, but this one is not being called
first add this configuration parameter
parameters:
ezpublish_legacy.default.module_default_layout: 'YourBundle::pagelayout_legacy.html.twig'
you may add it in the parameters.yml file located in path/to/yourezpublishinstall/ezpublish/config, the parameters.yml is usually imported in the config.yml located in the same folder
this would define the twig template located in path/to/yourbundle/Resources/views/pagelayout_legacy.html.twig as the parent template for legacy stack modules templates
inside the pagelayout_legacy.html.twig template, you may use this code
{% extends 'YourBundle::pagelayout.html.twig' %}
{% block content %}
{# module_result variable is received from the legacy controller. #}
{% if module_result.errorCode is defined %}
<h1>{{ module_result.errorMessage }} ({{ module_result.errorCode }})</h1>
{% else %}
{{ module_result.content|raw }}
{% endif %}
{% endblock %}
note in the code, the template extends the pagelayout.html.twig template, that should here define a block named content, the pagelayout.html.twig may usually be the main base layout for your ez publish 5 website
you may modify the pagelayout_legacy.html.twig template to your needs
reference:
http://share.ez.no/forums/developer/overriding-legacy-error-pages-templates

How to Logout Session Symfony Fos:Userbundle

I am new to Symfony2, i am using FOSUserBundle. I overwrote the default template for the FOSUserBundle, and doing so i have lost the 'loggout' link on the profile page at
resource: "#FOSUserBundle/Resources/config/routing/profile.xml"
Is there a way to loggout from the symfony tool bar at the bottom?
and what is the resource link to loggout a user in fosUserBundle
I think, that the default route for logout in FOSUerBundle is "fos_user_security_logout", so you can generate a logout link anywhere in your site with this route:
<a href="{{ path('fos_user_security_logout') }}">
It is also possible to add a new block to the Symfony2 debug toolbar with the logout link.
You should have a look here: Adding Web Profiler Templates
You can extend the 'WebProfilerBundle:Profiler:layout.html.twig' layout and add the custom content to the toolbar block.
{% block toolbar %}
{# the web debug toolbar content #}
{% endblock %}

Categories