Symfony Teil 3: Twitter Bootstrap und Custom CSS

Nach der Generierung im vorherigen Kapitel besteht nun eine funktionierende Mini-Anwendung, die aber optisch nicht so reizvoll aussieht.

symfony_my_albums_naked

Weitere Template-Schicht

Durch die Anlage des Projektes und durch die Generierung sind nur zwei Arten von Twig-Dateien entstanden:

  •  Basis-Template in <htdocs>/symfony-myalbums/app/Resources/views/base.html.twig
  • einzelnen Seiten, z.B. <htdocs>/symfony-myalbums/src/Bjoerne/MyAlbumsBundle/Resources/views/Album/index.html.twig

Es empfiehlt sich für jedes Bundle dazwischen noch eine Template-Schicht einzuziehen. Dazu lege ich eine Datei layout.html.twig in <htdocs>/symfony-myalbums/src/Bjoerne/MyAlbumsBundle/Resources/views an. Diese hat folgenden Inhalt:

{% extends '::base.html.twig' %}
{% block title %}My Albums{% endblock %}
{% block stylesheets %}
{% endblock %}

Sie erweitert das Basis-Template und setzt die Blöcke title und stylesheets (hiermit werde ich später Twitter Bootstrap und eigene CSS-Dateien laden). In allen Seiten (edit.html.twig, index.html.twig, new.html.twig, show.html.twig) ersetze ich nun die Zeile

{% extends '::base.html.twig' %}

durch

{% extends 'BjoerneMyAlbumsBundle::layout.html.twig' %}

Twitter Bootstrap Variante 1: Manuelle Installation in web/lib

Auf der Suche nach Bootstrap in Zusammenhang mit Symfony stößt man direkt auf Twitter Bootstrap for Symfony2. Dieses Bundle unterstützt zum einen beim Laden von Bootstrap, stellt auch auch ein Form Theme bereit, so dass Formulare automatisch im Bootstrap-Stil erscheinen.

Wer davon nicht überzeugt ist (dummerweise bin ich das erst auch nicht, revidiere diese Entscheidung aber später), kann Bootstrap selbst laden. Das geht recht einfach. Ich kopiere dazu Bootstrap in <htdocs>/symfony-myalbums/web/lib/bootstrap. Um die CSS einzubinden, ist der folgende Code in layout.html.twig notwendig:

        {% stylesheets filter='cssrewrite' 'lib/bootstrap/css/bootstrap.css' %}
            <link rel="stylesheet" href="{{ asset_url }}" />
        {% endstylesheets %}

Der filter cssrewrite ist notwendig, damit referenzierte Grafiken (z.B. Bootstrap-Icons) richtig referenziert werden. Das Ergebnis sieht schon ganz gut aus.

symfony_my_albums_bootstrap

In der prod-Umgebung stehen die css-Dateien nur zur Verfügung, wenn sie statisch erzeugt wurden. Das geht mit dem folgenden Kommandozeilenaufruf:

php app/console assetic:dump --env=prod

Twitter Bootstrap Variante 2: Installation über Bundle

Als ich mich an die Anpassung der Formular setze, fällt mir auf, dass es nicht ohne ist, da manuell anzupassen. Ich stoße auf das Form Themes-Konzept von Symfony und finde heraus, dass das von Twitter Bootstrap for Symfony2 unterstützt wird. Ich verwerfe also die manuelle Installation und installiere das Bundle wie auf dessen Homepage beschrieben.

Eine genaue Befolgung der Anleitung ist wichtig, denn fehlt beispielweise nur eine Option, funktioniert das ganze nicht. Ich wähle die Variante With Assetic.

Lessphp, Twitter Bootstrap und JQuery müssen zusätzlich installiert werden. In meine composer.json füge ich ein (jquery unterscheidet sich von der Anleitung!):

        "leafo/lessphp": "0.4.0",
        "components/jquery": "2.0.*",
        "twitter/bootstrap": "2.3.*",
        "braincrafted/bootstrap-bundle": "dev-master"

Für die Icons lege ich symbolische Links an, wie in der Anleitung beschrieben.

Anpassung der Seiten und Nutzung von Bootstrap-CSS-Klassen

Nur blaue Links machen die Mini-Anwendung noch nicht schön. Besser wäre es wenn die Anwendung Bootstrap-Klassen für Tabelle, Formular-Elemente und Buttons verwendet.

Tabellen

Den Tabellen in index.html.twig und show.html.twig gebe ich die CSS-Klasse table mit. Das ist noch die einfachste Übung.

Formulare

Ich möchte, dass meine Formulare die Klasse form-horizontal und die darunterliegenden Elemente die entsprechenden Bootstrap-Klassen (z.B. control-group) bekommen. Dazu sind mehre Schritt notwendig. Zunächst müssen die form-Aufrufe durch form_start, form_widget und form_end ersetzt werden. Aus

{{ form(form) }}

wird dann

    {{ form_start(form, {attr: {class: 'form-horizontal'}}) }}
        {{ form_widget(form, {'form_type': 'horizontal'}) }}
    {{ form_end(form) }}

Das sieht schon sehr nach Bootstrap aus, aber der Submit-Button ist noch falsch ausgerichtet. Das lässt sich lösen, in dem der Submit-Button nicht mehr vom Controller erstellt wird, sondern in den twig-Dateien. Aufrufe wie:

...
$form->add('submit', 'submit', array('label' => 'Create', 'attr' => array('class' => 'btn')));
...
$form->add('submit', 'submit', array('label' => 'Update', 'attr' => array('class' => 'btn')));
...
->add('submit', 'submit', array('label' => 'Delete', 'attr' => array('class' => 'btn')))
...

entferne ich einfach aus dem Controller und passe die twig-Dateien an, z.B.

    {{ form_start(form, {attr: {class: 'form-horizontal'}}) }}
        {{ form_widget(form, {'form_type': 'horizontal'}) }}
        <div>
            <div>
                <button type="submit">Create</button>
            </div>
        </div>
    {{ form_end(form) }}

Buttons

Alle Buttons bekommen die btn-Klasse. Außerdem setze ich noch Icons ein.

            <a href="{{ path('album_new') }}" class="btn">
                <i class="icon-plus-sign"></i>
                Create a new entry
            </a>

Weitere Anpassungen mit eigener CSS-Datei

Das Zwischenergebnis ist schon ganz ok:

symfony_my_albums_bootstrap_button_list

Zwei Dinge fallen auf:

  • Es fehlt ein Außenabstand, der Inhalt klebt förmlich am Browser-Rand.
  • Die Bootstrap-Buttons befinden sich noch in gewöhnlichen Bullet-Point-Listen, sollen aber ohne Bullets nebeneinander stehen.

Ich lege eine application.css in <htdocs>/symfony-myalbums/src/Bjoerne/MyAlbumsBundle/Resources/css an:

body {
    margin: 30px;
}
ul {
    list-style: none;
    margin: 0;
}
ul li {
    float: left;
    margin-right: 10px;
}
.table, .form-horizontal {
    margin-bottom: 40px;
}

Damit das CSS genutzt werden kann, ist die Registrierung des Bundles in der Assetic-Konfiguration notwendig. In der config.yml konfiguriere ich daher, dass Assets des Bundles berücksichtigt werden sollen:

assetic:
    debug:          %kernel.debug%
    use_controller: false
    bundles:        [BjoerneMyAlbumsBundle]

Damit die CSS-Datei geladen wird, passe ich layout.html.twig an

{% extends '::base.html.twig' %}
{% block title %}My Albums{% endblock %}
{% block stylesheets %}
    <link rel="stylesheet" href="{{ asset('css/bootstrap.css') }}">
    {% stylesheets '@BjoerneMyAlbumsBundle/Resources/css/application.css' filter='cssrewrite' %}
        <link rel="stylesheet" href="{{ asset_url }}" />
    {% endstylesheets %}
{% endblock %}

Das kommt der Applikation von Zend nun schon recht nahe, aber ist durch wesentlich weniger (vor allem selbstgeschriebenen) Code entstanden. Das Thema CSS ist noch ausbaufähig, indem LESS oder SASS statt reinem CSS zum Einsatz kommen.

symfony_my_albums_final

Projekt auf Github

Das erstellte Projekt steht bei Github zur Verfügung: https://github.com/bjoerne2/symfony-myalbums.

Lokale Installation:

  • Klonen in dein htdocs-Verzeichnis
  • Einrichtung lokale Datenbank, z.B. symfony_myalbums
  • Kommandozeile: composer install
  • Eingabe der Datenbankdaten
  • Kommandozeile: app/console doctrine:schema:create
  • Im Browser: http://localhost/symfony-myalbums/web/app_dev.php/album/

Fazit

Aller Anfang ist schwer und so musste ich doch viele Dinge nachlesen, darunter auch viele Kleinigkeiten. Auch kam es vor, dass ich Zeit für Fehlersuche aufgewendet habe, weil mir die Erfahrung mit Symfony noch fehlte.

Aber die Arbeit mit Symfony macht Spaß und ich glaube, dass die Entwicklung noch richtig Fahrt aufnehmen wird, wenn ich mit den Konzepten von Symfony richt vertraut bin.

 

bjoerne_com_bjoern_weinbrenner_softwareentwickler_icon_leistungen_02

Lust auf mehr? Als PHP-Entwickler und Softwarearchitekt kann ich Sie in Ihren Projekten unterstützen. Melden Sie sich gerne bei mir.

2017-01-28T14:29:42+00:00 10.09.2013|Tags: , , , , , |4 Comments

4 Kommentare

  1. Michael Brauner 12. September 2013 um 15:12 Uhr- Antworten

    Hallo Björn. Ich verzweifle. Ich möchte endlich mal entwickeln können. Stattdessen stresse ich mich rum mit der Installierung von diesem blöden Bootstrap Package. Ich habe alles so gemacht, wie beschrieben. Ich versteh es einfach nicht. Bin echt verzweifelt. Ich sehne mich danach endlich wieder php code schreiben zu können. Stattdessen muss ich mich damit rumquälen stylesheets und js- dateien einbinden zu dürfen :D. Überlege schon, ob ich symfony nicht sein lasse.

    Wenn du mir helfen könntest, wäre ich dir unendlich dankbar.

    Liebe Grüße
    Michael

    • Björn Weinbrenner 12. September 2013 um 15:29 Uhr- Antworten

      Hallo Michael!
      Wo drückt der Schuh denn genau? Hast du eine Fehlermeldung oder Fehlerbeschreibung für mich?
      Gruß
      Björn

      • Michael Brauner 12. September 2013 um 16:40 Uhr- Antworten

        Fehlerbeschreibung ist: ich mache alles so, wie beschrieben. Aber es wird kein Stylsheet und kein js eingebunden. Es geht einfach nicht. Oh man. Meine Nerven 😀

  2. Anja 11. Januar 2014 um 20:17 Uhr- Antworten

    Hallo Björn,

    habe die Twitter Bootstrap gerade erst entdeckt und vielleicht wird es eine dauerhafte Lösung für mich. In deinem Fazit erkenne ich mich voll wieder. Es ist sicher aufwendig, wenn man Symfony angeht aber man lernt halt auch die Vorteile und das System zu schätzen. Ich glaube es lohnt sich, so oder so. Nur mit Twig kann ich noch nichts anfangen. :/

    Danke für deinen Blogeintrag und viele Grüsse,

    Anja

Hinterlassen Sie einen Kommentar