Advertisement
  1. Code
  2. OOP

AntiPatterns-Grundlagen: Rails-Ansichten

by
Read Time:14 minsLanguages:

German (Deutsch) translation by Władysław Łucyszyn (you can also view the original English article)

In dieser anfängerfreundlichen Serie beschäftigen wir uns mit AntiPatterns, die - wie der Name schon sagt - so ziemlich das Gegenteil von Designmustern darstellen. Sie sind Entdeckungen von Lösungen für Probleme, die Sie unbedingt vermeiden sollten.

In diesem Artikel konzentrieren wir uns auf das Haupt-View AntiPattern - PHPitis - und arbeiten einige Techniken aus, um Ihre Ansichten schlank und gemein zu halten. Tonnenweise Ruby-Code in Ihren Ansichten zu haben, ist nicht nur böse, sondern oft einfach unnötig.

Themen

  • Rails-Ansichten
  • PHPitis
  • Helfer extrahieren
  • Hilfreiche Helfer
  • Formen
  • Teilweise
  • Bedingter Inhalt
  • Semantisches Markup

Rails-Ansichten

Rails wird standardmäßig mit ERb (Embedded Ruby) geliefert, und ich denke, es ist vorerst nicht erforderlich, coole View-Rendering-Engines wie Slim für unsere Beispiele zu verwenden. Wenn Sie der Meinung sind, dass "Konvention über Konfiguration" hauptsächlich für die Modell- und Controller-Ebenen gilt, verpassen Sie viele der Extras, die die Arbeit mit Rails so schnell und fortschrittlich machen. Die Pflege der Ansichtsebene umfasst nicht nur die Art und Weise, wie Sie Ihr Markup erstellen, sondern auch CSS/Sass, JavaScript, Ansichtshilfen und Ihre Layoutvorlagen. Aus diesem Blickwinkel betrachtet wird es etwas tiefer, als Sie vielleicht zunächst denken. Die schiere Anzahl von Technologien, die bei der Erstellung Ihrer Ansichten eine Rolle spielen können, legt nahe, dass darauf geachtet werden sollte, dass die Dinge ordentlich, klar und flexibel bleiben.

Da die Art und Weise, wie wir Markups und Stile schreiben, viel weniger eingeschränkt ist als die Domänenmodellierung, sollten Sie besonders vorsichtig sein, um die Dinge so einfach wie möglich zu halten. Wartung sollte so ziemlich Ihre oberste Priorität sein. Da Redesigns oder Designiterationen häufiger auftreten können als umfangreiche Änderungen an Ihrer Modellebene, erhält die Vorbereitung auf Änderungen eine ganz neue Bedeutung, wenn es um Ihre benutzerbezogene Ebene geht. Mein Rat: Bauen Sie nicht unbedingt für die Zukunft, aber unterschätzen Sie auf keinen Fall die Änderungsrate - insbesondere, wenn Sie einen dieser "Ideengeber" haben, der sich mit Implementierungen im Team auskennt. Was mir an Rails Ansatz für Ansichten in MVC gefällt, ist, dass er als gleich wichtig behandelt wird und die Lehren aus der Modelldomäne in die Ansicht einbezogen wurden - wann immer dies möglich und nützlich ist. Andere Frameworks scheinen zuzustimmen, da sie viele dieser von Rails entwickelten Ideen integriert haben.

Da der letzte Artikel etwas umfangreicher war, habe ich dieses Thema als kleine Verschnaufpause gewählt. Die folgenden Artikel über Rails-Controller und Tests sind wieder größer. Die AntiPatterns für Ansichten sind nicht so viele, aber sie sind dennoch gleich wichtig. Wir konzentrieren uns auf die Hauptmethode, PHPitis, und arbeiten einige Techniken aus, um Ihre Ansichten schlank und gemein zu halten. Da die Ansicht Ihre Präsentationsebene ist, sollten Sie möglicherweise besonders darauf achten, keine gefährlichen Verschmutzungen zu verursachen. Lassen Sie uns anfangen!

PHPitis

Warum haben wir überhaupt MVC? Ja, denn die Trennung von Bedenken schien das Vernünftigste zu sein. Sicher, die Implementierungen dieser Idee variieren hier und da ein wenig, aber das Gesamtkonzept, unterschiedliche Verantwortlichkeiten für jede Schicht zu haben, ist die Kernmotivation für die Erstellung robuster Anwendungen. Tonnenweise Code in Ihrer Ansichtsebene zu haben, ist Entwicklern von der PHP-Seite vielleicht nicht fremd - obwohl ich höre, dass ihre Frameworks bereits aufgeholt haben (stark beeinflusst von Dingen wie Rails?) -, aber in Ruby-Land haben diese Dinge lange gedauert war ein lautstarkes AntiPattern.

Abgesehen von den offensichtlichen Problemen wie dem Mischen von Verantwortlichkeiten und Duplikaten fühlt es sich einfach böse und faul an - auch ein bisschen dumm, um ehrlich zu sein. Klar, ich verstehe, wenn Sie viel innerhalb eines Rahmens, einer Sprache oder eines anderen Ökosystems entwickeln, ist es leicht, sich an solchen Dingen zu beteiligen oder taub zu werden. Was ich an den Leuten mag, die Ruby pushen, ist, dass diese Dinge viel weniger Gewicht zu haben scheinen - das könnte ein Grund sein, warum Innovationen in der Community nie ein Problem zu sein schienen. Was am besten funktioniert, gewinnt das Argument, und wir können vorwärts gehen.

Ist dies also ein ganzer Abschnitt, der sich dem Bashing von PHP widmet? Überhaupt nicht! In der Vergangenheit hatten PHP-Apps den Ruf, schwache Trennungen zwischen Modellen, Ansichten und Controllern zu haben (vielleicht war dies einer der Hauptgründe, warum die Leute das Schreiben von Apps mit Rails für viel attraktiver hielten). Es schien nicht so sexy, einzelne Dateien mit Code für alle drei Ebenen zu haben. Wenn wir also Tonnen von Ruby oder Domain-Code in unsere Ansichten einfügen, sieht es aus wie der gefürchtete PHP-Stil der Strukturierung von Dingen - PHPitis. Nur ein paar Dinge sind so schlecht, wenn es um die Entwicklung von Web-Apps geht. Wenn Sie sich für glückliche Entwickler und Ihre eigene Zukunft interessieren, kann ich nicht verstehen, warum irgendjemand diesen Weg gehen würde - es liegt anscheinend nur Schmerz vor Ihnen.

Rails bietet viele Extras, um den Code in der Ansicht so gering wie möglich zu halten. Sie müssen die Methoden von Helfern, Layouts und Präprozessoren kennenlernen, um eine sauberere Ansicht zu erzielen. Eine einfache Faustregel lautet, Domain-Logik aus Ihren Ansichten herauszuhalten - keine Verknüpfungen!

Der Preis dafür, dass man faul ist, ist schwer zu überschätzen. Der Ruby-Code, der sich in der Präsentationsschicht befinden muss, sollte so klein und einfach wie möglich sowie intelligent organisiert sein. Ihre Belohnung wird Code sein, dessen Erweiterung und Pflege eine Freude ist, und neue Teammitglieder werden es auch leichter haben, ihre Köpfe um die neue Codebasis zu wickeln. Als Bonus werden nette Freak-Designer, die Code schreiben, auch nicht böse sein und verdorbenes Essen in Ihrem Salat verstecken, wenn Sie Tonnen von Ruby-Code aus ihrem Markup heraushalten.

Hilfreiche Helfer

Wenn Sie die unzähligen Hilfsmethoden in Rails kennen, wird die Qualität Ihrer Präsentationsebene erheblich verbessert. Es räumt nicht nur auf und sorgt für gelegentliche Geschwindigkeitssteigerungen bei der Produktivität, sondern hilft Ihnen vor allem bei der Bekämpfung von PHPitis.

Das, was Sie an diesen Helfern schätzen sollten, ist, dass sie Auszüge aus häufig benötigtem Code darstellen. Anstatt das Rad neu zu erfinden, prüfen Sie im Zweifelsfall, ob es noch keinen Helfer gibt, der Ihr Problem in der Ansicht löst - das gilt natürlich auch für Modelle und Steuerungen.

Hier ist eine Liste von Helfern, die Sie sich gleich ansehen sollten:

  • form_for
  • Andere Helfer für Formulare.
  • fields_for
  • link_to
  • content_for
  • Und natürlich schreiben Sie Ihre eigenen.

Formen

Schauen wir uns zuerst form_for an. Ich weiß, dass Formulare ein bisschen langweilig und für ein Thema nicht so sexy sind, aber ich empfehle Ihnen dringend, sie zu lesen, um sich mit den feineren Details vertraut zu machen. Es ist wichtig zu verstehen, wie sie funktionieren. Ich erinnere mich, dass ich oft nur einen Blick über sie geworfen habe, ohne ihnen viel Aufmerksamkeit zu schenken. Natürlich können Sie sie ganz einfach zum Arbeiten bringen, ohne zu verstehen, was unter der Haube vor sich geht. In Zukunft könnte ich mir die Zeit nehmen, einen vollständigen Artikel darüber zu schreiben. In der Zwischenzeit empfehle ich dringend, dass Sie ein wenig Zeit damit verbringen, die Dokumentation zu überprüfen - zumindest werden Sie zu schätzen wissen, wie bequem Rails es macht, mit Formularen umzugehen.

Das Hässliche

Das folgende Beispiel zeigt Ihnen den HTML-Code eines kleinen Formulars, das wir zum Erstellen von Agenten benötigen. Es werden nur drei Parameter als Eingabe akzeptiert: name, number und licence_to_kill. Eigentlich viel Code für diese kleine Aufgabe. Das authenticity_token stammt von Rails - eine Sicherheitssache, die die App vor "Fälschung von standortübergreifenden Anforderungen" schützt.

some.html.erb

Das Schreiben eines Formulars von Hand ist nicht nur langwierig, sondern auch fehleranfällig. Wenn wir uns dem so nähern würden, müssten wir auch das Problem mit den unterschiedlichen Routen und CSS-Klassen lösen, die wir möglicherweise zum Erstellen eines neuen Objekts und zum Aktualisieren eines vorhandenen Objekts benötigen. Tatsächlich müssten wir Formulare duplizieren Datensätze erstellen und bearbeiten. Wie Sie gleich sehen werden, trifft Rails Sie mehr als zur Hälfte. Abschluss: Wie auch immer Sie es ausdrücken, der manuelle Ansatz ist unangenehm und unpraktisch.

Das Schlechte

Wir könnten den folgenden Weg gehen, der die Konventionen in Rails nicht perfekt nutzt. Kopf hoch, tu es nicht. Grundsätzlich zeigt sich, dass Sie die verfügbaren Werkzeuge nicht zu Ihrem Vorteil nutzen und das Formular für new Aktionen und edit aktionen duplizieren.

some.html.erb

Was hier passiert, ist, dass der Form Builder das Modell trägt, das Sie für das Formular benötigen.

Hinter den Kulissen wird die obige Zeile wie folgt erweitert:

Die Methode form_for akzeptiert einige Argumente:

  • ein Symbol oder eine Zeichenfolge zur Angabe des Objekts
  • ein url-Hash
  • ein html-Hash
  • ein namespace-Hash

Der URL-Hash dient zum Festlegen der Routing-Optionen. Das bedeutet, dass Sie manuell angeben können, an welchen Routing-Pfad Sie das Formular senden - benannte Routen sind hierfür hilfreich. Dieser Stil wird als "generischer Weg" bezeichnet, da Sie den Aufruf von form_for manuell konfigurieren müssen.

Warum ist diese Lösung nicht optimal? Weil wir die Geschäftslogik so weit wie möglich von unseren Ansichten und Controllern fernhalten möchten. Ein Nebeneffekt davon ist, dass wir bei Bedarf weniger Teile wechseln müssen.

HTML

Falls Sie es verpasst haben, hat uns dieser Ansatz nicht automatisch IDs und Klassen für das form-Tag zur Verfügung gestellt. Die für input-Tags wurden jedoch für Sie generiert. Wir werden das in einer Minute beheben. Wissen Sie einfach, was Sie kostenlos bekommen können und dass Sie dies wahrscheinlich zu Ihrem Vorteil nutzen sollten. Wenn Sie etwas anderes oder einen zusätzlichen Namespace benötigen, können Sie den html-Hash oder den namespace-Hash verwenden, um die Dinge etwas genauer anzugeben.

some.html.erb
HTML

Nicht schlecht! Jetzt hat das form-Tag die angegebene Klasse und ID - was auch immer Ihren Blutfluss bewirkt - und die input-Tags haben einen Namespace mit mi6. Fast dort.

Die Gute

Dieser Stil wird als "ressourcenorientierter Stil" bezeichnet und enthält die geringste Menge an Ruby, die Sie zum Schreiben in Ihre Ansichten benötigen. Mit diesem Ansatz möchten wir uns auf die automatisierte Identifizierung von Ressourcen verlassen. Rails ermittelt anhand des Objekts selbst, welche Routen benötigt werden. Darüber hinaus erhalten Sie eine andere HTML-Ausgabe zum Erstellen eines neuen Objekts oder zum Bearbeiten eines vorhandenen Objekts. Hinter den Kulissen fragt Rails das Objekt nur, ob es bereits vorhanden ist, und handelt entsprechend.

Das Erstellen von Formularen auf diese Weise ist eine clevere Anwendung von Konventionen und hilft, Doppelarbeit zu vermeiden. Eine Linie und das ganze schwere Heben ist für Sie erledigt.

some.html.erb

Viel besser, nicht wahr? Jetzt bekommen wir genau das, was wir für bestehende und neue Objekte benötigen. Außerdem mussten wir unserer Senden-Schaltfläche keinen Text hinzufügen. Rails hat sich darum gekümmert und passt sich auch neuen oder vorhandenen Objekten an.

HTML für ein neues Objekt
HTML zum Bearbeiten von Objekten

Beim Bearbeiten von Objekten wird dies auch in der HTML-Ausgabe berücksichtigt, indem die ID zur Formular-ID und die Route oder Aktion hinzugefügt werden, die zum Aktualisieren eines bestimmten Objekts erforderlich ist.

Ein Wort zur Rails-Magie. Wenn Leute in genau diesen Situationen argumentieren, dass Rails für ihren Geschmack zu magisch ist, denke ich oft, dass dies einfach bedeuten könnte, dass sie nicht genug Zeit damit verbracht haben, die Werkzeuge ihres Fachs zu erlernen. Wenn Sie sich die Zeit nehmen, diese Werkzeuge zu beherrschen, werden Sie häufig verstehen, warum eine Vereinfachung oder Extraktion vorgenommen wurde, und sie wirken auch viel nüchterner und unkomplizierter.

Beachtung!

In den obigen Codebeispielen wurde form_object als Blockparameter verwendet. Dies wird nicht als bewährte Methode empfohlen, wurde jedoch durchgeführt, um Sie daran zu erinnern, was dieses Objekt darstellt und was sich aus form_for ergibt. Die meisten Leute benutzen nur ein einfaches |f| oder |form|, die viel schöner und prägnanter aussieht.

Übrigens sind Dinge wie label, text_field, check_box und dergleichen nur Hilfsmethoden, die für das Form Builder-Objekt aufgerufen werden. Es gibt eine Menge davon, die so ziemlich jeden möglichen Bedarf abdecken, dem Sie begegnen könnten.

some.html.erb

Prägnant und liest sich gut, oder?

Teilweise

Sammlungen sind eine weitere Sache, über die wir nicht zu ausführlich sprechen möchten. Das Rendern von Partials für einzelne Objekte von Sammlungen ist so präzise und unkompliziert - wenn es richtig gemacht wird -, dass Sie meiner Meinung nach kaum eine Entschuldigung dafür haben, Rails-Konventionen nicht zu verwenden, um den Ruby-Ansichtscode zu reduzieren.

Lassen Sie uns die Dinge mit diesem umdrehen und mit einem Beispiel beginnen, das Ihnen zeigt, wie Sie ermutigt werden, dies zu tun. Unterwegs werde ich erklären, was Sie auch weglassen können.

Die Gute

app/views/agent/index.html.erb

Die render-Methode ist ziemlich schlau. Die obige Zeile ist alles, was Sie schreiben müssen, um eine Sammlung zu durchlaufen. Wenn Sie in dieser Ansicht etwas ändern müssen, handelt es sich um eine sehr kleine Änderung - und daher um eine kleine Fehlerursache.

Was hier passiert, ist, dass das Framework bestimmen kann, welchen Teil es benötigt. Durch den Namen des Objekts weiß es, wo nach dem Teil gesucht werden muss - vorausgesetzt, Sie halten sich an die herkömmliche Benennung von Dingen. So wie ich das sehe, ist dies ein gutes Beispiel dafür, wie Rails nicht versucht, Sie mit Zauberei zu beeindrucken. Das Rails-Team arbeitet hart daran, Ihnen das Leben zu erleichtern, indem es sich wiederholende Bürokratie abbaut.

app/views/agents/_agent.erb

Das einzige andere, was erforderlich ist, damit dies funktioniert, ist, eine Teilvorlage am entsprechenden Pfad im Verzeichnis Ihres Objekts zu platzieren und die benötigten Attribute aus dem Objekt zu extrahieren. Sie müssen keine eigenen Schleifen schreiben. Es ist schnell und einfach, praktisch und pragmatisch, würde ich sagen.

Diese Extraktion wurde ursprünglich durchgeführt, da der Name des Teils ohnehin die meiste Zeit der Name des iterierten Objekts war. Daher war es einfach, eine Konvention zu erstellen, die diese allgemeine Aufgabe effektiver behandelt.

Das Schlechte

OK, jetzt, da wir wissen, wie wir damit umgehen sollen, schauen wir uns an, was Sie vermeiden könnten und sollten. Das folgende Beispiel ist nur eine schlechte Verwendung von Rails, aber ich würde es diesmal nicht als hässlich bezeichnen.

app/views/agents/index.html.erb

Sie erhalten das gleiche Ergebnis wie oben, aber es ist definitiv ausführlicher. Das Durchlaufen der Sammlung in der Ansicht ist nicht mehr erforderlich. Wenn Sie render wie oben verwenden, wird der Blockparameter-agent impliziert, und Sie können ihn einfach ohne each-Schleife verwenden. Halten Sie sich also von Code wie diesem fern - Sie sehen dadurch nicht besonders gut aus (aber niemand wird Ihren Kopf dafür einsammeln). Es ist einfach nicht elegant und trägt zur PHPitis bei.

Helfer extrahieren

Die naheliegendste Lösung zum Bereinigen von Code aus Ihren Ansichten besteht darin, das Schreiben von Code zu vermeiden oder ihn intelligent zu extrahieren. Angenommen, wir möchten die Namen unserer Agenten in der Indexliste verschlüsseln. Wir sollten diesen Code nicht direkt in unsere Ansichten aufnehmen. Wenn wir feststellen, dass das Modell auch nicht die geeignete Ebene ist, um dies zu platzieren, ist möglicherweise ein benutzerdefinierter Helfer im Verzeichnis app/helpers die richtige Wahl.

app/helpers/agents_helper.rb

Indem wir dies in ein Modul im Hilfeverzeichnis packen, haben wir jetzt in unseren Ansichten Zugriff auf diese Methode. Bitte geben Sie bestimmten Helfern ihr eigenes Zuhause und stellen Sie nicht alles auf ApplicationHelper(app/helpers/application_helper.rb), was wirklich für "globalere" Dinge gedacht ist.

Jetzt kann ich in meiner Teilvorlage - oder in jeder Ansicht - auf diesen kleinen Kerl zugreifen, um meine Agentensammlung zu rendern.

app/views/agents/_agent.erb

Ihre eigenen benutzerdefinierten Helfer sind eine großartige Möglichkeit, Ihre Ansichten sauber und gesund zu halten. Und wie Sie gesehen haben, ist es so schnell und einfach, dass es kaum eine Entschuldigung gibt, zu faul zu sein und sie nicht für den Kampf gegen PHPitis zu extrahieren.

Bedingter Inhalt

Die Hilfsmethode content_for ist ein praktisches Werkzeug zum Extrahieren von Inhalten, die für einen Teil nicht wirklich in die Rechnung passen, aber ein wenig gekapselt werden müssen. Auf diese Weise können Sie ein bisschen Markup speichern, das Sie Seite für Seite anwenden können - Sie geben es bei Bedarf in das Layout ein. In der Größe sollte es viel kleiner sein als Teilbilder oder sogar Layouts.

Diese Technik kann Ihnen auch den Schritt ersparen, eine eigene Methode dafür zu erstellen. Navigationsmenüs oder Seitenleisten sind häufig Beispiele, bei denen dieser Helfer nützlich wird. Angenommen, Sie möchten einen Platz in Ihrem Menü haben, der nur für Administratoren bestimmt ist, aber Sie müssen nicht das gesamte Layout anpassen. Oder Sie haben Seiten, auf denen die Seitenleiste nicht benötigt wird. Mit content_for fügen Sie das, was Sie benötigen, Seite für Seite dort ein, wo Sie es benötigen. Vervielfältigung nicht mehr!

app/views/agents/index.html.erb
app/views/layouts/application.html.erb

Abgesehen von der Tatsache, dass dieser header ein guter Kandidat für die Extraktion in einen Teil ist, sehen Sie sich den Abschnitt yield:double_o_navbar an. Dies ist eine nachgebende Region, die Code aus einem content_for-Block einfügt. Code wird nur eingefügt, wenn die Symbolnamen übereinstimmen. Hier möchten wir, dass nur Double-O-Agenten Zugriff auf bestimmte Links in der Navigationsleiste haben. Alle anderen sehen nur Home and About. Denken Sie an die speziellen Links, die ein Administrator sehen muss, um niemals eine öffentliche Oberfläche zu erhalten.

Sie können diesen Helfer auch verwenden, um bei Bedarf id- oder class attribute in HTML-Tags einzufügen. Hin und wieder ist dies praktisch.

Eine weitere häufige Verwendung ist das dynamische Auffüllen des <title> einer Seite mit einem content_for-Block.

app/views/layouts/application.html.erb
some.html.erb

Sie platzieren einfach den gewünschten Titel in einem content_for-Block und das Anwendungslayout fügt ihn für Sie ein. Sie können damit klüger werden, aber das sollte vorerst ausreichen. Sollten Sie keinen Titel benötigen oder vergessen, einen hinzuzufügen, dann das logische || wird eintreten und einen Standard Ihrer Wahl ergeben. Im obigen Beispiel müssen wir prüfen, ob ein Titel vorhanden ist, da sonst die Standardeinstellung nicht funktioniert.

Was Sie definitiv nicht tun möchten, ist, Instanzvariablen für solche Dinge zu erstellen. Einzelverantwortung, erinnern Sie sich?

Noch etwas: Sie können fragen, ob Seiten einen content_for-Block haben.

app/views/layouts/application.html.erb

Auf diese Weise können Sie vermeiden, dass Markups dupliziert werden, die für die Gestaltung einer Seite relevant sind, die sich anpasst, ob Elemente auf einer Seite vorhanden sind oder nicht.

Semantisches Markup

Dies ist etwas, das Sie definitiv vermeiden möchten.

Das obige Markup stammt aus der Bootstrap-Dokumentation und gibt an, wie die Spalten aussehen sollen - Informationen, die keine semantische Bedeutung haben und tatsächlich in Ihre Stylesheets gehören. Das ist das Zeug, über das Designer Albträume haben.

Was ist damit los? Dies ist wichtig, da - neben der fragwürdigen Benennung von Klassen - unsemantisches Markup die Trennung von Bedenken verletzt. Ihr Markup sollte nicht mit Styling-Informationen belästigt werden. Stattdessen sollten beide für sich stehen und es Ihnen ermöglichen, Stile mühelos auszutauschen - ohne Ihren HTML-Code zu berühren. Es ist nicht so schwierig, wie es zunächst klingen mag. Es erfordert jedoch ein wenig Disziplin.

Wenn Sie in der Lage sind, diese Styling-Informationen aus Ihrem Markup herauszuhalten, haben Sie PHPitis auf einer anderen Seite effektiv reduziert - für Designer eine wesentliche! Auch die Verwendung von generischen Divs ohne inhärente Bedeutung ist ein weiteres Beispiel für ein schlechtes Markup. HTML5 bietet Ihnen viele nützliche Elemente, die Ihrem zukünftigen Selbst, anderen Entwicklern und Suchmaschinen mehr Informationen vermitteln. Das Benennen ist angeblich schwierig, aber HTML5 bietet Ihnen viele semantische Elemente, die Ihre Optionen in dieser Hinsicht erheblich vereinfachen.

Abschließende Gedanken

Ich hoffe, Sie haben gesehen, dass Rails Views nicht viel Liebe brauchen, um zu glänzen. Entwickler können in Bezug auf die Front-End-Ebene ein bisschen schlau sein. Der Umgang mit Markups scheint manchmal etwas darunter zu liegen - HTML schreiben, DUH! Nun, ich sollte keine Steine werfen, aber ich habe eine fein abgestimmte, gut geschliffene Präsentationsschicht zu schätzen gelernt. Es macht viel mehr Spaß, damit zu arbeiten, und wenn es richtig gemacht wird, macht es viel schneller, die unvermeidlichen Änderungen vorzunehmen. Das Parsen von Tonnen von Ruby-Code gemischt mit schlecht geschriebenem Markup ist in meinem Buch keine lustige Erfahrung.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.