PHPackages                             siemendev/forskel - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. siemendev/forskel

ActiveSymfony-bundle[Utility &amp; Helpers](/categories/utility)

siemendev/forskel
=================

Forskel implements a fully decoupled frontend provider for multi site symfony projects.

021[2 issues](https://github.com/siemendev/forskel/issues)PHP

Since Apr 26Pushed 7y ago1 watchersCompare

[ Source](https://github.com/siemendev/forskel)[ Packagist](https://packagist.org/packages/siemendev/forskel)[ RSS](/packages/siemendev-forskel/feed)WikiDiscussions master Synced today

READMEChangelogDependenciesVersions (1)Used By (0)

[![Build Status](https://camo.githubusercontent.com/15ea0e17ba6c369e6797cb520d05d17bb278f03f07b677e72c23c31ff0b1b2c6/68747470733a2f2f7472617669732d63692e6f72672f7369656d656e6465762f666f72736b656c2e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/siemendev/forskel)[![Latest Stable Version](https://camo.githubusercontent.com/8eb5724c8548f6423f122a1c14ed474608b37bdf35c1f5ef90e082b1ca319e61/68747470733a2f2f706f7365722e707567782e6f72672f7369656d656e6465762f666f72736b656c2f762f737461626c65)](https://packagist.org/packages/siemendev/forskel)

Forskel
=======

[](#forskel)

Forskel is a loosely coupled frontend rendering library for multi-site symfony projects that share the same frontend markup.

**Sound good, right? *But what does that MEAN?***

When using the same frontend for multiple symfony projects, one way to keep redundancy low is to decouple the frontend architecture from the actual business logic into an own bundle. Taking over from this approach I´ve been developing *Forksel* to keep the templating out of the operational symfony projects.

With *Forskel* you're able to write super clean, object-oriented code instead of templating markup in the projects while you maintain the markup in the templates for all of them at one place: The *Forskel* based Extension-Bundle.

Give it a shot, take me to implementing *Forskel*!
--------------------------------------------------

[](#give-it-a-shot-take-me-to-implementing-forskel)

First of all, one thing is important to understand: **You don´t implement *Forskel* in a normal project.***Forskel* is intended to be used as a basic library/tool for your own external frontend bundle.

### Setup your first *Forskel* bundle

[](#setup-your-first-forskel-bundle)

So lets just jump right in and start with a basic implementation of *Forskel* for a demo project:

1. Setup an reusable Bundle for your project ouside your project root according to [The Symfony Documentation](https://symfony.com/doc/4.1/bundles/best_practices.html).
2. Install *Forskel* in your bundle: ` $ composer require siemendev/forskel`
3. Install your reuseable bundle in one of your main projects by configuring a local [repository](https://getcomposer.org/doc/05-repositories.md) in your composer.json. As long as you are developing locally, you probably want to link the bundle via the [*path* repository type](https://getcomposer.org/doc/05-repositories.md#path). Later on production environments you probably use the vcs repository to install specific stable versions of your bundle to your project.
4. **Keep in mind:** Unless you still want to use it, the twig templating engine will from now on no longer be used in your project´s repository. All templates will be created and maintained inside of your newly created bundle.

**That´s it already, we´re good to go!**

### Implementing your first model

[](#implementing-your-first-model)

1. Create your model file. e.g. \[bundle sources root\]/models/MyFancyPage.php

```
namespace vendor\FrontendBundle\Models;

use siemendev\ForskelBundle\Models\AbstractModel;
use siemendev\ForskelBundle\Models\ModelInterface;

class MyFancyPage extends AbstractModel
{
    /** @var string */
    public $headline;

    /** @var ModelInterface[] */
    public $contents;
}
```

*Pro tip:* Using private properties here with properly type-sensitive getters and setters allows you to force the right type for your property!

2. Create the corresponding template in \[bundle sources root\]/Resources/views/my-fancy-page.html.twig

```

    This is my fancy page.
    {% if model.headline is not empty %}
        {{ model.headline }}
    {% endif %}

    {% for content in model.contents %}
        {{ forskel_render(content) }}
    {% endfor %}

```

Okay, that´s it on the bundle side, lets move over to the project itself where you installed the bundle manually!

### Filling the model with data and rendering it

[](#filling-the-model-with-data-and-rendering-it)

In this example we´re using an existing controller, the IndexController from any project that has our previously created reusable bundle installed (see Setup 3).

Usually you would end this controller with a `return $this->render();` statement rendering the view, let´s see how *Forskel* changes this:

```
namespace vendor\ProjectBundle\Controller;

use vendor\FrontendBundle\Models\MyFancyPage;
use siemendev\ForskelBundle\Renderers\TwigRenderer;

class IndexController extends AbstractController
{
    /**
     * @Route("/", name="index")
     */
    public function index(TwigRenderer $forskel)
    {
        $page = new MyFancyPage();
        $page->headline = 'This page is so fancy!';

        return $forskel->render($page));
    }
}
```

**Pro tip:** If you don't want to inject the Renderer in every controller manually, try extending symfonys AbstractController to automaticly load the renderer.

**Master tip:** Overwrite the render() method in the extended AbstractController. This way you remove the build-in twig rendering, which forces the developers in the project even more to use Forskel for Frontend rendering.

Contribution welcome!
---------------------

[](#contribution-welcome)

If you´re trying out *Forskel* and have some feedback, [open up an issue](https://github.com/siemendev/forskel/issues)or start contributing directly into the github repository, I´m thankful for every help to make *Forskel* better!

###  Health Score

18

—

LowBetter than 8% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity3

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity37

Early-stage or recently created project

 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/218019b0f81dabec4d8d0927d1e22e76984e2dc026744985eecd364b6d0f1b3e?d=identicon)[siemendev](/maintainers/siemendev)

---

Top Contributors

[![siemendev](https://avatars.githubusercontent.com/u/11353665?v=4)](https://github.com/siemendev "siemendev (7 commits)")

### Embed Badge

![Health badge](/badges/siemendev-forskel/health.svg)

```
[![Health](https://phpackages.com/badges/siemendev-forskel/health.svg)](https://phpackages.com/packages/siemendev-forskel)
```

PHPackages © 2026

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