HTML-Dienst: Vorlagen-HTML

Sie können Apps Script-Code und HTML kombinieren, um dynamische Seiten mit minimalem zu konzentrieren. Wenn Sie eine Vorlagensprache verwendet haben, die Code und HTML kombiniert, z. B. PHP, ASP oder JSPs, sollte Ihnen die Syntax vertraut vorkommen.

Skriptlets

Apps Script-Vorlagen können drei spezielle Tags enthalten, sogenannte Scriptlets. Innenansicht Scriptlet verwenden, können Sie beliebigen Code schreiben, der in einem normalen file: Scriptlets können Funktionen aufrufen, die in anderen Codedateien definiert sind, globale Variablen zu ändern oder eine der Apps Script APIs zu verwenden. Sie können sogar Funktionen und Variablen in Skriptlets mit dem Vorbehalt, dass diese nicht von Funktionen aufgerufen werden, die in Codedateien oder anderen Vorlagen definiert sind.

Wenn Sie das Beispiel unten in den Script-Editor einfügen, wird der Inhalt des <?= ... ?>-Tag (ein Druck-Scriptlet) erscheint in Kursivschrift. Der kursiv geschriebene Code wird auf dem Server ausgeführt, bevor die Seite geschaltet wird. für den Nutzer. Da Scriptlet-Code vor dem Bereitstellen der Seite ausgeführt wird, kann nur einmal pro Seite ausgeführt werden. im Gegensatz zu clientseitigem JavaScript oder Apps Script Funktionen, die Sie über google.script.run, Scriptlets können 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>

Die doGet()-Funktion für HTML-Vorlagen weicht von den Beispielen ab. zum Erstellen und Bereitstellen von einfachem HTML. Die Funktion das hier gezeigt wird, HtmlTemplate-Objekt aus dem HTML-Code und ruft dann ihre evaluate()-Methode, um die Skriptlets aus und konvertieren die Vorlage in ein HtmlOutput-Objekt, das vom Skript die für den Nutzer ausgeliefert werden können.

Standard-Scriptlets

Standard-Scriptlets mit der Syntax <? ... ?> führen Code ohne explizit Inhalte an die Seite ausgeben. Wie dieses Beispiel zeigt, result des Codes in einem Scriptlet kann sich dennoch auf den HTML-Inhalt auswirken. aus dem Skriptlet heraus:

Code.gs

function doGet() {
  return HtmlService
      .createTemplateFromFile('Index')
      .evaluate();
}

Index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <? if (true) { ?>
      <p>This will always be served!</p>
    <? } else  { ?>
      <p>This will never be served.</p>
    <? } ?>
  </body>
</html>

Scriptlets drucken

Das Drucken von Scriptlets mit der Syntax <?= ... ?>, gibt die Ergebnisse von mithilfe von Kontext-Escaping ihren Code auf der Seite einfügen.

Beim Kontext-Escaping verfolgt Apps Script den Kontext der Ausgabe. auf der Seite – innerhalb eines HTML-Attributs, in einem clientseitigen script-Tag oder an anderen Stellen ein und fügt automatisch Escape-Zeichen hinzu um vor Cross-Site-Scripting-Angriffen (XSS) zu schützen.

In diesem Beispiel gibt das erste Druck-Scriptlet direkt einen String aus. es ist gefolgt von einem Standard-Scriptlet, das ein Array und eine Schleife einrichtet, ein weiteres Druck-Scriptlet zur Ausgabe des Array-Inhalts.

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>

Beachten Sie, dass ein Druck-Scriptlet nur den Wert seiner ersten Anweisung ausgibt. verhalten sich die verbleibenden Anweisungen so, als wären sie in einem Standard- Scriptlet enthalten ist. So hat z. B. nur das Skriptlet <?= 'Hello, world!'; 'abc' ?> gibt „Hello, world!“ aus.

Drucken von Scriptlets erzwingen

Scriptlets mit der Syntax <?!= ... ?>, für die das erzwungene Drucken verwendet wird, entsprechen dem Drucken mit der Ausnahme, dass sie Kontext-Escaping vermeiden.

Kontextbezogene Maskierung ist wichtig, wenn Ihr Skript Eingaben durch nicht vertrauenswürdige Nutzer zulässt. Von muss das Drucken erzwungen werden, wenn Ihr Scriptlet bewusst enthält HTML-Code oder Skripte, die genau wie angegeben eingefügt werden sollen.

Im Allgemeinen sollten Sie Druck-Scriptlets anstelle von erzwungenem Drucken verwenden. es sei denn, Sie wissen, dass Sie HTML oder JavaScript unverändert drucken müssen.

Apps Script-Code in Scriptlets

Scriptlets sind nicht auf die Ausführung von normalem JavaScript beschränkt. können Sie auch beliebige der folgenden drei Techniken, um Ihren Vorlagen Zugriff auf Apps Script zu gewähren. Daten.

Da der Vorlagencode vor dem Schalten der Seite ausgeführt wird, können diese Techniken nur die ursprünglichen Inhalte auf einer Seite einspeisen. Zugriff Apps Script-Daten einer Seite interaktiv nutzen, verwenden Sie google.script.run API.

Apps Script-Funktionen über eine Vorlage aufrufen

Scriptlets können jede Funktion aufrufen, die in einer Apps Script-Codedatei oder -bibliothek definiert ist. Dieses Beispiel zeigt eine Möglichkeit, Daten aus einer Tabellenkalkulation in eine Vorlage zu übertragen, eine HTML-Tabelle aus den Daten zu 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. Dieses Beispiel führt das gleiche Ergebnis wie im vorherigen Beispiel aus, indem die Daten im Vorlage selbst und nicht über eine separate Funktion.

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 senden

Schließlich können Sie Variablen in eine Vorlage übernehmen, indem Sie sie als Eigenschaften zuweisen. des HtmlTemplate-Objekts. Einmal Dieses Beispiel führt wieder zum gleichen Ergebnis wie die vorherigen Beispiele.

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>

Debugging-Vorlagen

Die Fehlerbehebung von Vorlagen kann eine Herausforderung sein, da der von Ihnen geschriebene Code nicht ausgeführt wird directly; wandelt der Server die Vorlage in Code um und führt aus diesem Code.

Wenn nicht offensichtlich ist, wie die Vorlage Ihre Scriptlets interpretiert, Debugging-Methoden in der Kurs HtmlTemplate kann Ihnen helfen worum es geht.

getCode()

getCode() gibt eine String mit dem Code, den der Server aus der Vorlage erstellt. Wenn Sie protokollieren fügen Sie ihn in den Skripteditor ein, Debuggen wie gewohnt Apps Script-Code

Hier ist die einfache Vorlage, die wieder eine Liste mit Google-Produkten zeigt. 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>

PROTOKOLL (BEWERTET)

(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('');
})();

getCodeWithComments()

getCodeWithComments() ähnelt getCode(), gibt den ausgewerteten Code jedoch als Kommentare zurück, die Seite an Seite mit der Originalvorlage angezeigt.

Schritt-für-Schritt-Anleitung zum bewerteten Code

In beiden Beispielen des bewerteten Codes werden Sie zunächst feststellen, output-Objekt, das mit der Methode HtmlService.initTemplate() erstellt wurde. Diese Methode ist undokumentiert, da er nur von den Vorlagen selbst benötigt wird. output ist ein spezielles HtmlOutput-Objekt mit zwei ungewöhnlich benannten Eigenschaften, _ und _$, die für Aufrufe von append() und appendUntrusted()

output hat eine weitere spezielle Eigenschaft, $out, die sich auf eine reguläre HtmlOutput-Objekt, das nicht über diese speziellen Eigenschaften verfügt. Vorlage gibt dieses normale Objekt am Ende des Codes zurück.

Jetzt, da Sie diese Syntax verstehen, sollte der Rest des Codes ziemlich einfach sein. die Sie befolgen sollten. HTML-Inhalte außerhalb von Scriptlets (z. B. das b-Tag) werden angehängt. mit output._ = (ohne kontextbedingte Maskierung) und scriptlets als JavaScript angehängt werden (mit oder ohne kontextbezogenes Escape-Zeichen, je nach Scriptlet-Art).

Beachten Sie, dass der ausgewertete Code die Zeilennummern aus der Vorlage beibehält. Wenn Sie beim Ausführen des bewerteten Codes ein Fehler auftritt, entspricht die Zeile dem Inhalt in der Vorlage.

Hierarchie der Kommentare

Da im ausgewerteten Code Zeilennummern beibehalten werden, können Kommentare Scriptlets, um andere Scriptlets und sogar HTML-Code auszukommentieren. 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 will print 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. */ ?>