Dynamic routes with AngularJS and Silex


These days I’m playing with AngularJS. Today I want to experiment with dynamic routes. Let me show your an example. Imagine a simple route configuration:

$routeProvider.when('/page/page1', {templateUrl: 'partials/page1.html', controller: Controller1});
$routeProvider.when('/page/page2', {templateUrl: 'partials/page2.html', controller: Controller2});
$routeProvider.when('/page/page3', {templateUrl: 'partials/page3.html', controller: Controller3});

It’s very simple but: What happens if our application is big and it grows fast? We need to add new lines and reload the browser.
With AngularJS we can add paramenters to the routes:

$routeProvider.when('/page/:page', {templateUrl: 'partials/page.html', controller: Controller});

Now we don’t need to add new routes but what can we do with the partials? After browse the web and stack overflow finally I found this solution:

.when('/page/:page', {template: '<div ng-include="templateUrl">Loading...</div>', controller: DynamicController})

And now we need to define our DynamicController and load there our needed partial:

function DynamicController($scope, $routeParams) {
    var unique = (new Date()).getTime();
    $scope.templateUrl = '/api/pages/' + $routeParams.page + '?unique=' + unique;
}

We can load our partial as a static file but in this example I’m using a Silex backend to provide my partials.

<?php
require_once __DIR__ . '/../../vendor/autoload.php';

use Silex\Application;
use Symfony\Component\HttpFoundation\Response;
$app          = new Application();
$app['debug'] = true;

$app->register(new Silex\Provider\TwigServiceProvider(), [
    'twig.path'    =>  __DIR__.'/../../views',
    'twig.options' => [
       'cache'       => __DIR__ . '/../../cache',
       'auto_reload' => true
    ]
]);

$app->before(function() use ($app){
    $app['twig']->setLexer( new Twig_Lexer($app['twig'], [
        'tag_comment'   => ['[#', '#]'],
        'tag_block'     => ['[%', '%]'],
        'tag_variable'  => ['[[', ']]'],
        'interpolation' => ['#[', ']'],
    ]));
});

$app->get('/pages/{name}', function($name) use ($app){
    return $app['twig']->render('hello.html.twig', ['name' => $name]);
});

$app->get('/pages/js/{name}', function($name) use ($app){
    $response = new Response($app['twig']->render('hello.js', ['name' => $name]));
    $response->headers->set("Content-Type", 'application/javascript');

    return $response;
});

$app->run();

As you can see we need to use one small hack to use twig and AngularJS together. They aren’t good friends with the default configuration. Both uses the same syntax ‘{{ expresion }}’. Because of that we will change Twig’s default behaviour within a middleware.

And basically that’s all. You can see a working example in my github account using Booststrap and UI Booststrap

11 thoughts on “Dynamic routes with AngularJS and Silex

      1. yes. (In my example I’m forcing to reload the partial (with ‘unique’ timestamp))

  1. You can use the verbatim tag in Twig instead of changing all your tags grammar in your twig templates.

    1. yes, but (afaik) all code between verbatin tag is raw data for twig and if I need to use a twig variable inside my templates (twig) turn into a nightmare (close/open/close/…). both solutions are “ugly”, indeed

    1. What’s the correct to do it with angular? (I also would preffer to change angular’s side instead of twig)

      1. angular.module(‘app’, [])
        .config([‘$interpolateProvider’, function ($interpolateProvider) {
        $interpolateProvider.startSymbol(‘[[‘);
        $interpolateProvider.endSymbol(‘]]’);
        }]);

        And then in angular you can use [[ var ]] instead {{ var }} 🙂

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.