Spec-Zone.ru › Bottle 0.11

SimpleTemplate Engine

Bottle поставляется со встроенным, быстрым, мощным и простым в освоении шаблонизатором под названием SimpleTemplate или stpl вкратце. Это движок по умолчанию, используемый помощниками view() и template(), но также может быть использован как самостоятельный шаблонизатор общего назначения. Этот документ объясняет синтаксис шаблонов и показывает примеры для распространённых случаев использования.

Базовое использование API:

SimpleTemplate реализует API BaseTemplate:

>>> from bottle import SimpleTemplate
>>> tpl = SimpleTemplate('Hello {{name}}!')
>>> tpl.render(name='World')
u'Hello World!'

В этом документе мы используем помощника template() в примерах для простоты:

>>> from bottle import template
>>> template('Hello {{name}}!', name='World')
u'Hello World!'

Просто имейте в виду, что компиляция и рендеринг шаблонов — это две разные операции, даже если помощник template() скрывает этот факт. Шаблоны обычно компилируются только один раз и кешируются внутри, но рендерятся многократно с различными аргументами ключевых слов.

Синтаксис SimpleTemplate

Python — очень мощный язык, но его чувствительный к отступам синтаксис затрудняет его использование в качестве языка шаблонов. SimpleTemplate устраняет некоторые из этих ограничений и позволяет вам писать чистые, удобочитаемые и поддерживаемые шаблоны, сохраняя при этом полный доступ к функциям, библиотекам и скорости языка Python.

Предупреждение

Синтаксис SimpleTemplate компилируется непосредственно в байткод Python и выполняется при каждом вызове SimpleTemplate.render(). Не рендерите недоверенные шаблоны! Они могут содержать и выполнять вредный код Python.

Встроенные операторы

Вы уже узнали об использовании оператора {{...}} из примера “Hello World!” выше, но есть и больше: любой оператор Python разрешён в фигурных скобках, если он возвращает строку или что-то, что имеет строковое представление:

>>> template('Hello {{name}}!', name='World')
u'Hello World!'
>>> template('Hello {{name.title() if name else "stranger"}}!', name=None)
u'Hello stranger!'
>>> template('Hello {{name.title() if name else "stranger"}}!', name='mArC')
u'Hello Marc!'

Встроенный оператор Python выполняется во время рендеринга и имеет доступ ко всем аргументам ключевых слов, переданным методу SimpleTemplate.render(). HTML-специальные символы автоматически экранируются для предотвращения атак XSS. Вы можете начать оператор с восклицательного знака, чтобы отключить экранирование для этого оператора:

>>> template('Hello {{name}}!', name='<b>World</b>')
u'Hello &lt;b&gt;World&lt;/b&gt;!'
>>> template('Hello {{!name}}!', name='<b>World</b>')
u'Hello <b>World</b>!'

Встроенный код Python

Символ % отмечает строку кода Python. Единственное отличие от реального кода Python заключается в том, что вам необходимо явно закрывать блоки оператором %end. Взамен вы можете выровнять код с окружающим шаблоном и не беспокоиться о правильном отступе блоков. Парсер SimpleTemplate обрабатывает это за вас. Строки, не начинающиеся с %, рендерятся как текст, как обычно:

%if name:
  Hi <b>{{name}}</b>
%else:
  <i>Hello stranger</i>
%end

Символ % распознается только в том случае, если это первый символ, не являющийся пробелом, в строке. Чтобы экранировать ведущий %, вы можете добавить второй. %% заменяется одним % в результирующем шаблоне:

This line contains a % but no python code.
%% This text-line starts with '%'
%%% This text-line starts with '%%'

Устранение символов перевода строки

Вы можете устранить символ перевода строки перед строкой кода, добавив двойной обратный слэш в конце строки:

<span>\\
%if True:
nobreak\\
%end
</span>

Этот шаблон генерирует следующий вывод:

<span>nobreak</span>

Оператор %include

Вы можете включать другие шаблоны, используя оператор %include sub_template [kwargs]. Параметр sub_template указывает имя или путь к включаемому шаблону. Остальная часть строки интерпретируется как список пар key=statement параметров, аналогичных аргументам ключевых слов в вызовах функций. Они передаются в подшаблон аналогично вызову SimpleTemplate.render(). Допускается и синтаксис **kwargs для передачи словаря:

%include header_template title='Hello World'
<p>Hello World</p>
%include footer_template

Оператор %rebase

Оператор %rebase base_template [kwargs] вызывает рендеринг base_template вместо исходного шаблона. Базовый шаблон затем включает исходный шаблон с пустым оператором %include и имеет доступ ко всем переменным, указанным в kwargs. Таким образом, возможно обернуть шаблон другим шаблоном или смоделировать функцию наследования, присутствующую в некоторых других шаблонизаторах.

Предположим, у вас есть шаблон содержимого и вы хотите обернуть его в общую рамочную HTML-структуру. Вместо того, чтобы включать несколько шаблонов заголовка и подвала, вы можете использовать один базовый шаблон для рендеринга фрейма макета.

Базовый шаблон с именем layout.tpl:

<html>
<head>
  <title>{{title or 'No title'}}</title>
</head>
<body>
  %include
</body>
</html>

Основной шаблон с именем content.tpl:

This is the page content: {{content}}
%rebase layout title='Content Title'

Теперь вы можете отобразить content.tpl:

>>> print template('content', content='Hello World!')
<html>
<head>
  <title>Content Title</title>
</head>
<body>
  This is the page content: Hello World!
</body>
</html>

Более сложный сценарий включает цепочку переопределений и несколько блоков содержимого. Шаблон block_content.tpl определяет две функции и передаёт их базовому шаблону columns.tpl:

%def leftblock():
  Left block content.
%end
%def rightblock():
  Right block content.
%end
%rebase columns leftblock=leftblock, rightblock=rightblock, title=title

Базовый шаблон columns.tpl использует две вызываемые функции для рендеринга содержимого левой и правой колонки. Затем он оборачивает себя шаблоном layout.tpl , определённым ранее:

%rebase layout title=title
<div style="width: 50%; float:left">
  %leftblock()
</div>
<div style="width: 50%; float:right">
  %rightblock()
</div>

Посмотрим, как block_content.tpl рендерит:

>>> print template('block_content', title='Hello World!')
<html>
<head>
  <title>Hello World</title>
</head>
<body>
<div style="width: 50%; float:left">
  Left block content.
</div>
<div style="width: 50%; float:right">
  Right block content.
</div>
</body>
</html>

Функции пространства имён

Обращение к неопределённым переменным в шаблоне вызывает NameError и останавливает рендеринг немедленно. Это стандартное поведение Python и ничего нового, но обычный Python не имеет простого способа проверить доступность переменной. Это быстро становится раздражающим, если вы хотите поддерживать гибкие входные данные или использовать один и тот же шаблон в разных ситуациях. SimpleTemplate помогает здесь: следующие три функции определены в стандартном пространстве имён и доступны из любой точки шаблона:

defined(name)

Возвращает True, если переменная определена в текущем пространстве имён шаблона, в противном случае — False.

get(name, default=None)

Возвращает переменную или значение по умолчанию.

setdefault(name, default)

Если переменная не определена, создаёт её со значением по умолчанию. Возвращает переменную.

Вот пример, который использует все три функции для реализации необязательных переменных шаблона различными способами:

% setdefault('text', 'No Text')
<h1>{{get('title', 'No Title')}}</h1>
<p> {{ text }} </p>
% if defined('author'):
  <p>By {{ author }}</p>
% end

API SimpleTemplate

class SimpleTemplate(source=None, name=None, lookup=[], encoding='utf8', **settings) [source]
classmethod split_comment(code) [source]

Удаляет комментарии (#...) из кода Python.

render(*args, **kwargs) [source]

Отрендерить шаблон, используя аргументы ключевых слов как локальные переменные.

Известные ошибки

Некоторые синтаксические конструкции, разрешенные в Python, проблематичны в шаблоне. Следующие синтаксические конструкции не будут работать с SimpleTemplate:

  • Многострочные операторы должны заканчиваться обратной косой чертой (\) и комментарий, если присутствует, не должен содержать дополнительных символов #.
  • Многострочные строки пока не поддерживаются.

© 2009–2017 Marcel Hellkamp
Licensed under the MIT License.
https://bottlepy.org/docs/0.11/stpl.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API