旧バージョンのドキュメントを参照しています。 最新のドキュメントはこちらをご参照ください。
テンプレートの使用
Kong Portalはlua-resty-template
テンプレートライブラリ上に構築されており、https://github.com/bungle/lua-resty-templateで確認できます。ライブラリの基本的な使い方については後述します。何が実現できるかについての詳細な情報は、ソースドキュメントを参照してください。
構文
(lua-resty-templates ドキュメントからの抜粋)
テンプレートでは次のタグを使用できます。
-
{{expression}}
、式の結果を書き込みます(HTMLエスケープ処理された) -
{*expression*}
, 式の結果を記述します -
{% lua code %}
は、Luaコードを実行します -
{(path-to-partial)}
、パスでpartial
ファイルを含める場合、ファイルのコンテキストを指定することもできます{(partials/header.html, { message = "Hello, World" } )}
-
{-block-}...{-block-}
{-block-}
の内容を、(このケースでは)キーblock
を持つblocks
テーブルに格納された値にラップします。ブロックの使用を参照してください。定義済みのブロック名(verbatim
およびraw
)をそのまま使用しないでください。 -
{-verbatim-}...{-verbatim-}
、{-raw-}...{-raw-}
は定義済みのブロックであり、その内部はlua-resty-template
によって処理されず、内容がそのまま出力されます。 -
{# comments #}
{#
から#}
までのすべての要素はコメントアウト(出力も実行も不可)状態とみなされます。
カスタムプロパティの表示
OpenAPI仕様では、カスタムプロパティを使用できます。Dev Portalでカスタムプロパティを公開するには、spec-renderer.html
ファイルのshowExtensions
をtrue
に変更します。デフォルトでは、showExtensions
はfalse
です。
部分的
パーシャルは、レイアウトが参照できる HTML のスニペットです。パーシャルはそのレイアウトがアクセスできるデータと同じすべてのデータにアクセスでき、他のパーシャルを呼び出すこともできます。コードをパーシャルに分割すると、大きなページを整理しやすくなるだけでなく、さまざまなレイアウトで共通のページ要素を共有できます。
content/index.txt
---
layout: index.html
title: Partials
header_logo: assets/images/example.jpeg
header_nav_items:
about:
href: /about
guides:
href: /guides
hero_title: Partials Info
hero_description: Partials are wicked sick!
---
layouts/index.html
{(partials/header.html)}
<div class="content" id="sl-md0000000">
{(partials/hero.html)}
</div>
{(partials/footer.html)}
partials/header.html
<header class="row" id="sl-md0000000">
<div class="column" id="sl-md0000000">
<img src="{{page.header_logo}}" id="sl-md0000000"/>
</div>
<div class="column" id="sl-md0000000">
{(partials/header_nav.html)}
</div>
</header>
partials/header_nav.html
<ul id="sl-md0000000">
{% for title, href in each(page.header_nav_items) do %}
<li id="sl-md0000000"><a href="{{href}}" id="sl-md0000000">{{title}}</a></li>
{% end %}
</ul>
partials/hero.html
<h1 id="sl-md0000000">{{page.hero_title}}</h1>
<p id="sl-md0000000">{{page.hero_description}}</p>
partials/hero.html
<footer id="sl-md0000000">
<p id="sl-md0000000">footer</p>
</footer>
出力:
<header class="row" id="sl-md0000000">
<div class="column" id="sl-md0000000">
<img src="assets/images/example.jpeg" id="sl-md0000000"/>
</div>
<div class="column" id="sl-md0000000">
<ul id="sl-md0000000">
<li id="sl-md0000000"><a href="/about" id="sl-md0000000">about</a></li>
<li id="sl-md0000000"><a href="/guieds" id="sl-md0000000">guides</a></li>
</ul>
</div>
</header>
<h1 id="sl-md0000000">Partials Info</h1>
<p id="sl-md0000000">Partials are wicked sick!</p>
<footer id="sl-md0000000">
<p id="sl-md0000000">footer</p>
</footer>
ブロック
ブロックを使用すると、ビューまたは部分を別のテンプレートに埋め込むことができます。ブロックは、異なるテンプレートで共通のラッパーを共有する場合に特に便利です。
以下の例では、コンテンツ ファイルがwrapper.html
ではなくindex.html
を参照していることに注意してください。
content/index.txt
---
layout: index.html
title: Blocks
description: Blocks are the future!
---
layouts/index.html
{% layout = "layouts/wrapper.html" %} <- syntax declaring where to find the block
{-main-} <- delimiter describing what content renders in block
<div class="content" id="sl-md0000000">
<h1 id="sl-md0000000">{{page.title}}</h1>
<p id="sl-md0000000">{{page.description}}<p id="sl-md0000000">
</div>
{-main-}
layouts/wrapper.html
<!doctype id="sl-md0000000" >
<html id="sl-md0000000">
<head id="sl-md0000000">
<title id="sl-md0000000">Testing lua-resty-template blocks</title>
</head>
<body id="sl-md0000000">
<header id="sl-md0000000">
<p id="sl-md0000000">header</p>
</header>
{*main*} <- syntax indicating where to place the block
<footer id="sl-md0000000">
<p id="sl-md0000000">footer</p>
</footer>
</body>
</html>
出力:
<!doctype id="sl-md0000000" >
<html id="sl-md0000000">
<head id="sl-md0000000">
<title id="sl-md0000000">Testing lua-resty-template blocks</title>
</head>
<body id="sl-md0000000">
<header id="sl-md0000000">
<p id="sl-md0000000">header</p>
</header>
<div class="content" id="sl-md0000000">
<h1 id="sl-md0000000">Blocks</h1>
<p id="sl-md0000000">Blocks are the future!<p id="sl-md0000000">
</div>
<footer id="sl-md0000000">
<p id="sl-md0000000">footer</p>
</footer>
</body>
</html>
コレクション
コレクションは、コンテンツのセットをグループとしてレンダリングできる強力なツールです。コレクションとしてレンダリングされるコンテンツは、構成可能なルートパターンとレイアウトを共有します。コレクションはポータル portal.conf.yaml
ファイルで構成します。
以下の例は、個々の posts
で構成される基本的な blog
コレクションをレンダリングするのに必要なすべての設定/ファイルを示しています。
portal.conf.yaml
name: Kong Portal
theme:
name: base
collections:
posts:
output: true
route: /:stub/:collection/:name
layout: post.html
上記を見ると、collections
オブジェクトが宣言されたことがわかります。このオブジェクトは個別コレクションで構成されています。この例では、posts
という名前のコレクションを構成しています。レンダラーはcontent
フォルダ内の_posts
というルートディレクトリでレンダリングする個々のページを検索します。animals
という名前の別のコレクション構成を作成した場合、レンダラーは_animals
というディレクトリでレンダリングするコンテンツファイルを検索します。
各構成項目は、いくつかのパーツで構成されています。
-
output
- 必須 :false
-
タイプ :
boolean
-
説明 :このオプション属性は、コレクションをレンダリングするかどうかを決定します。
false
に設定すると、コレクションの仮想ルートは作成されません。
-
route
- 必須 : true
-
タイプ :
string
-
デフォルト :
none
-
説明 :
route
属性は必須で、どのパターンからコレクションルートを生成するかをレンダラーに伝えます。コレクションルートには、各コレクションメンバーを一意に識別する有効な動的名前空間が必ず1つ以上含まれている必要があります。- ルート宣言内の
:
で始まる名前空間はすべて動的であると見なされます。 - Kongでは、特定の動的名前空間のみが有効と認識されます。
-
:title
: 名前空間を、headmatterで宣言されたコンテンツtitle
に置き換えます。 -
:name
:名前空間をコンテンツのファイル名に置き換えます。 -
:collection
: 名前空間を現在のコレクションの名前に置き換えます。 -
:stub
:各コンテンツのheadmatterのnamespaceをheadmatter.stub
の値で置き換えます。
-
- ルート宣言内の
-
layout
-
必須 :true
-
タイプ :
string
-
説明 :
layout
属性は、コレクションがレンダリングに使用する HTML レイアウトを決定します。パスルートは、現在のテーマlayouts
ディレクトリ内からアクセスされます。
-
タイプ :
-
必須 :true
content/_posts/post1.md
---
title: Post One
stub: blog
---
This is my first post!
content/_posts/post2.md
---
title: Post Two
stub: blog
---
This is my second post!
themes/base/layouts/post.html
<h1 id="sl-md0000000">{{ page.title }}</h1>
<p id="sl-md0000000">{* page.body *}</p>
出力:
<kong_portal_gui_url id="sl-md0000000">/blog/posts/post1
より:
<h1 id="sl-md0000000">Post One</h1>
<p id="sl-md0000000">This is my first post!</p>
<kong_portal_gui_url id="sl-md0000000">/blog/posts/post2
より:
<h1 id="sl-md0000000">Post Two</h1>
<p id="sl-md0000000">This is my second post!</p>
Kong テンプレートヘルパー - Lua API
Kong テンプレートヘルパーは、レンダリング時にポータルデータへのアクセスを提供し、Kong への強力な統合を実現するオブジェクトのコレクションです。
グローバル:
-
l
- 最初のバージョンのロケールヘルパーで、現在アクティブなページから値を取得します。 -
each
- リストまたはテーブルを反復処理するためによく使用されるヘルパー。 -
print
- リスト/テーブルを印刷するためによく使用されるヘルパー。 -
markdown
- リスト/テーブルを印刷するためによく使用されるヘルパー。 -
json_decode
- JSON を Lua テーブルにデコードします。 -
json_encode
- LuaテーブルをJSONにエンコードします。
オブジェクト:
-
portal
- ポータルオブジェクトは、現在アクセスされているのワークスペースポータルを指します。 -
page
- ページオブジェクトは、現在アクティブなページとそのコンテンツを参照します。 -
user
- ユーザーオブジェクトはKongポータルに現在ログインしてアクセスしている開発者を表します。 -
theme
- テーマオブジェクトは、現在アクティブなテーマとその変数を表します。 -
tbl
= テーブルヘルパーメソッド。例:map
、filter
、find
、sort
. -
str
= 文字列ヘルパーメソッド。例:lower
、upper
、reverse
、endswith
など -
helpers
- ヘルパー関数は、一般的なタスクを簡素化したり、Kong Portal メソッドへの簡単なショートカットを提供したりします。
用語/定義:
-
list
- Luaでの通称である配列([1, 2, 3]
)は、テーブルのようなオブジェクト({1, 2, 3}
)です。Luaリストのインデックスは、0
ではなく1
から始まります。値には配列表記(list[1]
)でアクセスできます。 -
table
- LuaではオブジェクトまたはHashMap({1: 2}
)ともよく呼ばれ、({1 = 2}
)のように記述されます。値には配列またはドット表記(table.one or table["one"]
)でアクセスできます。
l(key, fallback)
現在アクティブなページから現在の翻訳をキーで返します。
戻り値の型
string
使用法
content/en/example.txt
を使用:
---
layout: example.html
locale:
title: Welcome to {{portal.name}}
slogan: The best developer portal ever created.
---
content/es/example.txt
を使用:
---
layout: example.html
locale:
title: Bienvenido a {{portal.name}}
slogan: El mejor portal para desarrolladores jamás creado.
---
layouts/example.html
を使用:
<h1 id="sl-md0000000">{* l("title", "Welcome to" .. portal.name) *}</h1>
<p id="sl-md0000000">{* l("slogan", "My amazing developer portal!") *}</p>
<p id="sl-md0000000">{* l("powered_by", "Powered by Kong.") *}</p>
出力:
en/example
の場合:
<h1 id="sl-md0000000">Welcome to Kong Portal</h1>
<p id="sl-md0000000">The best developer portal ever created.</p>
<p id="sl-md0000000">Powered by Kong.</p>
es/example
の場合:
<h1 id="sl-md0000000">Bienvenido a Kong Portal</h1>
<p id="sl-md0000000">El mejor portal para desarrolladores jamás creado.</p>
<p id="sl-md0000000">Powered by Kong.</p>
注記
-
l(...)
は、page
オブジェクトからのヘルパーです。page.l
経由でもアクセス可能です。ただし、page.l
テンプレート補間をサポートしていません (たとえば、 ``は機能しません)。
each(list_or_table)
渡される引数のタイプに応じて適切な反復子を返します。
戻り値の型
Iterator
使用法
テンプレート(リスト):
{% for index, value in each(table) do %}
<ul id="sl-md0000000">
<li id="sl-md0000000">Index: {{index}}</li>
<li id="sl-md0000000">Value: {{ print(value) }}</li>
</ul>
{% end %}
テンプレート(テーブル):
{% for key, value in each(table) do %}
<ul id="sl-md0000000">
<li id="sl-md0000000">Key: {{key}}</li>
<li id="sl-md0000000">Value: {{ print(value) }}</li>
</ul>
{% end %}
print(any)
入力値の出力を文字列として返します。
戻り値の型
string
使用法
テンプレート(テーブル):
<pre id="sl-md0000000">{{print(page)}}</pre>
markdown(文字列)
引数として渡されたマークダウン文字列からHTMLを返します。文字列引数が有効なマークダウンでない場合、関数は文字列をそのまま返します。正しくレンダリングするには、ヘルパーを未加工の{* *}
区切り文字とともに使用する必要があります。
戻り値の型
string
使用法
テンプレート(引数としての文字列):
<pre id="sl-md0000000">{* markdown("##This is Markdown") *}</pre>
テンプレート(引数としてのコンテンツ値):
<pre id="sl-md0000000">{* markdown(page.description) *}</pre>
json_encode(object)
JSONは引数として渡されたLuaテーブルをエンコードします
戻り値の型
string
使用法
テンプレート:
<pre id="sl-md0000000">{{ json_encode({ dog = cat }) }}</pre>
json_decode(string)
JSON 文字列引数を Lua テーブルにデコードします
戻り値の型
table
使用法
テンプレート:
<pre id="sl-md0000000">{{ print(json_encode('{"dog": "cat"}')) }}</pre>
ポータル
portal
では現在のポータルに関連するデータにアクセスできます。たとえば、ポータルの構成、コンテンツ、仕様、レイアウトなどのデータです。
portal.workspace
portal.url
portal.api_url
portal.auth
portal.specs
portal.specs_by_tag
portal.developer_meta_fields
次のようにして、portal
オブジェクトで現在のワークスペースポータル構成に直接アクセスできます。
portal[config_key] or portal.config_key
たとえば、 portal.auth
はポータルの構成値です。構成値のリストは、 kong.conf
のポータルセクションを読むことで確認できます。
kong.confから
ポータルには portal_
で始まる設定値のみが表示され、portal_
プレフィックスを削除することでアクセスできます。
一部の設定値は変更またはカスタマイズされています。これらのカスタマイズは、ポータルメンバーセクションに記載されています。
portal.workspace
現在のポータルのワークスペースを返します。
戻り値の型
string
使用法
テンプレート:
{{portal.workspace}}
出力:
default
portal.url
現在のポータルのURLをワークスペースと共に返します。
戻り値の型
string
使用法
テンプレート:
{{portal.url}}
出力:
http://127.0.0.1:8003/default
portal.api_url
追加された現在のワークスペースでportal_api_url
の設定値を返します。
戻り値の型
string or nil
使用法
テンプレート:
{{portal.api_url}}
portal_api_url = http://127.0.0.1:8004
の場合の出力結果:
http://127.0.0.1:8004/default
portal.auth
現在のポータルの認証タイプを返します。
戻り値の型
string
使用法
値の印刷
入力:
{{portal.auth}}
portal_auth = basic-auth
の場合の出力結果:
basic-auth
認証が有効になっているかどうかを確認
入力:
{% if portal.auth then %}
Authentication is enabled!
{% end %}
portal_auth = basic-auth
の場合の出力結果:
Authentication is enabled!
portal.specs
現在のポータル内に含まれる仕様ファイルの配列を返します。
戻り値の型
array
使用法
コンテンツ値の表示
テンプレート:
<pre id="sl-md0000000">{{ print(portal.specs) }}</pre>
出力:
{
{
"path" = "content/example1_spec.json",
"content" = "..."
},
{
"path" = "content/documentation/example1_spec.json",
"content" = "..."
},
...
}
値のループ
テンプレート:
{% for _, spec in each(portal.specs) %}
<li id="sl-md0000000">{{spec.path}}</li>
{% end %}
出力:
<li id="sl-md0000000">content/example1_spec.json</li>
<li id="sl-md0000000">content/documentation/example1_spec.json</li>
パスでフィルタリング
テンプレート:
{% for _, spec in each(helpers.filter_by_path(portal.specs, "content/documentation")) %}
<li id="sl-md0000000">{{spec.path}}</li>
{% end %}
出力:
<li id="sl-md0000000">content/documentation/example1_spec.json</li>
portal.developer_meta_fields
開発者を登録するためにKongで利用可能/必要な開発者メタフィールドの配列を返します。
戻り値の型
array
使用法
値の印刷
テンプレート:
{{ print(portal.developer_meta_fields) }}
出力:
{
{
label = "Full Name",
name = "full_name",
type = "text",
required = true,
},
...
}
値のループ
テンプレート:
{% for i, field in each(portal.developer_meta_fields) do %}
<ul id="sl-md0000000">
<li id="sl-md0000000">Label: {{field.label}}</li>
<li id="sl-md0000000">Name: {{field.name}}</li>
<li id="sl-md0000000">Type: {{field.type}}</li>
<li id="sl-md0000000">Required: {{field.required}}</li>
</ul>
{% end %}
出力:
<ul id="sl-md0000000">
<li id="sl-md0000000">Label: Full Name</li>
<li id="sl-md0000000">Name: full_name</li>
<li id="sl-md0000000">Type: text</li>
<li id="sl-md0000000">Required: true</li>
</ul>
...
ページ
page
は、ページのURL、パス、ブレッドクラムなどを含む、現在のページに関連するデータにアクセスを提供します。
新しいコンテンツ ページを作成するときに、キーと値を定義できます。ここでは、それらの値にアクセスする方法とその他の興味深い点について学習します。
page
オブジェクトに直接定義してキー値にアクセスするには、次のように指定します。
page[key_name] or page.key_name
このように、ネストしたキーにアクセスすることもできます。
page.key_name.nested_key
ここで注意が必要です。出力エラーを回避するには、次に示すように、nested_key
にアクセスする前に key_name
が存在することを確認してください。
{{page.key_name and page.key_name.nested_key}}
page.route
現在のページのルート/パスを返します。
戻り値の型
string
使用法
テンプレート:
{{page.route}}
出力(指定URLはhttp://127.0.0.1:8003/default/guides/getting-started
)。
guides/getting-started
page.url
現在のページの URL を返します。
戻り値の型
string
使用法
テンプレート:
{{page.url}}
出力(指定URLはhttp://127.0.0.1:8003/default/guides/getting-started
)。
http://127.0.0.1:8003/default/guides/getting-started
page.breadcrumbs
現在のページの階層リンクコレクションを返します。
戻り値の型
table[]
アイテムのプロパティ
-
item.path
- アイテムへの完全パス、フォワードスラッシュの接頭辞なし。 -
item.display_name
- フォーマットされた名前。 -
item.is_first
- これはリストの最初のアイテムですか? -
item.is_last
- これはリストの最後のアイテムですか?
使用法
テンプレート:
<div id="sl-md0000000 breadcrumbs">
<a href="" id="sl-md0000000">Home</a>
{% for i, crumb in each(page.breadcrumbs) do %}
{% if crumb.is_last then %}
/ {{ crumb.display_name }}
{% else %}
/ <a href="{{crumb.path}}" id="sl-md0000000">{{ crumb.display_name }}</a>
{% end %}
{% end %}
</div>
page.body
現在のページの本文を文字列として返します。ルートのコンテンツファイルに .md
または .markdown
の拡張子が付いている場合、本文はマークダウンからHTMLに解析されます。
戻り値の型
string
.txt、.json、.yaml、.ymlテンプレートの使用法
index.txt
:
This is text content.
テンプレート:
<h1 id="sl-md0000000">This is a title</h1>
<p id="sl-md0000000">{{ page.body) }}</p>
出力:
> # This is a title
> This is text content.
使用法:.md、.markdown テンプレート
テンプレート(markdown):
テンプレート内のマークダウンをレンダリングするには、未加工の区切り記号 {* *}
を使用してください。
index.txt
# This is a title
This is text content.
テンプレート:
{* page.body *}
出力:
> # This is a title
> This is text content.
ユーザー
user
は、現在認証されているユーザーに関連するデータへのアクセスを許可します。ユーザーオブジェクトは、KONG_PORTAL_AUTH
が有効な場合にのみ適用されます。
user.is_authenticated
現在のユーザーの認証ステータスを boolean
値で返します。
戻り値の型
boolean
使用法
テンプレート:
{{print(user.is_authenticated)}}
出力:
true
user.has_role
ユーザーに引数として指定されたロールがある場合はtrue
を返します。
戻り値の型
boolean
使用法
テンプレート:
{{print(user.has_role("blue"))}}
出力:
true
user.get
開発者属性を引数に受け取り、存在すれば値を返します。
戻り値の型
any
使用法
テンプレート:
{{user.get("email")}}
{{print(user.get("meta"))}}
出力:
example123@konghq.com
{ "full_name" = "example" }
テーマ
theme
オブジェクトは、theme.conf.yaml
ファイルに設定された値を公開します。さらに、portal.conf.yaml
に含まれる変数のオーバーライドも含まれます。
theme.colors
色変数のテーブルとその値をキーと値のペアで返します。
戻り値の型
table
使用法
theme.conf.yaml
:
name: Kong
colors:
primary:
value: '#FFFFFF'
description: 'Primary Color'
secondary:
value: '#000000'
description: 'Secondary Color'
tertiary:
value: '#1DBAC2'
description: 'Tertiary Color'
テンプレート:
{% for k,v in each(theme.colors) do %}
<p id="sl-md0000000">{{k}}: {{v}}</p>
{% end %}
出力:
<p id="sl-md0000000">primary: #FFFFFF</p>
<p id="sl-md0000000">secondary: #000000</p>
<p id="sl-md0000000">tertiary: #1DBAC2</p>
theme.colors
説明
string引数でcolor varを取り、値を返します。
戻り値の型
string
使用法
theme.conf.yaml
:
name: Kong
colors:
primary:
value: '#FFFFFF'
description: 'Primary Color'
secondary:
value: '#000000'
description: 'Secondary Color'
tertiary:
value: '#1DBAC2'
description: 'Tertiary Color'
テンプレート:
<p id="sl-md0000000">primary: {{theme.color("primary")}}</p>
<p id="sl-md0000000">secondary: {{theme.color("secondary")}}</p>
<p id="sl-md0000000">tertiary: {{theme.color("tertiary")}}</p>
出力:
<p id="sl-md0000000">primary: #FFFFFF</p>
<p id="sl-md0000000">secondary: #000000</p>
<p id="sl-md0000000">tertiary: #1DBAC2</p>
theme.fonts
フォント変数のテーブルとその値をキーと値のペアで返します。
戻り値の型
table
使用法
theme.conf.yaml
:
name: Kong
fonts:
base: Roboto
code: Roboto Mono
headings: Lato
テンプレート:
{% for k,v in each(theme.fonts) do %}
<p id="sl-md0000000">{{k}}: {{v}}</p>
{% end %}
出力:
<p id="sl-md0000000">base: Roboto</p>
<p id="sl-md0000000">code: Roboto Mono</p>
<p id="sl-md0000000">headings: Lato</p>
theme.font
文字列引数でフォント名を取り、値を返します。
戻り値の型
string
使用法
theme.conf.yaml
:
name: Kong
fonts:
base: Roboto
code: Roboto Mono
headings: Lato
テンプレート:
<p id="sl-md0000000">base: {{theme.font("base")}}</p>
<p id="sl-md0000000">code: {{theme.font("code")}}</p>
<p id="sl-md0000000">headings: {{theme.font("headings")}}</p>
出力:
<p id="sl-md0000000">base: #FFFFFF</p>
<p id="sl-md0000000">code: #000000</p>
<p id="sl-md0000000">headings: #1DBAC2</p>
str
便利な文字列ヘルパーメソッドを含むテーブル。
使用法
.upper()
例:
<pre id="sl-md0000000">{{ str.upper("dog") }}</pre>
メソッド
str.byte
str.char
str.dump
str.find
str.format
str. gfind
str.gmatch
str.gsub
str.len
str.lower
str.match
str.rep
str.reverse
str.sub
str.upper
str. isalpha
str.isdigit
str.isalnum
str.isspace
str.islower
str.isupper
str.startswith
str.endswith
str.join
str.splitlines
str.split
str.expandtabs
str.lfind
str.rfind
str.replace
str.count
str. ljust
str.rjust
str.center
str.lstrip
str. rstrip
str.strip
str.splitv
str.partition
str.rpartition
str.at
str.lines
str.title
str.shorten
str.quote_string
tbl
便利なテーブルヘルパーメソッドを含むテーブル
使用法
.map()
例:
{% tbl.map({"dog", "cat"}, function(item) %}
{% if item ~= "dog" then %}
{% return true %}
{% end %}
{% end) %}