Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Meta Template Engine
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
ayato
October 02, 2017
Programming
1.2k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Meta Template Engine
ayato
October 02, 2017
More Decks by ayato
See All by ayato
マイクロサービス内で動くAPIをF#で書いている
ayato0211
1
1.7k
Clojureという言語が私逹にもたらしたもの
ayato0211
6
3.2k
3年間考え続けてきたWebアプリケーションにおけるテストの話
ayato0211
3
320
Re:REPL-Driven Development
ayato0211
3
1.4k
超変換! Hiccup data structure!!
ayato0211
2
690
About Integrant
ayato0211
0
610
Muscle Assert
ayato0211
0
340
Clojureを用いたWebアプリケーション開発
ayato0211
2
3.3k
翻訳にまつわるエトセトラ
ayato0211
6
1.3k
Other Decks in Programming
See All in Programming
残高管理から台帳サービスへの進化
artoy
1
210
コーディング自動化の次へ。人の介入をゼロにするファクトリーとサポートAIによる実践
timakin
5
4.2k
Performance Optimization With LLMs
xleitix
0
170
AIで開発が速くなった先で、開発チームは何を目指すか
shihochan
1
1.7k
PyConTW 2026 - AI Coding 不只是工具升級, 區域醫院醫療資訊系統協作開發與資訊團隊轉型實踐
cclai999
0
130
AWS CDKのカスタムリソースでContinuum(旧Security Agent)を実装した話 | Implementing Continuum (formerly Security Agent) via AWS CDK Custom Resource
akihisaikeda
2
160
Vue Fes Japan の “作る側”に関わってみて
naokihaba
0
170
Lambda durable functionsでHuman in the Loopを楽に…楽に……
har1101
0
150
Web Framework Benchmark Battle 2026, Any%
a_matsuda
2
2.7k
AI-Powered Domain-Driven Design
ziobrando
0
190
Apple Intelligence を用いた個人情報誤送信防止、及びユーザーリクエスト体験の改善について
yukiny
0
360
自サークルのIdPからログアウトできるようになるまで
taiseiue
1
140
Featured
See All Featured
[RailsConf 2023] Rails as a piece of cake
palkan
59
7.1k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.6k
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2.2k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
35
2.9k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
370
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
BBQ
matthewcrist
90
10k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
2
6.3k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
59k
Being A Developer After 40
akosma
92
590k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2.1k
Everyday Curiosity
cassininazir
0
360
Transcript
メタテンプレートエンジンの話 市ヶ谷Geek★Night#14 市ヶ谷java 〜JVM言語の玉手箱〜
メタテンプレートエンジンの話 市ヶ谷Geek★Night#14 市ヶ谷clojure 〜JVM言語の玉手箱〜
あやぴー •ayato-p@github •Cybozu Startups, Inc. •Clojure書いてる •Webアプリ書いてる
TL;DR
というわけで…
Clojureの話をします
事の発端
HTMLフォーム面倒 <div class="form-group"> <label for="input-email">Email Address</label> <input id="input-email" class="form-control" type="email"
name="email" th:classappend= "${errors.containsKey('email')} ? 'is-invalid'" th:value="${values.email}" placeholder="Enter email" /> <div class="invalid-feedback" th:text="${errors.email}"> </div> <small class="form-text text-muted"> We'll never share your email with anyone else. </small> </div>
HTMLフォーム面倒 [:div.form-group [:label {:for "input-email"} "Email address"] [:input#input-email.form-control {:type :email
:name :email :class (when (contains? errors :email) "is-invalid") :value (:email values) :placeholder "Enter email"}] [:div.invalid-feedback (:email errors)] [:small.form-text.text-muted "We'll never share your email with anyone else."]]
面倒なこと •_methodみたいなやつ •formのmethod属性に直接putとかdelete書きたい •__csrf_tokenみたいなやつ •いちいち書くのは面倒 •エラー表示のために書く条件分岐 •前回表示していた値を表示するための式 •たいていの場合name属性に依存している
HTMLフォーム面倒 [:div.form-group [:label {:for "input-email"} "Email address"] [:input#input-email.form-control {:type :email
:name :email :class (when (contains? errors :email) "is-invalid") :value (:email values) :placeholder "Enter email"}] [:div.invalid-feedback (:email errors)] [:small.form-text.text-muted "We'll never share your email with anyone else."]] ここが決まれば…
HTMLフォーム面倒 [:div.form-group [:label {:for "input-email"} "Email address"] [:input#input-email.form-control {:type :email
:name :email :class (when (contains? errors :email) "is-invalid") :value (:email values) :placeholder "Enter email"}] [:div.invalid-feedback (:email errors)] [:small.form-text.text-muted "We'll never share your email with anyone else."]] ここが決まるはず
考えた
テンプレートエンジンが HTMLに変換する前に 求める形に変換できれば いいんじゃない
つまり… メタテンプレートエンジン…
Kuuga https://github.com/ayato-p/kuuga
“こんなやつらのために、 これ以上誰かの涙は⾒たくない! 皆に笑顔でいて欲しいんです! だから⾒ててください!俺の…変⾝!! ”
“HTML Formのために、 これ以上誰かの涙は⾒たくない! Hiccupユーザーに笑顔でいて欲しいんです! だから⾒ててください!俺の…変換!! ”
変換ルール( (defmethod growing/transform-by-tag :input [_ options tag-vector] (let [[tagkw tagopts
contents] (tool/parse-tag-vector tag-vector)] `[~tagkw (update-input-opts ~options ~tagopts) ~@contents]))
変換ルール) (defmethod growing/transform-by-class :form-group [_ options tag-vector] (let [[tagkw tagopts
contents] (tool/parse-tag-vector tag-vector) contents (reduce (fn [contents' tagvec'] (let [[tk to _] (tool/parse-tag-vector tagvec') [_ t] (tool/parse-tag-keyword tk)] (cond-> (conj contents' tagvec') (= t "input") (conj `(invalid-fb ~options ~to))))) [] contents))] `[~tagkw ~tagopts ~@contents]))
そうすると
これを… (ultimate/transform opts [:div.form-group [:label {:for "input-email"} "Email address"] [:input#input-email.form-control
{:type :email :name :email :placeholder "Enter email"}] [:small.form-text.text-muted "We'll never share your email with anyone else."]])
こんな感じで展開できる [:div.form-group [:label {:for "input-email"} "Email address"] [:input#input-email.form-control {:type :email
:name :email :class (when (contains? errors :email) "is-invalid") :value (:email values) :placeholder "Enter email"}] [:div.invalid-feedback (:email errors)] [:small.form-text.text-muted "We'll never share your email with anyone else."]] ※イメージです
[:div.form-group [:label {:for "input-email"} "Email address"] [:input#input-email.form-control {:type :email :name
:email :class (when (contains? errors :email) "is-invalid") :value (:email values) :placeholder "Enter email"}] [:div.invalid-feedback (:email errors)] [:small.form-text.text-muted "We'll never share your email with anyone else."]] ここが消えた! こんな感じで展開できる
まとめ •Kuugaは超便利 •Clojureはいいぞ •9/25(月) Lisp Meetup •10/4(水) 教養としてのClojure
Enjoy Clojure