Vous pouvez combiner du code Apps Script et du code HTML pour créer des pages dynamiques avec un minimum d'efforts. Si vous avez utilisé un langage de création de modèles qui combine du code et du HTML, tel que PHP, ASP ou JSP, la syntaxe doit vous sembler familière.
Scriptlets
Les modèles Apps Script peuvent contenir trois balises spéciales, appelées scriptlets. À l'intérieur un scriptlet, vous pouvez écrire n'importe quel code compatible avec un script Apps Script normal : les scriptlets peuvent appeler des fonctions définies dans d'autres fichiers de code, référencer des variables globales ou utiliser l'une des API Apps Script. Vous pouvez même définir des fonctions et des variables dans des scriptlets, la mise en garde étant qu'elles ne peuvent pas appelées par des fonctions définies dans des fichiers de code ou d'autres modèles.
Si vous collez l'exemple ci-dessous dans l'éditeur de scripts, le contenu du fichier
Le tag <?= ... ?>
(un scriptlet d'impression) apparaîtra dans
en italique. Ce code en italique est exécuté sur le serveur avant que la page ne soit diffusée.
pour l'utilisateur. Comme le code de scriptlet s'exécute avant que la page ne soit diffusée,
ne peuvent s'exécuter qu'une seule fois par page. contrairement au code JavaScript côté client ou à Apps Script
des fonctions que vous appelez
google.script.run
, les scriptlets ne peuvent pas
à nouveau après le chargement de la page.
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>
Notez que la fonction doGet()
pour le code HTML modélisé diffère des exemples
pour créer et diffuser du code HTML simplifié. La fonction
génère une
l'objet HtmlTemplate
du code HTML
fichier, puis appelle sa fonction
evaluate()
pour
exécuter les scriptlets et convertir le modèle en
HtmlOutput
que le script
peuvent être diffusées auprès de l'utilisateur.
Scriptlets standards
Les scriptlets standards, qui utilisent la syntaxe <? ... ?>
, exécutent du code sans
renvoyant explicitement du contenu sur la page. Toutefois, comme le montre cet exemple,
result du code à l'intérieur d'un scriptlet peut quand même avoir une incidence sur le contenu HTML.
en dehors du scriptlet:
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>
Imprimer des scriptlets
Les scriptslets d'impression, qui utilisent la syntaxe <?= ... ?>
, génèrent les résultats de
leur code dans la page à l'aide de l'échappement contextuel.
Avec l'échappement contextuel, Apps Script garde une trace du contexte de la sortie
sur la page, dans un attribut HTML, dans une balise script
côté client ou
et ajoute automatiquement des caractères d'échappement
pour vous protéger contre les attaques par script intersites (XSS).
Dans cet exemple, le premier scriptlet d'impression génère directement une chaîne : c'est suivie d'un scriptlet standard qui configure un tableau et une boucle, puis un autre scriptlet d'impression pour générer le contenu du tableau.
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>
Notez qu'un scriptlet d'impression n'affiche que la valeur de sa première instruction.
toutes les instructions restantes se comportent comme si elles étaient contenues dans un
scriptlet. Ainsi, par exemple, le scriptlet <?= 'Hello, world!'; 'abc' ?>
uniquement
affiche "Hello, world!"
Forcer l'impression de scriptlets
L'impression forcée de scriptlets, qui utilisent la syntaxe <?!= ... ?>
, est semblable à l'impression.
scriptlets, sauf qu'ils évitent l'échappement contextuel.
L'échappement contextuel est important si votre script autorise des entrées utilisateur non fiables. Par le contraste, vous devrez forcer l'impression si la sortie de votre scriptlet s'affiche de manière intentionnelle contient du code HTML ou des scripts à insérer exactement comme spécifié.
En règle générale, utilisez des scriptlets d'impression plutôt que de forcer l'impression de scriptlets. à moins que vous ne sachiez que vous devez imprimer HTML ou JavaScript tel quel.
Code Apps Script dans des scriptslets
Les scriptlets ne sont pas limités à l'exécution de JavaScript normal. vous pouvez également utiliser des trois techniques suivantes pour permettre à vos modèles d'accéder à Apps Script données.
Gardez toutefois à l'esprit que le code du modèle s'exécute avant que la page ne soit diffusée.
pour l'utilisateur, ces techniques permettent uniquement d'alimenter une page avec du contenu initial. Pour y accéder
les données Apps Script d'une page de manière interactive, utilisez la
google.script.run
à la place.
Appeler des fonctions Apps Script à partir d'un modèle
Les scriptlets peuvent appeler n'importe quelle fonction définie dans un fichier de code ou une bibliothèque Apps Script. Cet exemple montre une façon d'extraire les données d'une feuille de calcul dans un modèle, puis créer un tableau HTML à partir des données.
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>
Appeler directement les API Apps Script
Vous pouvez également utiliser le code Apps Script directement dans des scriptlets. Cet exemple produit le même résultat que dans l'exemple précédent en chargeant les données dans le un modèle lui-même plutôt que via une fonction distincte.
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>
Transférer des variables vers des modèles
Enfin, vous pouvez transférer des variables dans un modèle en les attribuant en tant que propriétés
de l'objet HtmlTemplate
. Une fois
Là encore, cet exemple donne le même résultat que les exemples précédents.
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>
Modèles de débogage
Les modèles peuvent être difficiles à déboguer, car le code que vous écrivez n'est pas exécuté directly; le serveur transforme votre modèle en code, puis exécute au code qui en résulte.
S'il n'est pas évident de savoir comment le modèle interprète vos scriptlets, deux
de débogage dans
La classe HtmlTemplate
peut vous aider
de mieux comprendre
ce qui se passe.
getCode()
getCode()
renvoie une
chaîne contenant le code que le serveur crée à partir du modèle. Si vous
enregistrer les
puis collez-le dans l'éditeur de script. Vous pouvez l'exécuter
déboguez-la comme d'habitude
Code Apps Script.
Voici le modèle simple qui affiche à nouveau
une liste de produits Google,
suivi du résultat de 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 (ÉVALUÉ)
(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()
est semblable à getCode()
, mais renvoie le code évalué sous forme de commentaires qui
apparaîtront à côté du modèle original.
Parcourir le code évalué
La première chose que vous remarquerez dans l'un ou
l'autre des exemples de code évalué est l'analyse
Objet output
créé par la méthode HtmlService.initTemplate()
. Cette méthode
n'est pas documentée, car seuls les modèles eux-mêmes ont besoin de l'utiliser. output
est un
un objet HtmlOutput
spécial avec
des propriétés au nom inhabituel, _
et _$
, qui sont un raccourci pour appeler
append()
et
appendUntrusted()
.
output
comporte une autre propriété spéciale, $out
, qui fait référence à une propriété
HtmlOutput
qui ne possède pas ces propriétés spéciales. Le modèle
renvoie cet objet normal à la fin du code.
Maintenant que vous comprenez cette syntaxe, le reste du code devrait être assez facile
à suivre. Le contenu HTML en dehors des scriptlets (comme la balise b
) est ajouté.
en utilisant output._ =
(sans échappement contextuel) ;
et les scriptlets sont ajoutés en tant que JavaScript (avec ou sans échappement contextuel,
selon le type de scriptlet).
Notez que le code évalué conserve les numéros de ligne du modèle. Si vous recevez un message d'erreur lors de l'exécution du code évalué, la ligne correspond à la un contenu équivalent dans le modèle.
Hiérarchie des commentaires
Comme le code évalué conserve les numéros de ligne, il est possible que les commentaires à l'intérieur de scriptlets pour commenter d'autres scriptlets et même du code HTML. Ces exemples montrent quelques effets surprenants des commentaires:
<? 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. */ ?>