PHPackages                             hoffmann/silex-view - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Templating &amp; Views](/categories/templating)
4. /
5. hoffmann/silex-view

ActiveLibrary[Templating &amp; Views](/categories/templating)

hoffmann/silex-view
===================

Generic Views for Silex

5139PHP

Since Jan 5Pushed 12y ago2 watchersCompare

[ Source](https://github.com/hoffmann/Silex-View)[ Packagist](https://packagist.org/packages/hoffmann/silex-view)[ RSS](/packages/hoffmann-silex-view/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

Silex-View
==========

[](#silex-view)

[Silex-View](https://github.com/hoffmann/Silex-View) is an implementation of class based views similar to [django class based views](https://docs.djangoproject.com/en/1.5/topics/class-based-views/)and [flask pluggable views](http://flask.pocoo.org/docs/views/) for the php microframework [silex](http://silex.sensiolabs.org/).

In silex you attach closures to a route. The following is a simple example.

```
$app->get('/blog/show/{id}', function (Application $app, Request $request, $id) {
    ...
});
```

Silex does the injection of the `$app` and `$request` variables base on type hinting. When the route matches the closure is called, and the `$app` and `$request` is bound to your silex application and the currend request. Routing variables like the `$id`parameter can be added to the function definition as well.

This is a nice and quick way to build small application. But in my opinion putting your controller logic in a closure leads to tighly coupled code which is difficult to test.

The [silex documentation](http://silex.sensiolabs.org/doc/usage.html#controllers-in-classes) shows how to put your controllers in classes:

```
$app->get('/', 'Igorw\Foo::bar');

use Silex\Application;
use Symfony\Component\HttpFoundation\Request;

namespace Igorw
{
    class Foo
    {
        public function bar(Request $request, Application $app)
        {
            ...
        }
    }
}
```

This approach is much better. Now you can [test](http://silex.sensiolabs.org/doc/testing.html) your controller class with mocked `$request` and `$application` objects. As a bonus your routing definitions are small and clean and your conrtrollers are separated from your routing code and can be reused.

There are two things I don't like:

- You pass your controllter class as a string to your routing function. Maybe this is the php way of doing things, but it does not feel right to me. On top it annoyes me that [phpstrom](www.jetbrains.com/phpstorm/) - my ide of choice - does not recognice it, so you can't click on it or use the goto definition shortcut.
- You are not able to pass arguments to the constructor of your controller. This is a bigger obstacle for me.

[Silex-View](https://github.com/hoffmann/Silex-View) has as simple `BaseView` class which you can inherint from:

```
use SilexView\BaseView

class MyView extends BaseView
{
    private $greeting;
    function __construct($greeting){
        $this->greeting = $greeting;
    }

    function get($request, $app){
        return $this->greeting.' '.$request->get('name');
    }
}
```

and use it in your routing definition:

```
$app->get('/hello/{name}', MyView::asView('hello'));
```

`BaseView::asView()` is a static method which returns a closure that will be called when the route matches:

```
class BaseView
{
    public static function asView()
    {
        $classname= get_called_class();
        $args = func_get_args();
        return function(\Symfony\Component\HttpFoundation\Request $request,
                        \Silex\Application $app) use ($classname, $args){
            $cls = new \ReflectionClass($classname);
            $instance = $cls->newInstanceArgs($args);
            return $instance->dispatch($request, $app);
        };
...
```

All arguments passed to the `asView` function will be forwarded to the constructor of your inherited controller class. Inspired by the [django class based views](https://docs.djangoproject.com/en/1.5/topics/class-based-views/)the `BaseView` class dispaches the request based on the htttp method of the request. So a `GET`request will be passed to the `get(..)` method and a `POST` request to the `post(...)` method of your controller class. With this convention it is very easy and clean to build REST Controllers.

```
class BaseView
{
    ...
    protected $http_method_names = array('get', 'post', 'put', 'delete', 'head', 'options', 'trace');
    public function dispatch($request, $app)
    {
        $method = strtolower($request->getMethod());
        //if no head method is defined use get
        if ("head" === $method && ! method_exists($this, "head"))
            $method = "get";
        if (! (in_array($method, $this->http_method_names) &&
               method_exists($this, $method)))
            return $this->httpMethodNotAllowed($method);
        return $this->$method($request, $app);
    }
```

The `TemplateView` Class is a shortcut for `GET` request which should be rendered by a template. All you have to do is create a subclass and implement the `getContextData()` function which should return an array of arguments which are needed in your twig template

```
class MyTemplate extends TemplateView
{
    function getContextData($request, $app)
    {
        return array('name' => "Joe");
    }
}
```

The implementation is as follows:

```
class TemplateView extends BaseView
{

    /*
     * Get the Template Name for the view
     * default implementation is to use the class name without namespace
     */
    function getTemplateName(){
        $cls = explode('\\', get_class($this));
        return end($cls).'.twig';

    }

    function get($request, $app)
    {
        return $app["twig"]->render($this->getTemplateName(),
                                    $this->getContextData($request, $app));
    }

    function getContextData($request, $app)
    {
    }
}
```

###  Health Score

23

—

LowBetter than 27% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity15

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/331377521dbb2918e90e95bd439cf407c176ba3948cbb24350476b081e9139c8?d=identicon)[hoffmann](/maintainers/hoffmann)

---

Top Contributors

[![hoffmann](https://avatars.githubusercontent.com/u/7143?v=4)](https://github.com/hoffmann "hoffmann (8 commits)")

### Embed Badge

![Health badge](/badges/hoffmann-silex-view/health.svg)

```
[![Health](https://phpackages.com/badges/hoffmann-silex-view/health.svg)](https://phpackages.com/packages/hoffmann-silex-view)
```

###  Alternatives

[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9682.1M97](/packages/roots-acorn)[whitecube/nova-flexible-content

Flexible Content &amp; Repeater Fields for Laravel Nova.

8053.0M25](/packages/whitecube-nova-flexible-content)[mopa/bootstrap-bundle

Easy integration of twitters bootstrap into symfony2

7042.9M33](/packages/mopa-bootstrap-bundle)[limenius/react-bundle

Client and Server-side react rendering in a Symfony Bundle

3871.2M](/packages/limenius-react-bundle)[nicmart/string-template

StringTemplate is a very simple string template engine for php. I've written it to have a thing like sprintf, but with named and nested substutions.

2101.7M30](/packages/nicmart-string-template)[symfony/ux-icons

Renders local and remote SVG icons in your Twig templates.

555.8M69](/packages/symfony-ux-icons)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
