2017 © Pedro Peláez
 

symfony-bundle object-routing-bundle

Symfony2 Bundle that allows generating urls from objects (sf1 style).

image

zenstruck/object-routing-bundle

Symfony2 Bundle that allows generating urls from objects (sf1 style).

  • Wednesday, December 16, 2015
  • by kbond
  • Repository
  • 2 Watchers
  • 8 Stars
  • 458 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 0 Forks
  • 0 Open issues
  • 8 Versions
  • 3 % Grown

The README.md

ZenstruckObjectRoutingBundle

Build Status Scrutinizer Code Quality Code Coverage SensioLabs Insight StyleCI Latest Stable Version License, (*1)

A Symfony Bundle that enables passing objects to your router. It works by decorating the default router with a custom ObjectRouter that transforms objects into a route name and route parameters. These are passed to the default router., (*2)

For those that remember symfony 1, this bundle brings back functionality that was available in that framework., (*3)

Installation

  1. Install with composer:, (*4)

    composer require zenstruck/object-routing-bundle
  2. Enable the bundle in the kernel:, (*5)

    // app/AppKernel.php
    
    public function registerBundles()
    {
        $bundles = array(
            // ...
            new Zenstruck\ObjectRoutingBundle\ZenstruckObjectRoutingBundle(),
        );
    }
    

Usage

To use this bundle, you must first have an object. Let's use a BlogPost example:, (*6)

namespace Acme\Entity;

class BlogPost
{
    private $id;
    private $slug;
    private $body;

    public function getId()
    {
        return $this->id;
    }

    public function getSlug()
    {
        return $this->slug;
    }

    public function getBody()
    {
        return $this->body;
    }
}

Next, you must have some routes for that object:, (*7)

# app/config/routing.yml

blog_post_show:
    pattern:  /blog/{id}-{slug}
    defaults: { _controller: AcmeBundle:BlogPost:show }

blog_post_edit:
    pattern:  /blog/{id}/edit
    defaults: { _controller: AcmeBundle:BlogPost:delete }

blog_post_delete:
    pattern:  /blog/{id}
    defaults: { _controller: AcmeBundle:BlogPost:delete }
    methods:  [DELETE]

Without this bundle

Now, suppose you want to generate a route for a blog post. The standard way of doing this is as follows:, (*8)

Twig:, (*9)

```html+jinja {# variable "post" is an instance of "BlogPost" with id=1, slug=example #}, (*10)

{{ path('blog_post_show', { id: post.id, slug: post.slug }) }} {# /blog/1-example #} {{ path('blog_post_show', { id: post.id, slug: post.slug, view: full }, true) }} {# http://example.com/blog/1-example?view=full #} {{ path('blog_post_edit', { id: post.id }) }} {# /blog/1/edit #} {{ path('blog_post_delete', { id: post.id }) }} {# /blog/1 #}, (*11)


**Symfony Controller**: ```php namespace Acme\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; class MyController extends Controller { public function myAction() { $post = // instance of Acme\Entity\BlogPost with id=1, path=example // blog_post_show (/blog/1-example) $url = $this->generateUrl('blog_post_show', ['id' => $post->getId(), 'slug' => $post->getSlug()]); // blog_post_show with extra parameter and absolute (http://example.com/blog/1-example?view=full) $url = $this->generateUrl( 'blog_post_show', ['id' => $post->getId(), 'slug' => $post->getSlug(), 'view' => 'full'], true ); // blog_post_edit (/blog/1/edit) $url = $this->generateUrl('blog_post_edit', ['id' => $post->getId()]); // blog_post_delete (/blog/1) $url = $this->generateUrl('blog_post_delete', ['id' => $post->getId()]); } }

With this bundle

In this bundle's config, setup a mapping of BlogPost to the blog post routes:, (*12)

# app/config/config.yml

zenstruck_object_routing:
    class_map:
        Acme\Entity\BlogPost:
            default_route: blog_post_show
            default_parameters: [id]
            routes:
                blog_post_show: [id, path]
                blog_post_edit: ~
                blog_post_delete: ~

Generating routes for a blog post is now much simpler:, (*13)

Twig:, (*14)

```html+jinja {# variable "post" is an instance of "BlogPost" with id=1, slug=example #}, (*15)

{{ path(post) }} {# /blog/1-example (blog_post_show url because it is the default route) #} {{ path('blog_post_show', post) }} {# equivalent to above #} {{ path(post, { view: full }, true) }} {# http://example.com/blog/1-example?view=full #} {{ path('blog_post_show', post, { view: full }, true) }} {# equivalent to above #} {{ path('blog_post_edit', post) }} {# /blog/1/edit #} {{ path('blog_post_delete', post) }} {# /blog/1 #}, (*16)


**Symfony Controller**: ```php namespace Acme\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; class MyController extends Controller { public function myAction() { $post = // instance of Acme\Entity\BlogPost with id=1, slug=example // blog_post_show (/blog/1-example) $url = $this->generateUrl($post); // blog_post_show url because it is the default route $url = $this->generateUrl('blog_post_show', $post); // equivalent to above // blog_post_show with extra parameter and absolute (http://example.com/blog/1-example?view=full) $url = $this->generateUrl($post, ['view' => 'full'], true); $url = $this->generateUrl('blog_post_show', $post, ['view' => 'full'], true); // equivalent to above // blog_post_edit (/blog/1/edit) $url = $this->generateUrl('blog_post_edit', $post); // blog_post_delete (/blog/1) $url = $this->generateUrl('blog_post_delete', $post); } }

Custom Transformations

This bundle comes with a ClassMapObjectTransformer that uses the bundle's config to map object classes to routes. If you have a more complex scenario, you can add your own transformers. Simply have your custom transformer implement Zenstruck\ObjectRoutingBundle\ObjectTransformer\ObjectTransformer and register it as a service tagged with zenstruck_object_routing.object_transformer., (*17)

See Zenstruck\ObjectRoutingBundle\ObjectTransformer\ClassMapObjectTransformer for a reference., (*18)

Full Default Config

zenstruck_object_routing:
    class_map:

        # Prototype
        class:

            # Optional - The route to use when an object is passed as the 1st parameter of Router::generate()
            default_route:        null

            # Route parameter as key, object method/public property as value (can omit key if object method/property is the same)
            default_parameters:

                # Examples:
                - id
                - path

            # Route name as key, parameter array as value (can leave parameter array as null if same as default_parameters)
            routes:

                # Examples:
                blog_show:           ~
                blog_edit:
                    - id

                # Prototype
                route_name:           []

NOTE 1: This bundle's router uses the PropertyAccess component to access the object's properties/methods., (*19)

NOTE 2: When mapping multiple objects that inherit one another, be sure to order them from child to parent. For instance, if you had a BlogPost that has a parent class of Page and both are mapped, be sure to put BlogPost before Page., (*20)

The Versions