| 

.NET C# Java Javascript Exception

4
In einer kleinen Website (nein, nicht dieselbe wie in meiner vorigen Frage) muß ich auf ein paar Seiten Listen strukturierter Daten formatieren. Das Aussehen eines einzelnen Listeneintrags ist relativ stabil, und die Listen ändern sich zu selten, als daß es mir eine serverseitige Lösung wert wäre, und zu oft, um jedesmal das finale HTML editieren zu wollen.

Mein aktueller Ansatz: ich erfasse die Daten im JSON-Format und nutze ein Template und knockoutjs, um die Listen zu generieren. Dann ziehe ich mir aus meinem Entwickler-Browser den generierten HTML-Code, werfe die nun nicht mehr nötigen Verweise auf knockout und die JSON-Datei raus und lege das Ergebnis auf den Server. (Warum? Suchmaschinen sollen die fertige Seite sehen, und ich will auch keinen Besucher zwingen, Javascript zu erlauben, um eine letztlich ja doch statische Seite ansehen zu können.)

Funktioniert, ist aber doch etwas unhandlich. Deshalb die Frage: wie könnte man das besser machen? Da ich sowieso schon gerne mit Visual Studio arbeite, habe ich mir überlegt, dass ich dort ein T4 Text Template schreiben könnte, das meine Seiten erzeugt. Sieht vielleicht nicht so schön aus wie die Javascript-Variante, aber ich spare mir die nervige Nachbearbeitung. Was haltet ihr davon, und welche Alternativen fallen Euch noch ein?

(Randbedingung: ich möchte die fertigen Seiten lokal direkt von der Platte im Browser öffnen können und auch sonst keinerlei serverseitige Programmierung einsetzen müssen.)
08.01.2013
Matthias Hlawatsch 13,2k 4 9
4 Antworten
2
Eine Möglichkeit wäre es den Prozess mit NodeJS+jQuery zu automatisieren.

Transforming HTML with Node.js and jQuery
09.01.2013
Floyd 14,6k 3 9
1
@Matthias: btw. Glückwunsch zum 10k Rating :)
Floyd 09.01.2013
+1 und ein doppeltes Dankeschön!
Deine Idee gefällt mir aus mindestens 3 Gründen:
- Ich kann weiter mit knockout arbeiten, muß also die Templates nicht anfassen.
- Der Technologie-Zoo wird nicht größer, denn nodejs ist sowieso schon an Bord (weil ich stylus verwende).
- Ich bekomme eine Gelegenheit, mal was mit Typescript zu machen (wenn schon, denn schon...).
Matthias Hlawatsch 09.01.2013
Ich wußte doch, daß ich noch was vergessen habe: auf die gleiche Weise könnte ich auch die "Client Side Includes" aus meiner anderen Frage implementieren. Ich seh schon, ich muß bald mal die IDE anwerfen. ;-) Ergebnisse dann irgendwann hier...
Matthias Hlawatsch 09.01.2013
1
Wenn Du die Daten im XML-Format bereitstellen kannst, wäre XSLT eine Option.
In einem Projekt setze ich genau diese Technik ein, um wie von Dir auch gefordert, die fertigen Seiten direkt lokal von Platte im Browser öffnen zu können.
T4 ist auch eine Option, hier hast Du mehr Möglichkeiten als bei XSLT. Aus der KISS Perspektive würde ich für XSLT plädieren.

PS: Ich habe gesehen, dass Du am 21.01. auch am Architecture Dojo teilnimmst. Nachdem ich ja im Herbst schon Floyd kennenlernen durfte, freu ich mich sehr, auch Dich mal persönlich zu treffen.
09.01.2013
ffordermaier 8,4k 3 9
+1 Dankeschön - stimmt, so könnte man es auch machen. XSLT fällt für mich aber nicht in die KISS-Kategorie - die wenigen Male, die ich was damit gemacht hab, fand ich die Technologie immer furchtbar unintuitiv und schwer zu debuggen. Und dazu kommt, dass die Daten manuell erfasst werden - theoretisch wäre also XML möglich, praktisch macht das aber keinen Spaß. JSON geht da grad noch so.

Freue mich auch schon aufs Kennenlernen am 21.!
Matthias Hlawatsch 09.01.2013
0
Da ich seit geraumer Zeit eher in der Ruby (on Rails) Welt zuhause bin wäre mein Ansatz folgender. Ein Ruby-Script schreiben das:
1 Das die JSON-Daten holt und in einen Hash lädt (ein Hash ist im Endeffekt ein assoziatives Array bzw. eine HashTable)
2. Über ein ERB-Template das HTML-Grundgerüst definieren und damit die Daten aus dem Hash an der jeweiligen Stelle in die Ausgabe schreiben
3a Die Ausgabe in eine Datei auf dem lokalen Rechner schreibt oder
3b Die Ausgabe direkt auf den Webserver lädt

Wenn Du noch nie etwas mir Ruby/RoR gemacht hast und auch keine Lust hast dich damit zu befassen, ist der Ansatz eher ungeeignet, aber wenn Ruby eh schon installiert ist oder die Neugier groß genug ist... Mit Ruby kann man sehr einfach sehr viel automatisieren (ganz ohne dem Rails-Framwork), was mit anderen Sprachen/Frameworks/Tools auch aber eher umständlich geht.
15.01.2013
phg 1,6k 3
0
So, es hat nun doch eine Weile gedauert, bis ich Floyds Tip mal ausprobieren konnte - aber was lange währt...

Im Kern war die Idee goldrichtig. jquery brauche ich nicht, wohl aber das nodejs-Modul jsdom. Damit kann ich ein Skript basteln, das eine HTML-Seite einmal in den "Browser" lädt, das darin enthaltene Javascript (bei mir also insbesondere die Datenbindung mit knockout) ausführt, und den dadurch enstandenen DOM-Baum, aber ohne die nun nicht mehr benötigten script-Tags, als HTML-Code wieder abspeichert. Ich kann also meine Templates unverändert lassen und einfach den Prozess der "HTML-Aufbereitung" automatisieren.

Und so sieht das Skript aus:

var fs = require('fs');
var jsdom = require("jsdom");

var input = "path/to/input.html";
var output = "path/to/output.html";

ladeSeite(input, function(event) {
var window = event.target;
entferneScriptTags(window.document);
schreibeHtmlCode(output, window.document);
window.close();
});

function ladeSeite(path, onLoaded) {
var htmlSource = fs.readFileSync(path, "utf8");

//ohne die Angabe von "url" werden relative Pfade in der HTML-Seite
//bezogen auf das Skript aufgelöst, nicht auf den Speicherort der HTML-Datei
var dom = jsdom.jsdom(htmlSource, null, {url: path});
var window = dom.createWindow();

//das Laden abwarten, sonst läuft keine knockout nicht
window.addEventListener('load', onLoaded);
}

function entferneScriptTags(document) {
var scriptTags = document.getElementsByTagName('script');
for(var i = 0; i < scriptTags.length; i++) {
if (scriptTags[i].parentNode) {
scriptTags[i].parentNode.removeChild(scriptTags[i]);
}
}
}

function schreibeHtmlCode(path, document) {
// The non-standard window.document.outerHTML also exists,
// but currently does not preserve source code structure as well

// The following two operations are non-standard
var htmlSource = document.doctype.toString()+document.innerHTML;
fs.writeFileSync(path, htmlSource);
}
11.02.2013
Matthias Hlawatsch 13,2k 4 9

Stelle deine Html-Frage jetzt!