Mit Vorlagen können Sie Google Apps Script-Code und HTML kombinieren, um dynamische Seiten mit minimalem Aufwand zu erstellen. Wenn Sie bereits Vorlagensprachen verwendet haben, die Code und HTML kombinieren, z. B. PHP, ASP oder JSP, sollte Ihnen die Syntax bekannt vorkommen.
Scriptlets
Apps Script-Vorlagen können drei spezielle Tags enthalten, die als Scriptlets bezeichnet werden. In einem Scriptlet können Sie jeden Code schreiben, der in einer normalen Apps Script-Datei funktioniert: Scriptlets können Funktionen aufrufen, die in anderen Codedateien definiert sind, auf globale Variablen verweisen oder eine der Apps Script-APIs verwenden. Sie können sogar Funktionen und Variablen in Scriptlets definieren. Diese können jedoch nicht von Funktionen aufgerufen werden, die in Codedateien oder anderen Vorlagen definiert sind.
Wenn Sie das folgende Beispiel in den Skripteditor einfügen, wird der Inhalt des
<?= ... ?> Tags (ein Druck-Scriptlet) kursiv dargestellt. Dieser Code wird auf dem Server ausgeführt, bevor die Seite dem Nutzer bereitgestellt wird. Da Scriptlet-Code ausgeführt wird, bevor die Seite bereitgestellt wird, kann er nur einmal pro Seite ausgeführt werden. Im Gegensatz zu clientseitigem JavaScript oder
Apps Script-Funktionen, die Sie über
google.script.run aufrufen, können Scriptlets nach dem Laden der Seite nicht
noch einmal ausgeführt werden.
Code.gs
function doGet() {
return HtmlService
.createTemplateFromFile('Index')
.evaluate();
}
Index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
Hello, World! The time is <?= new Date() ?>.
</body>
</html>
Beachten Sie, dass sich die Funktion doGet für HTML-Vorlagen von den Beispielen
zum Erstellen und Bereitstellen von einfachem HTML unterscheidet. Die hier gezeigte Funktion
generiert ein
HtmlTemplate-Objekt aus der HTML
-Datei und ruft dann die Methode
evaluate auf, um die Scriptlets auszuführen und die Vorlage in ein
HtmlOutput-Objekt umzuwandeln, das das Skript dem Nutzer bereitstellen kann.
Standard-Scriptlets
Standard-Scriptlets, die die Syntax <? ... ?> verwenden, führen Code aus, ohne
explizit Inhalte auf der Seite auszugeben. Wie dieses Beispiel zeigt, kann das Ergebnis des Codes in einem Scriptlet jedoch weiterhin den HTML-Inhalt außerhalb des Scriptlets beeinflussen:
Code.gs
function doGet() {
return HtmlService
.createTemplateFromFile('Index')
.evaluate();
}
Index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<? if (true) { ?>
<p>This is always served!</p>
<? } else { ?>
<p>This is never served.</p>
<? } ?>
</body>
</html>
Druck-Scriptlets
Druck-Scriptlets, die die Syntax <?= ... ?> verwenden, geben die Ergebnisse von
ihrem Code mithilfe von kontextbezogener Maskierung auf der Seite aus.
Bei der kontextbezogenen Maskierung verfolgt Apps Script den
Kontext der Ausgabe auf der Seite – in einem HTML-Attribut, in einem clientseitigen
script Tag oder an einer anderen Stelle – und fügt automatisch Maskierungszeichen hinzu, um
vor Cross-Site-Scripting-Angriffen (XSS)
zu schützen.
In diesem Beispiel gibt das erste Druck-Scriptlet direkt einen String aus. Es folgt ein Standard-Scriptlet, das ein Array und eine Schleife einrichtet, gefolgt von einem weiteren Druck-Scriptlet, das den Inhalt des Arrays ausgibt.
Code.gs
function doGet() {
return HtmlService
.createTemplateFromFile('Index')
.evaluate();
}
Index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<?= 'My favorite Google products:' ?>
<? var data = ['Gmail', 'Docs', 'Android'];
for (var i = 0; i < data.length; i++) { ?>
<b><?= data[i] ?></b>
<? } ?>
</body>
</html>
Ein Druck-Scriptlet gibt nur den Wert der ersten Anweisung aus. Alle verbleibenden Anweisungen verhalten sich so, als wären sie in einem Standard-Scriptlet enthalten. Das Scriptlet <?= 'Hello, world!'; 'abc' ?> gibt beispielsweise nur
„Hello, world!“ aus.
Erzwungene Druck-Scriptlets
Erzwungene Druck-Scriptlets, die die Syntax <?!= ... ?> verwenden, ähneln Druck-
Scriptlets, vermeiden jedoch die kontextbezogene Maskierung.
Die kontextbezogene Maskierung ist wichtig, wenn Ihr Skript nicht vertrauenswürdige Nutzereingaben zulässt. Im Gegensatz dazu müssen Sie den Druck erzwingen, wenn die Ausgabe Ihres Scriptlets absichtlich HTML oder Skripts enthält, die Sie genau wie angegeben einfügen möchten.
In der Regel sollten Sie Druck-Scriptlets anstelle von erzwungenen Druck-Scriptlets verwenden, es sei denn, Sie wissen, dass Sie HTML oder JavaScript unverändert ausgeben müssen.
Apps Script-Code in Scriptlets
Scriptlets sind nicht auf die Ausführung von normalem JavaScript beschränkt. Sie können auch eine der folgenden drei Techniken verwenden, um Ihren Vorlagen Zugriff auf Apps Script-Daten zu gewähren.
Da der Vorlagencode jedoch ausgeführt wird, bevor die Seite dem Nutzer bereitgestellt wird, können diese Techniken nur anfängliche Inhalte auf einer Seite bereitstellen. Wenn Sie interaktiv auf
Apps Script-Daten von einer Seite aus zugreifen möchten, verwenden Sie stattdessen die
google.script.run-API.
Apps Script-Funktionen aus einer Vorlage aufrufen
Scriptlets können jede Funktion aufrufen, die in einer Apps Script-Codedatei oder -Bibliothek definiert ist. In diesem Beispiel wird gezeigt, wie Sie Daten aus einer Tabelle in eine Vorlage abrufen und dann eine HTML-Tabelle aus den Daten erstellen.
Code.gs
function doGet() {
return HtmlService
.createTemplateFromFile('Index')
.evaluate();
}
function getData() {
return SpreadsheetApp
.openById('1234567890abcdefghijklmnopqrstuvwxyz')
.getActiveSheet()
.getDataRange()
.getValues();
}
Index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<? var data = getData(); ?>
<table>
<? for (var i = 0; i < data.length; i++) { ?>
<tr>
<? for (var j = 0; j < data[i].length; j++) { ?>
<td><?= data[i][j] ?></td>
<? } ?>
</tr>
<? } ?>
</table>
</body>
</html>
Apps Script-APIs direkt aufrufen
Sie können Apps Script-Code auch direkt in Scriptlets verwenden. In diesem Beispiel wird dasselbe Ergebnis wie im vorherigen Beispiel erzielt, indem die Daten in der Vorlage selbst und nicht über eine separate Funktion geladen werden.
Code.gs
function doGet() {
return HtmlService
.createTemplateFromFile('Index')
.evaluate();
}
Index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<? var data = SpreadsheetApp
.openById('1234567890abcdefghijklmnopqrstuvwxyz')
.getActiveSheet()
.getDataRange()
.getValues(); ?>
<table>
<? for (var i = 0; i < data.length; i++) { ?>
<tr>
<? for (var j = 0; j < data[i].length; j++) { ?>
<td><?= data[i][j] ?></td>
<? } ?>
</tr>
<? } ?>
</table>
</body>
</html>
Variablen an Vorlagen übertragen
Schließlich können Sie Variablen in eine Vorlage übertragen, indem Sie sie als Eigenschaften
des HtmlTemplate-Objekts zuweisen. Auch in diesem Beispiel wird dasselbe Ergebnis wie in den vorherigen Beispielen erzielt.
Code.gs
function doGet() {
var t = HtmlService.createTemplateFromFile('Index');
t.data = SpreadsheetApp
.openById('1234567890abcdefghijklmnopqrstuvwxyz')
.getActiveSheet()
.getDataRange()
.getValues();
return t.evaluate();
}
Index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<table>
<? for (var i = 0; i < data.length; i++) { ?>
<tr>
<? for (var j = 0; j < data[i].length; j++) { ?>
<td><?= data[i][j] ?></td>
<? } ?>
</tr>
<? } ?>
</table>
</body>
</html>
Fehler in Vorlagen beheben
Die Fehlerbehebung in Vorlagen kann schwierig sein, da der von Ihnen geschriebene Code nicht direkt ausgeführt wird. Stattdessen wandelt der Server Ihre Vorlage in Code um und führt diesen resultierenden Code aus.
Wenn nicht klar ist, wie die Vorlage Ihre Scriptlets interpretiert, können Ihnen zwei
Methoden zur Fehlerbehebung in der
HtmlTemplate Klasse helfen, die Vorgänge
besser zu verstehen.
Die Funktion „getCode“
Die getCode Funktion
gibt einen String zurück, der den Code enthält, den der Server aus der Vorlage erstellt.
Wenn Sie den
Code protokollieren und dann in den Skripteditor einfügen, können Sie ihn wie normalen
Apps Script-Code ausführen und Fehler beheben
.
Hier ist noch einmal die Vorlage, die eine Liste der Google-Produkte anzeigt, gefolgt vom Ergebnis von getCode:
Code.gs
function myFunction() {
Logger.log(HtmlService
.createTemplateFromFile('Index')
.getCode());
}
Index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<?= 'My favorite Google products:' ?>
<? var data = ['Gmail', 'Docs', 'Android'];
for (var i = 0; i < data.length; i++) { ?>
<b><?= data[i] ?></b>
<? } ?>
</body>
</html>
LOG (AUSGEWERTET)
(function() { var output = HtmlService.initTemplate(); output._ = '<!DOCTYPE html>\n';
output._ = '<html>\n' +
' <head>\n' +
' <base target=\"_top\">\n' +
' </head>\n' +
' <body>\n' +
' '; output._$ = 'My favorite Google products:' ;
output._ = ' '; var data = ['Gmail', 'Docs', 'Android'];
for (var i = 0; i < data.length; i++) { ;
output._ = ' <b>'; output._$ = data[i] ; output._ = '</b>\n';
output._ = ' '; } ;
output._ = ' </body>\n';
output._ = '</html>';
/* End of user code */
return output.$out.append('');
})();
Die Funktion „getCodeWithComments“
Die
getCodeWithComments
Funktion ähnelt getCode(), gibt aber den ausgewerteten Code als Kommentare
zurück, die neben der ursprünglichen Vorlage angezeigt werden.
Ausgewerteten Code durchgehen
Das erste, was Ihnen in beiden Beispielen für ausgewerteten Code auffällt, ist das implizite output-Objekt, das von der Methode HtmlService.initTemplate erstellt wurde. Diese Methode ist nicht dokumentiert, da sie nur von Vorlagen selbst verwendet werden muss. output ist ein
spezielles HtmlOutput-Objekt mit zwei
ungewöhnlich benannten Eigenschaften, _ und _$, die eine Kurzform für den Aufruf von
append und
appendUntrusted sind.
output hat eine weitere spezielle Eigenschaft, $out, die auf ein reguläres HtmlOutput-Objekt verweist, das diese speziellen Eigenschaften nicht besitzt. Die Vorlage gibt dieses normale Objekt am Ende des Codes zurück.
Nachdem Sie diese Syntax verstanden haben, können Sie den Rest des Codes nachvollziehen. HTML
Inhalte außerhalb von Scriptlets (z. B. das Tag b) werden mit output._ =
angehängt (ohne kontextbezogene
Maskierung). Scriptlets werden als JavaScript angehängt (mit oder ohne kontextbezogene Maskierung,
je nach Art des Scriptlets).
Der ausgewertete Code behält die Zeilennummern aus der Vorlage bei. Wenn beim Ausführen von ausgewertetem Code ein Fehler auftritt, entspricht die Zeile dem entsprechenden Inhalt in der Vorlage.
Hierarchie der Kommentare
Da der ausgewertete Code die Zeilennummern beibehält, können Kommentare in Scriptlets andere Scriptlets und sogar HTML-Code auskommentieren. Diese Beispiele zeigen einige überraschende Auswirkungen von Kommentaren:
<? var x; // a comment ?> This sentence won't print because a comment begins
inside a scriptlet on the same line.
<? var y; // ?> <?= "This sentence won't print because a comment begins inside
a scriptlet on the same line.";
output.append("This sentence prints because it's on the next line, even though
it's in the same scriptlet.") ?>
<? doSomething(); /* ?>
This entire block is commented out,
even if you add a */ in the HTML
or in a <script> */ </script> tag,
<? until you end the comment inside a scriptlet. */ ?>