bridgetown-slim-support 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +160 -0
- data/bin/bridgetown-slim-support +55 -0
- data/lib/bridgetown/slim_support/converter.rb +70 -0
- data/lib/bridgetown/slim_support/helpers.rb +183 -0
- data/lib/bridgetown/slim_support/plugin.rb +10 -0
- data/lib/bridgetown/slim_support/version.rb +7 -0
- data/lib/bridgetown/slim_support/view.rb +70 -0
- data/lib/bridgetown/slim_support.rb +65 -0
- data/lib/bridgetown-slim-support.rb +3 -0
- metadata +135 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 768c9a031faa70ecd91541fc7c44d6e37312a9631cedf6056bea103c88023572
|
|
4
|
+
data.tar.gz: a7f00d36f7a718b618628445e15ccda0b8008b6b7df2cf1c61c65bbf03746d0a
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: b3782237ad2900085f3dadba5ae365b54612267ef3414feea4c0197d5c62ea49f90db0ed31c9ce60fdb0cbbdc8545b11aa9c6a18d7dce66b898cb1dc68b32b48
|
|
7
|
+
data.tar.gz: eac26db4c1fff4f3e8290f210f773554f233a1d8ece6a9ad6335aabf7eac6c4ecef0297e56ebbf2ae0d8a5d36f8bf0d3b35c92b5a16f3ba90ff07f8552531dbd
|
data/README.md
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Bridgetown Slim Support
|
|
2
|
+
|
|
3
|
+
Slim テンプレートを Bridgetown 2.0 で扱うためのヘルパーとコンバーターを提供する RubyGems パッケージです。`image_tag` や `link_to`、部分テンプレート(`render`)などの Rails ライクな API を含みます。
|
|
4
|
+
|
|
5
|
+
## 主な機能
|
|
6
|
+
|
|
7
|
+
- Slim ファイル (`.slim`) を HTML に変換する Bridgetown コンバーター
|
|
8
|
+
- `image_tag`, `link_to` の Slim/ERB 両対応テンプレートヘルパー
|
|
9
|
+
- Slim 部分テンプレートにも対応したカスタム `Bridgetown::SlimSupport::View`
|
|
10
|
+
- サイト初期化時にヘルパーとコンバーターを登録する Bridgetown フック
|
|
11
|
+
|
|
12
|
+
## インストール
|
|
13
|
+
|
|
14
|
+
Gemfile に以下を追加します。
|
|
15
|
+
|
|
16
|
+
```ruby
|
|
17
|
+
gem "bridgetown-slim-support"
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Bundler でインストールします。
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
bundle install
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`bridgetown-slim-support` は依存として `slim` / `tilt` / `fastimage` を自動でインストールします。Gemfile に個別に追記する必要はありません。
|
|
27
|
+
|
|
28
|
+
## Bridgetown への設定
|
|
29
|
+
|
|
30
|
+
サイトの初期化時に Slim テンプレートエンジンを有効にするため、`config/initializers.rb` へ次のように追記してください。
|
|
31
|
+
|
|
32
|
+
```ruby
|
|
33
|
+
Bridgetown.configure do |config|
|
|
34
|
+
require "bridgetown/slim_support" # Slim サポート一式をロード
|
|
35
|
+
config.template_engine "slim"
|
|
36
|
+
end
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
これでサイトのリセット時に Slim コンバーターとヘルパーが登録されます。
|
|
40
|
+
|
|
41
|
+
## 使い方の例
|
|
42
|
+
|
|
43
|
+
Slim テンプレートではヘルパーメソッドを利用できます。
|
|
44
|
+
|
|
45
|
+
```slim
|
|
46
|
+
= image_tag "cover.jpg"
|
|
47
|
+
= link_to "アトリヱ未来", "https://atelier-mirai.net"
|
|
48
|
+
|
|
49
|
+
= render "shared/card", title: "Slim Sample", image: "cover.jpg" do
|
|
50
|
+
p
|
|
51
|
+
| Explore how Slim integrates with
|
|
52
|
+
= link_to "Bridgetown", "https://www.bridgetownrb.com"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`image_tag` はローカル画像に対し幅・高さを自動付与し、`link_to` はテキストリンクおよびブロック構文の両方で利用できます。`render` では部分テンプレートにパラメータとブロックを同時に渡せます。
|
|
56
|
+
|
|
57
|
+
上記は次のような HTML に変換されます(`width` / `height` には FastImage が検出した実寸法が入ります)。
|
|
58
|
+
|
|
59
|
+
```html
|
|
60
|
+
<img src="/images/cover.jpg" alt="Cover" loading="lazy" width="1200" height="600">
|
|
61
|
+
<a href="https://atelier-mirai.net">アトリヱ未来</a>
|
|
62
|
+
<div class="card">
|
|
63
|
+
<div class="card__image">
|
|
64
|
+
<img src="/images/cover.jpg" alt="Cover" loading="lazy" width="1200" height="600">
|
|
65
|
+
</div>
|
|
66
|
+
<div class="card__body">
|
|
67
|
+
<h2>Slim Sample</h2>
|
|
68
|
+
<p>Explore how Slim integrates with<a href="https://www.bridgetownrb.com">Bridgetown</a></p>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
部分テンプレートは `_partials/shared/_card.slim` のように配置できます。
|
|
74
|
+
|
|
75
|
+
```slim
|
|
76
|
+
/- src/_partials/shared/_card.slim
|
|
77
|
+
.card
|
|
78
|
+
- if image
|
|
79
|
+
.card__image
|
|
80
|
+
== image_tag image
|
|
81
|
+
.card__body
|
|
82
|
+
- if title
|
|
83
|
+
h2
|
|
84
|
+
== title
|
|
85
|
+
- if block_given?
|
|
86
|
+
== yield
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## 部分テンプレートの探索ディレクトリの変更
|
|
90
|
+
`config/initializers.rb` の `Bridgetown.configure` ブロック内に `config.partials_dir = "_includes"` を追記すれば、別ディレクトリを探索させることも可能です。
|
|
91
|
+
|
|
92
|
+
```ruby
|
|
93
|
+
Bridgetown.configure do |config|
|
|
94
|
+
require "bridgetown/slim_support" # Slim サポート一式をロード
|
|
95
|
+
|
|
96
|
+
config.template_engine "slim" # Slim サポートを有効
|
|
97
|
+
config.partials_dir = "_includes" # 部分テンプレートを探索するディレクトリ
|
|
98
|
+
|
|
99
|
+
# `image_tag` の既定 `loading` を無効化したい場合
|
|
100
|
+
Bridgetown::SlimSupport::Helpers.default_loading = nil
|
|
101
|
+
# 常に eager 読み込みさせたい場合
|
|
102
|
+
Bridgetown::SlimSupport::Helpers.default_loading = :eager
|
|
103
|
+
end
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## image_tag の設定例
|
|
107
|
+
|
|
108
|
+
デフォルトでは `loading="lazy"` が付与されますが、`loading: :eager` や `loading: nil` を指定するとその設定が優先されます。
|
|
109
|
+
|
|
110
|
+
```slim
|
|
111
|
+
= image_tag "cover.jpg"
|
|
112
|
+
= image_tag "hero.jpg", loading: :eager
|
|
113
|
+
= image_tag "key_visual.jpg", loading: nil
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
```html
|
|
117
|
+
<img src="/images/cover.jpg" loading="lazy" alt="Cover" width="1200" height="600">
|
|
118
|
+
<img src="/images/hero.jpg" loading="eager" alt="Hero" width="1200" height="600">
|
|
119
|
+
<img src="/images/key_visual.jpg" alt="Key visual" width="1200" height="600">
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Front Matter での Slim 指定
|
|
123
|
+
`.slim` 拡張子以外のファイルでも、Front Matter に `template_engine: slim` を追加すると Slim としてレンダリングされます。
|
|
124
|
+
|
|
125
|
+
```yaml
|
|
126
|
+
---
|
|
127
|
+
template_engine: slim
|
|
128
|
+
---
|
|
129
|
+
parent
|
|
130
|
+
child XML with Slim syntax
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
例えば `src/data.xml` に上記を記述すれば、変換後も `.xml` のまま Slim テンプレートとして処理されます。
|
|
134
|
+
|
|
135
|
+
## 開発
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
git clone https://github.com/atelier-mirai/bridgetown-slim-support.git
|
|
139
|
+
cd bridgetown-slim-support
|
|
140
|
+
bundle install
|
|
141
|
+
|
|
142
|
+
# テスト実行
|
|
143
|
+
bundle exec rake test
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
テストや追加機能を実装する際は `lib/bridgetown/slim_support/` 配下のコードを編集してください。
|
|
147
|
+
|
|
148
|
+
## クレジット
|
|
149
|
+
|
|
150
|
+
- Atelier Mirai (https://atelier-mirai.net)
|
|
151
|
+
|
|
152
|
+
## 外部ライブラリ
|
|
153
|
+
|
|
154
|
+
- fastimage — MIT License (https://github.com/sdsykes/fastimage)
|
|
155
|
+
- slim — MIT License (https://github.com/slim-template/slim)
|
|
156
|
+
- tilt — MIT License (https://github.com/rtomayko/tilt)
|
|
157
|
+
|
|
158
|
+
## ライセンス
|
|
159
|
+
|
|
160
|
+
MIT License
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "bridgetown/slim_support/version"
|
|
5
|
+
|
|
6
|
+
module Bridgetown
|
|
7
|
+
module SlimSupport
|
|
8
|
+
module CLI
|
|
9
|
+
module_function
|
|
10
|
+
|
|
11
|
+
def run(argv)
|
|
12
|
+
if argv.empty? || version_flag?(argv)
|
|
13
|
+
print_version
|
|
14
|
+
exit 0
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
if help_flag?(argv)
|
|
18
|
+
print_help
|
|
19
|
+
exit 0
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
warn "Usage: bridgetown-slim-support [--version|-v|--help|-h]"
|
|
23
|
+
exit 1
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def version_flag?(argv)
|
|
27
|
+
argv.any? { |arg| ["--version", "-v"].include?(arg) }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def help_flag?(argv)
|
|
31
|
+
argv.any? { |arg| ["--help", "-h"].include?(arg) }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def print_version
|
|
35
|
+
puts "bridgetown-slim-support #{Bridgetown::SlimSupport::VERSION}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def print_help
|
|
39
|
+
puts <<~HELP
|
|
40
|
+
Usage: bridgetown-slim-support [options]
|
|
41
|
+
|
|
42
|
+
Options:
|
|
43
|
+
-v, --version Show the installed bridgetown-slim-support version
|
|
44
|
+
-h, --help Show this help message
|
|
45
|
+
|
|
46
|
+
The gem integrates Slim template rendering into Bridgetown projects.
|
|
47
|
+
Once installed, simply require the gem in your Bridgetown site and build.
|
|
48
|
+
For detailed usage instructions, please refer to the README.
|
|
49
|
+
HELP
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
Bridgetown::SlimSupport::CLI.run(ARGV)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Bridgetown converter which renders `.slim` templates to HTML output.
|
|
4
|
+
# It keeps parity with ERB conversion so Slim pages work without extra setup.
|
|
5
|
+
require "slim"
|
|
6
|
+
|
|
7
|
+
module Bridgetown
|
|
8
|
+
module SlimSupport
|
|
9
|
+
class Converter < Bridgetown::Converter
|
|
10
|
+
priority :low
|
|
11
|
+
|
|
12
|
+
# Detect `.slim` extensions, allowing Bridgetown to dispatch to this converter.
|
|
13
|
+
# The second argument is unused but part of the Bridgetown converter API.
|
|
14
|
+
def matches(ext, convertible)
|
|
15
|
+
if convertible && convertible.respond_to?(:data)
|
|
16
|
+
engine = convertible.data[:template_engine] || convertible.data["template_engine"]
|
|
17
|
+
return true if engine&.to_s&.downcase == "slim"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
ext =~ /^\.slim$/i
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Always output HTML for Slim templates.
|
|
24
|
+
def output_ext(_ext)
|
|
25
|
+
return ".html" if _ext.to_s.casecmp(".slim").zero?
|
|
26
|
+
|
|
27
|
+
_ext
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Render Slim content using the custom view so helpers are available.
|
|
31
|
+
# This method mirrors Bridgetown's ERB converter by providing a view object
|
|
32
|
+
# which exposes helpers like `image_tag` and `link_to` to Slim templates.
|
|
33
|
+
def convert(content, convertible)
|
|
34
|
+
content = content.force_encoding("UTF-8") unless content.encoding == Encoding::UTF_8
|
|
35
|
+
|
|
36
|
+
begin
|
|
37
|
+
unless defined?(::Components::UI::Card)
|
|
38
|
+
site = if convertible.respond_to?(:site)
|
|
39
|
+
convertible.site
|
|
40
|
+
elsif defined?(Bridgetown::Current) && Bridgetown::Current.respond_to?(:site)
|
|
41
|
+
Bridgetown::Current.site
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
if site.respond_to?(:in_source_dir)
|
|
45
|
+
# Legacy support: eagerly load the old `ui/card` component if present
|
|
46
|
+
# so Slim templates referencing it do not fail.
|
|
47
|
+
ui_card_path = site.in_source_dir("_components", "ui", "card.rb")
|
|
48
|
+
require ui_card_path if File.exist?(ui_card_path)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
rescue LoadError
|
|
52
|
+
# Ignore missing component files; the goal is best-effort compatibility.
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
view = Bridgetown::SlimSupport::View.new(convertible)
|
|
56
|
+
|
|
57
|
+
template = Slim::Template.new { content }
|
|
58
|
+
|
|
59
|
+
result = if convertible.respond_to?(:current_document_output)
|
|
60
|
+
template.render(view) { convertible.current_document_output }
|
|
61
|
+
else
|
|
62
|
+
template.render(view)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
result = result.force_encoding("UTF-8") unless result.encoding == Encoding::UTF_8
|
|
66
|
+
result.respond_to?(:html_safe) ? result.html_safe : result
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bridgetown
|
|
4
|
+
module SlimSupport
|
|
5
|
+
# View helper methods shared between Slim and ERB templates.
|
|
6
|
+
# Many of these mirror Rails helpers, making migration from Rails views easier.
|
|
7
|
+
module Helpers
|
|
8
|
+
class << self
|
|
9
|
+
attr_accessor :default_loading
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
self.default_loading = :lazy
|
|
13
|
+
|
|
14
|
+
# Render an `<img>` tag with automatic path handling and optional dimensions.
|
|
15
|
+
# Automatically prepends `/images/` for relative paths and enables lazy loading.
|
|
16
|
+
def image_tag(path, **options)
|
|
17
|
+
src = if path.to_s.start_with?("/", "http://", "https://", "//")
|
|
18
|
+
path
|
|
19
|
+
else
|
|
20
|
+
"/images/#{path}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
options[:loading] = Bridgetown::SlimSupport::Helpers.default_loading unless options.key?(:loading)
|
|
24
|
+
|
|
25
|
+
unless path.to_s.include?("://")
|
|
26
|
+
options[:width] ||= nil
|
|
27
|
+
options[:height] ||= nil
|
|
28
|
+
|
|
29
|
+
file_path = if path.start_with?("/")
|
|
30
|
+
File.join(Dir.pwd, "src", path.sub(%r{^/}, ""))
|
|
31
|
+
else
|
|
32
|
+
File.join(Dir.pwd, "src", "images", path)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
if File.exist?(file_path)
|
|
36
|
+
if alt_blank?(options[:alt])
|
|
37
|
+
options[:alt] = humanized_alt_from_file(file_path)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
if options[:width].nil? || options[:height].nil?
|
|
41
|
+
begin
|
|
42
|
+
require "fastimage"
|
|
43
|
+
w, h = FastImage.size(file_path)
|
|
44
|
+
options[:width] ||= w
|
|
45
|
+
options[:height] ||= h
|
|
46
|
+
rescue LoadError
|
|
47
|
+
# ignore
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
if alt_blank?(options[:alt])
|
|
54
|
+
options[:alt] = humanized_alt_from_path(path)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
tag(:img, src: src, **options)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Generate an anchor tag, supporting block usage similar to Rails helpers.
|
|
61
|
+
# Accepts the same arguments whether called as `link_to("Label", "/")` or with a block.
|
|
62
|
+
def link_to(name = nil, url = nil, **options, &block)
|
|
63
|
+
if block_given?
|
|
64
|
+
if name.is_a?(Hash)
|
|
65
|
+
options = name.merge(options)
|
|
66
|
+
url ||= options.delete(:url) || options.delete("url")
|
|
67
|
+
else
|
|
68
|
+
url = name
|
|
69
|
+
end
|
|
70
|
+
inner_html = capture(&block)
|
|
71
|
+
else
|
|
72
|
+
inner_html = name.to_s.html_safe
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
options ||= {}
|
|
76
|
+
options = {} unless options.is_a?(Hash)
|
|
77
|
+
options = options.transform_keys(&:to_s)
|
|
78
|
+
|
|
79
|
+
url ||= options.delete("url") || "#"
|
|
80
|
+
|
|
81
|
+
existing_classes = Array(options.delete("class")).flat_map { |cls| cls.to_s.split(/\s+/) }.reject(&:empty?)
|
|
82
|
+
options["class"] = existing_classes.any? ? existing_classes.join(" ") : nil
|
|
83
|
+
|
|
84
|
+
content_tag(:a, inner_html, options.merge("href" => url))
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Wrap content within the given tag name.
|
|
88
|
+
# Supports block syntax so nested markup can be generated inline.
|
|
89
|
+
def content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block)
|
|
90
|
+
if block_given?
|
|
91
|
+
options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
|
|
92
|
+
content = capture { yield }
|
|
93
|
+
else
|
|
94
|
+
content = content_or_options_with_block
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
options = options ? options.transform_keys(&:to_s) : {}
|
|
98
|
+
tag_options_str = tag_options(options) if options
|
|
99
|
+
|
|
100
|
+
content = content.to_s
|
|
101
|
+
content = content.html_safe unless content.html_safe?
|
|
102
|
+
|
|
103
|
+
"<#{name}#{tag_options_str}>#{content}</#{name}>".html_safe
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Shorten text with an omission indicator.
|
|
107
|
+
# Useful for previews or card layouts where space is constrained.
|
|
108
|
+
def truncate_text(text, length: 30, omission: "...")
|
|
109
|
+
return "" if text.nil?
|
|
110
|
+
|
|
111
|
+
text = text.to_s
|
|
112
|
+
return text if text.length <= length
|
|
113
|
+
|
|
114
|
+
truncate_at = length - omission.length
|
|
115
|
+
truncate_at = 0 if truncate_at.negative?
|
|
116
|
+
|
|
117
|
+
text[0, truncate_at] + omission
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
private
|
|
121
|
+
|
|
122
|
+
def alt_blank?(value)
|
|
123
|
+
value.nil? || (value.respond_to?(:empty?) && value.empty?)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def humanized_alt_from_file(file_path)
|
|
127
|
+
humanized_alt_from_basename(File.basename(file_path))
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def humanized_alt_from_path(path)
|
|
131
|
+
return "" if path.nil?
|
|
132
|
+
|
|
133
|
+
segment = path.to_s.split("/").last.to_s
|
|
134
|
+
segment = segment.split("?").first.split("#").first
|
|
135
|
+
|
|
136
|
+
humanized_alt_from_basename(segment)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def humanized_alt_from_basename(name)
|
|
140
|
+
return "" if name.nil? || name.empty?
|
|
141
|
+
|
|
142
|
+
File.basename(name, ".*").gsub(/[-_]/, " ").capitalize
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Build HTML for a tag with optional nested content.
|
|
146
|
+
# This is the low-level primitive backing `content_tag` and `image_tag`.
|
|
147
|
+
def tag(name, **options, &block)
|
|
148
|
+
if block_given?
|
|
149
|
+
content = capture { yield }
|
|
150
|
+
"<#{name}#{tag_options(options)}>#{content}</#{name}>".html_safe
|
|
151
|
+
else
|
|
152
|
+
"<#{name}#{tag_options(options)} />".html_safe
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Convert a hash of options into HTML attributes.
|
|
157
|
+
# Keeps ordering deterministic by sorting attributes alphabetically.
|
|
158
|
+
def tag_options(options = {})
|
|
159
|
+
return "" if options.empty?
|
|
160
|
+
|
|
161
|
+
attrs = []
|
|
162
|
+
options.each do |key, value|
|
|
163
|
+
attrs << %(#{key}="#{value}") if value.present? || value == false
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
attrs.empty? ? "" : " #{attrs.sort.join(" ")}"
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Capture block output in a template-friendly way.
|
|
170
|
+
def capture(&block)
|
|
171
|
+
return "".html_safe unless block_given?
|
|
172
|
+
|
|
173
|
+
result = if defined?(Slim) && block.binding.eval("defined? _slim_compiled")
|
|
174
|
+
block.call
|
|
175
|
+
else
|
|
176
|
+
block.call
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
result.respond_to?(:to_s) ? result.to_s.html_safe : "".html_safe
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Hook into Bridgetown's lifecycle to install Slim helpers and converter.
|
|
4
|
+
# The `:after_reset` hook runs whenever a site is initialized or reloaded.
|
|
5
|
+
Bridgetown::Hooks.register :site, :after_reset do |site|
|
|
6
|
+
Bridgetown.logger.info "SlimSupport", "registering helpers and converter"
|
|
7
|
+
Bridgetown::SlimSupport.register_template_helpers!
|
|
8
|
+
Bridgetown::SlimSupport.register_converter!(site)
|
|
9
|
+
end
|
|
10
|
+
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Custom view object to render Slim templates with Bridgetown helpers.
|
|
4
|
+
# Acts as a drop-in replacement for Bridgetown's ERB view but tailored for Slim.
|
|
5
|
+
require "slim"
|
|
6
|
+
|
|
7
|
+
module Bridgetown
|
|
8
|
+
module SlimSupport
|
|
9
|
+
# View used by the Slim converter to provide helper access.
|
|
10
|
+
# Inherits from `Bridgetown::ERBView` to reuse existing rendering behavior.
|
|
11
|
+
class View < Bridgetown::ERBView
|
|
12
|
+
include Bridgetown::SlimSupport::Helpers
|
|
13
|
+
|
|
14
|
+
public :capture if private_method_defined?(:capture)
|
|
15
|
+
|
|
16
|
+
# Allow `render` to accept component instances as well as partial names.
|
|
17
|
+
# This mirrors ViewComponent integration where `render component` is common.
|
|
18
|
+
def render(item, *args, &block)
|
|
19
|
+
if item.is_a?(String)
|
|
20
|
+
partial(item, *args, &block)
|
|
21
|
+
else
|
|
22
|
+
super
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
# Locate and render a partial, falling back to ERB behaviour when necessary.
|
|
29
|
+
# Supports both `.slim` and `.erb` partials so mixed-template projects work.
|
|
30
|
+
def partial(partial_name, options = {}, &block)
|
|
31
|
+
partial_segments = partial_name.to_s.split("/")
|
|
32
|
+
if partial_segments.empty?
|
|
33
|
+
partial_segments = ["_partial"]
|
|
34
|
+
else
|
|
35
|
+
last = partial_segments.pop
|
|
36
|
+
partial_segments << (last.start_with?("_") ? last : "_#{last}")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
partial_path = find_partial_path(partial_segments)
|
|
40
|
+
return "".html_safe unless partial_path
|
|
41
|
+
|
|
42
|
+
content = File.read(partial_path, encoding: "UTF-8")
|
|
43
|
+
|
|
44
|
+
if partial_path.end_with?(".slim")
|
|
45
|
+
template = Slim::Template.new { content }
|
|
46
|
+
result = template.render(self, options, &block)
|
|
47
|
+
result.respond_to?(:html_safe) ? result.html_safe : result
|
|
48
|
+
else
|
|
49
|
+
super
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Resolve available partial paths in `_partials/` for Slim or ERB.
|
|
54
|
+
# Searches for Slim first, then ERB to preserve compatibility with core Bridgetown.
|
|
55
|
+
def find_partial_path(partial_segments)
|
|
56
|
+
site = resource.site if resource.respond_to?(:site)
|
|
57
|
+
return unless site
|
|
58
|
+
|
|
59
|
+
partials_dir = site.config["partials_dir"] || site.config[:partials_dir] || "_partials"
|
|
60
|
+
|
|
61
|
+
[".slim", ".erb"].each do |ext|
|
|
62
|
+
relative_path = File.join(*partial_segments) + ext
|
|
63
|
+
path = site.in_source_dir(partials_dir, relative_path)
|
|
64
|
+
return path if File.exist?(path)
|
|
65
|
+
end
|
|
66
|
+
nil
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Entry point for registering Slim support features with Bridgetown.
|
|
4
|
+
# Loads helper modules, converter, and view so they can be wired into a site.
|
|
5
|
+
require "bridgetown"
|
|
6
|
+
require "slim"
|
|
7
|
+
require "tilt"
|
|
8
|
+
|
|
9
|
+
require_relative "slim_support/version"
|
|
10
|
+
require_relative "slim_support/helpers"
|
|
11
|
+
require_relative "slim_support/converter"
|
|
12
|
+
require_relative "slim_support/view"
|
|
13
|
+
require_relative "slim_support/plugin"
|
|
14
|
+
|
|
15
|
+
module Bridgetown
|
|
16
|
+
# Collection of helpers and utilities enabling Slim templates.
|
|
17
|
+
module SlimSupport
|
|
18
|
+
class Error < StandardError; end
|
|
19
|
+
|
|
20
|
+
class << self
|
|
21
|
+
# Register Slim helpers with available Bridgetown view classes.
|
|
22
|
+
# The registration is idempotent so the hook can run on multiple lifecycle events.
|
|
23
|
+
def register_template_helpers!
|
|
24
|
+
return if @helpers_registered
|
|
25
|
+
|
|
26
|
+
if defined?(::Bridgetown::RubyTemplateView::Helpers)
|
|
27
|
+
# Make helper methods available to Ruby template helper modules.
|
|
28
|
+
::Bridgetown::RubyTemplateView::Helpers.include Bridgetown::SlimSupport::Helpers
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
if defined?(::Bridgetown::RubyTemplateView)
|
|
32
|
+
# Support direct usage from Ruby-based views.
|
|
33
|
+
::Bridgetown::RubyTemplateView.include Bridgetown::SlimSupport::Helpers
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if defined?(::Bridgetown::ERBView)
|
|
37
|
+
# Ensure ERB templates rendered alongside Slim keep feature parity.
|
|
38
|
+
::Bridgetown::ERBView.include Bridgetown::SlimSupport::Helpers
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
if defined?(::Bridgetown::ViewComponent::Base)
|
|
42
|
+
# Allow ViewComponent classes to use the same helper methods.
|
|
43
|
+
::Bridgetown::ViewComponent::Base.include Bridgetown::SlimSupport::Helpers
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
@helpers_registered = true
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Add the Slim converter to the site's converter stack.
|
|
50
|
+
def register_converter!(site)
|
|
51
|
+
converters = site.converters
|
|
52
|
+
|
|
53
|
+
unless converters
|
|
54
|
+
converters = []
|
|
55
|
+
site.instance_variable_set(:@converters, converters)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
return if converters.any? { |converter| converter.is_a?(Bridgetown::SlimSupport::Converter) }
|
|
59
|
+
|
|
60
|
+
# Append the converter so Slim templates render without additional configuration.
|
|
61
|
+
converters << Bridgetown::SlimSupport::Converter.new(site.config)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: bridgetown-slim-support
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Atelier Mirai
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: bridgetown
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '1.3'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '3.0'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: '1.3'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '3.0'
|
|
32
|
+
- !ruby/object:Gem::Dependency
|
|
33
|
+
name: slim
|
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
|
35
|
+
requirements:
|
|
36
|
+
- - ">="
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '4.1'
|
|
39
|
+
- - "<"
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: '6.0'
|
|
42
|
+
type: :runtime
|
|
43
|
+
prerelease: false
|
|
44
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
45
|
+
requirements:
|
|
46
|
+
- - ">="
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: '4.1'
|
|
49
|
+
- - "<"
|
|
50
|
+
- !ruby/object:Gem::Version
|
|
51
|
+
version: '6.0'
|
|
52
|
+
- !ruby/object:Gem::Dependency
|
|
53
|
+
name: tilt
|
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
|
55
|
+
requirements:
|
|
56
|
+
- - ">="
|
|
57
|
+
- !ruby/object:Gem::Version
|
|
58
|
+
version: '2.0'
|
|
59
|
+
- - "<"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '3.0'
|
|
62
|
+
type: :runtime
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '2.0'
|
|
69
|
+
- - "<"
|
|
70
|
+
- !ruby/object:Gem::Version
|
|
71
|
+
version: '3.0'
|
|
72
|
+
- !ruby/object:Gem::Dependency
|
|
73
|
+
name: fastimage
|
|
74
|
+
requirement: !ruby/object:Gem::Requirement
|
|
75
|
+
requirements:
|
|
76
|
+
- - ">="
|
|
77
|
+
- !ruby/object:Gem::Version
|
|
78
|
+
version: '2.4'
|
|
79
|
+
- - "<"
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '3.0'
|
|
82
|
+
type: :runtime
|
|
83
|
+
prerelease: false
|
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '2.4'
|
|
89
|
+
- - "<"
|
|
90
|
+
- !ruby/object:Gem::Version
|
|
91
|
+
version: '3.0'
|
|
92
|
+
description: Adds Slim converters, Rails-style helpers like `image_tag` and `link_to`,
|
|
93
|
+
partial rendering support, and configuration hooks so Bridgetown projects can adopt
|
|
94
|
+
Slim templates with minimal setup.
|
|
95
|
+
email:
|
|
96
|
+
- contact@atelier-mirai.net
|
|
97
|
+
executables:
|
|
98
|
+
- bridgetown-slim-support
|
|
99
|
+
extensions: []
|
|
100
|
+
extra_rdoc_files: []
|
|
101
|
+
files:
|
|
102
|
+
- README.md
|
|
103
|
+
- bin/bridgetown-slim-support
|
|
104
|
+
- lib/bridgetown-slim-support.rb
|
|
105
|
+
- lib/bridgetown/slim_support.rb
|
|
106
|
+
- lib/bridgetown/slim_support/converter.rb
|
|
107
|
+
- lib/bridgetown/slim_support/helpers.rb
|
|
108
|
+
- lib/bridgetown/slim_support/plugin.rb
|
|
109
|
+
- lib/bridgetown/slim_support/version.rb
|
|
110
|
+
- lib/bridgetown/slim_support/view.rb
|
|
111
|
+
homepage: https://github.com/atelier-mirai/bridgetown-slim-support
|
|
112
|
+
licenses:
|
|
113
|
+
- MIT
|
|
114
|
+
metadata:
|
|
115
|
+
source_code_uri: https://github.com/atelier-mirai/bridgetown-slim-support
|
|
116
|
+
changelog_uri: https://github.com/atelier-mirai/bridgetown-slim-support/blob/master/CHANGELOG.md
|
|
117
|
+
documentation_uri: https://github.com/atelier-mirai/bridgetown-slim-support#readme
|
|
118
|
+
rdoc_options: []
|
|
119
|
+
require_paths:
|
|
120
|
+
- lib
|
|
121
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
122
|
+
requirements:
|
|
123
|
+
- - ">="
|
|
124
|
+
- !ruby/object:Gem::Version
|
|
125
|
+
version: '3.4'
|
|
126
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
|
+
requirements:
|
|
128
|
+
- - ">="
|
|
129
|
+
- !ruby/object:Gem::Version
|
|
130
|
+
version: '0'
|
|
131
|
+
requirements: []
|
|
132
|
+
rubygems_version: 3.7.2
|
|
133
|
+
specification_version: 4
|
|
134
|
+
summary: Slim template support helpers for Bridgetown
|
|
135
|
+
test_files: []
|