isola 0.1.2 → 0.2.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 +4 -4
- data/.rubocop.yml +2 -0
- data/USAGE.ja.md +64 -0
- data/USAGE.md +64 -0
- data/lib/isola/context.rb +19 -8
- data/lib/isola/file_handler.rb +5 -4
- data/lib/isola/language_path_router.rb +39 -0
- data/lib/isola/site.rb +110 -26
- data/lib/isola/source.rb +7 -14
- data/lib/isola/static_file.rb +8 -0
- data/lib/isola/version.rb +1 -1
- data/lib/isola.rb +2 -0
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 507fdf7f262bfde7e67d143cc6d5b09b0c7b7939dfbc1c7aaf6dbcc9f1a5cf38
|
|
4
|
+
data.tar.gz: f39703fba0476b6cd38f5877111d2e3a9abf06cffe6cdc73341487085ff631fc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1f85fd79af5a9bea7886312fede020b672514f111be326758b6c36797bc8c449a37d294a6db5d2c38215be855447e4a9d56135526bcafe767c0de6d45280a3f2
|
|
7
|
+
data.tar.gz: ee38afab7cd7bf59701503651928773202de085f6e2d84be8e081429c4692ca9da069764ab1c36c9399006591f535c64a0653371d8a77abb6616bcf1267e0a0e
|
data/.rubocop.yml
ADDED
data/USAGE.ja.md
CHANGED
|
@@ -116,3 +116,67 @@ Isolaが処理するテンプレートエンジンは現在 **ERB**(`.erb`)
|
|
|
116
116
|
| `*.css`, `*.js` など | なし | そのままコピー |
|
|
117
117
|
|
|
118
118
|
`_`や`.`で始まるファイル・ディレクトリは自動的に除外されます(`_layouts/`と`_includes/`を除く)。
|
|
119
|
+
|
|
120
|
+
## 多言語対応
|
|
121
|
+
|
|
122
|
+
Isolaは多言語サイトの構築をサポートしています。デフォルト言語のページはサイトルートに、その他の言語は言語コード名のサブディレクトリに配置します。
|
|
123
|
+
|
|
124
|
+
### 設定
|
|
125
|
+
|
|
126
|
+
`_config.yaml`に`default_language`と`languages`を追加します:
|
|
127
|
+
|
|
128
|
+
```yaml
|
|
129
|
+
default_language: ja
|
|
130
|
+
languages:
|
|
131
|
+
ja:
|
|
132
|
+
label: "日本語"
|
|
133
|
+
en:
|
|
134
|
+
label: "English"
|
|
135
|
+
title: "My Site (EN)"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
各言語エントリでサイトレベルの設定値を上書きできます。例えば上記の設定では、英語ページのレンダリング時に`site[:title]`が`"My Site (EN)"`を返します。
|
|
139
|
+
|
|
140
|
+
### ディレクトリ構成
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
my-site/
|
|
144
|
+
├── _config.yaml
|
|
145
|
+
├── _layouts/
|
|
146
|
+
│ ├── default.html.erb # 共有レイアウト(全言語で使用)
|
|
147
|
+
│ └── en/default.html.erb # 英語専用レイアウト(上書き)
|
|
148
|
+
├── _includes/
|
|
149
|
+
│ ├── head.html.erb # 共有インクルード
|
|
150
|
+
│ └── en/head.html.erb # 英語専用インクルード(上書き)
|
|
151
|
+
├── index.md # デフォルト言語(ja)のページ
|
|
152
|
+
└── en/index.md # 英語ページ
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
- **ページ**: デフォルト言語のページはルートに配置します。他の言語は`<lang>/`サブディレクトリに配置します(例: `en/index.md`)。
|
|
156
|
+
- **レイアウトとインクルード**: 言語固有のオーバーライドは`_layouts/<lang>/`や`_includes/<lang>/`に配置します。言語固有のバージョンが見つからない場合、共有バージョンがフォールバックとして使われます。
|
|
157
|
+
|
|
158
|
+
### テンプレート変数
|
|
159
|
+
|
|
160
|
+
標準のテンプレート変数に加え、多言語サイトでは以下が利用できます:
|
|
161
|
+
|
|
162
|
+
- `page[:lang]` — 現在のページの言語(例: `:ja`, `:en`)
|
|
163
|
+
- `page[:translations]` — 現在のページの全翻訳版を`{lang: url_path}`形式のハッシュで返す(先頭が`/`のURLパスであり、`href`属性などにそのまま利用できます)
|
|
164
|
+
|
|
165
|
+
#### hreflangリンクの生成
|
|
166
|
+
|
|
167
|
+
`page[:translations]`を使って代替言語リンクを出力できます:
|
|
168
|
+
|
|
169
|
+
```erb
|
|
170
|
+
<% page[:translations].each do |lang, url| %>
|
|
171
|
+
<link rel="alternate" hreflang="<%= lang %>" href="<%= url %>">
|
|
172
|
+
<% end %>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### 出力
|
|
176
|
+
|
|
177
|
+
出力はソースの構成を反映します:
|
|
178
|
+
|
|
179
|
+
| ソース | 出力 |
|
|
180
|
+
|---|---|
|
|
181
|
+
| `index.md` | `_site/index.html` |
|
|
182
|
+
| `en/index.md` | `_site/en/index.html` |
|
data/USAGE.md
CHANGED
|
@@ -116,3 +116,67 @@ If an extension remains after processing, it is kept as-is. If no extension rema
|
|
|
116
116
|
| `*.css`, `*.js` etc. | None | Copied as-is |
|
|
117
117
|
|
|
118
118
|
Files and directories starting with `_` or `.` are excluded automatically (except `_layouts/` and `_includes/`).
|
|
119
|
+
|
|
120
|
+
## Multi-Language Support
|
|
121
|
+
|
|
122
|
+
Isola supports building multi-language sites. Pages for the default language live at the site root, while other languages are placed in subdirectories named by language code.
|
|
123
|
+
|
|
124
|
+
### Configuration
|
|
125
|
+
|
|
126
|
+
Add `default_language` and `languages` to `_config.yaml`:
|
|
127
|
+
|
|
128
|
+
```yaml
|
|
129
|
+
default_language: ja
|
|
130
|
+
languages:
|
|
131
|
+
ja:
|
|
132
|
+
label: "日本語"
|
|
133
|
+
en:
|
|
134
|
+
label: "English"
|
|
135
|
+
title: "My Site (EN)"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Each language entry can override any site-level configuration value. For example, `site[:title]` returns `"My Site (EN)"` when rendering English pages.
|
|
139
|
+
|
|
140
|
+
### Directory Structure
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
my-site/
|
|
144
|
+
├── _config.yaml
|
|
145
|
+
├── _layouts/
|
|
146
|
+
│ ├── default.html.erb # Shared layout (used by all languages)
|
|
147
|
+
│ └── en/default.html.erb # English-specific layout override
|
|
148
|
+
├── _includes/
|
|
149
|
+
│ ├── head.html.erb # Shared include
|
|
150
|
+
│ └── en/head.html.erb # English-specific include override
|
|
151
|
+
├── index.md # Default language (ja) page
|
|
152
|
+
└── en/index.md # English page
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
- **Pages**: Default-language pages live at the root. Other languages go in `<lang>/` subdirectories (e.g. `en/index.md`).
|
|
156
|
+
- **Layouts and includes**: Place language-specific overrides under `_layouts/<lang>/` or `_includes/<lang>/`. If a language-specific version is not found, the shared version is used as a fallback.
|
|
157
|
+
|
|
158
|
+
### Template Variables
|
|
159
|
+
|
|
160
|
+
In addition to the standard template variables, multi-language sites provide:
|
|
161
|
+
|
|
162
|
+
- `page[:lang]` — the language of the current page (e.g. `:ja`, `:en`)
|
|
163
|
+
- `page[:translations]` — a hash of `{lang: url_path}` (URL paths starting with `/`, suitable for `href` attributes) for all available translations of the current page
|
|
164
|
+
|
|
165
|
+
#### Generating hreflang Links
|
|
166
|
+
|
|
167
|
+
Use `page[:translations]` to output alternate-language links:
|
|
168
|
+
|
|
169
|
+
```erb
|
|
170
|
+
<% page[:translations].each do |lang, url| %>
|
|
171
|
+
<link rel="alternate" hreflang="<%= lang %>" href="<%= url %>">
|
|
172
|
+
<% end %>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Output
|
|
176
|
+
|
|
177
|
+
The output mirrors the source structure:
|
|
178
|
+
|
|
179
|
+
| Source | Output |
|
|
180
|
+
|---|---|
|
|
181
|
+
| `index.md` | `_site/index.html` |
|
|
182
|
+
| `en/index.md` | `_site/en/index.html` |
|
data/lib/isola/context.rb
CHANGED
|
@@ -2,30 +2,41 @@ require "tilt"
|
|
|
2
2
|
|
|
3
3
|
module Isola
|
|
4
4
|
class Context
|
|
5
|
-
attr_reader :
|
|
6
|
-
def initialize(
|
|
7
|
-
@
|
|
8
|
-
@meta =
|
|
5
|
+
attr_reader :content, :layout
|
|
6
|
+
def initialize(source, site, languages: {})
|
|
7
|
+
@source = source
|
|
8
|
+
@meta = source.meta.freeze
|
|
9
9
|
@site = site
|
|
10
10
|
@content = ""
|
|
11
11
|
@layout = {}
|
|
12
|
+
|
|
13
|
+
site_config = @site.config.merge(languages[@source[:lang]] || {})
|
|
14
|
+
@site_proxy = SimpleDelegator.new(@site).tap do
|
|
15
|
+
it.define_singleton_method(:[]) do |key|
|
|
16
|
+
site_config[key]
|
|
17
|
+
end
|
|
18
|
+
end
|
|
12
19
|
end
|
|
13
20
|
|
|
14
21
|
def page
|
|
15
22
|
@meta
|
|
16
23
|
end
|
|
17
24
|
|
|
25
|
+
def site
|
|
26
|
+
@site_proxy
|
|
27
|
+
end
|
|
28
|
+
|
|
18
29
|
def include name, params = {}
|
|
19
|
-
i = @site.include name
|
|
30
|
+
i = @site.include name, lang: @source[:lang]
|
|
20
31
|
raise "include #{name} not found in #{@current.filepath}" unless i
|
|
21
32
|
i.render(self, @site, params)[0]
|
|
22
33
|
end
|
|
23
34
|
|
|
24
35
|
def render
|
|
25
|
-
@current = @
|
|
26
|
-
@content, path = @
|
|
36
|
+
@current = @source
|
|
37
|
+
@content, path = @source.render(self, @site)
|
|
27
38
|
while @current.meta[:layout]
|
|
28
|
-
layout = site.layout(@current.meta[:layout])
|
|
39
|
+
layout = site.layout(@current.meta[:layout], lang: @source[:lang])
|
|
29
40
|
raise "#{@current.meta[:layout]} not found for #{@current.filepath}" unless layout
|
|
30
41
|
@current = layout
|
|
31
42
|
@content, _ = @current.render(self, @site)
|
data/lib/isola/file_handler.rb
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
module Isola
|
|
2
2
|
class FileHandler
|
|
3
|
-
attr_reader :
|
|
3
|
+
attr_reader :entries, :layouts, :includes, :root_dir
|
|
4
4
|
DEFAULT_EXCLUDES = [
|
|
5
5
|
".sass-cache", "gemfiles",
|
|
6
6
|
"Gemfile", "Gemfile.lock", "node_modules",
|
|
7
7
|
"vendor/bundle/", "vendor/cache/",
|
|
8
8
|
"vendor/gems/", "vendor/ruby/"
|
|
9
9
|
]
|
|
10
|
-
def initialize(root_dir, excludes: [])
|
|
10
|
+
def initialize(root_dir, output_path_func: nil, excludes: [])
|
|
11
11
|
@excludes = DEFAULT_EXCLUDES.union(excludes)
|
|
12
12
|
@rejects = Regexp.union(%r{(?:^|/)[._]}, %r{~$})
|
|
13
13
|
@root_dir = File.absolute_path(root_dir)
|
|
14
|
-
@
|
|
14
|
+
@entries = {}
|
|
15
15
|
@layouts = {}
|
|
16
16
|
@includes = {}
|
|
17
|
+
@output_path_func = output_path_func || method(:remove_exts)
|
|
17
18
|
collect(@root_dir)
|
|
18
19
|
end
|
|
19
20
|
|
|
@@ -36,7 +37,7 @@ module Isola
|
|
|
36
37
|
elsif path.start_with?("_includes/")
|
|
37
38
|
@includes[remove_exts(path).delete_prefix("_includes/")] = path
|
|
38
39
|
else
|
|
39
|
-
@
|
|
40
|
+
@entries[@output_path_func.call(path)] = path
|
|
40
41
|
end
|
|
41
42
|
end
|
|
42
43
|
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module Isola
|
|
2
|
+
class LanguagePathRouter
|
|
3
|
+
def initialize(default_language:, languages:)
|
|
4
|
+
@default_language = default_language.to_s
|
|
5
|
+
@languages = languages.map(&:to_s)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def language_for(path)
|
|
9
|
+
p = Pathname(path).each_filename.to_a
|
|
10
|
+
if p.length > 1 && @languages.include?(p[0])
|
|
11
|
+
p[0].to_sym
|
|
12
|
+
else
|
|
13
|
+
@default_language.to_sym
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def canonical_path(path)
|
|
18
|
+
p = Pathname(path).each_filename.to_a
|
|
19
|
+
if p.length > 1 && @languages.include?(p[0])
|
|
20
|
+
File.join(p[1..])
|
|
21
|
+
else
|
|
22
|
+
path
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def localized_path(path, language)
|
|
27
|
+
canonical = canonical_path(path)
|
|
28
|
+
if language.to_s == @default_language
|
|
29
|
+
canonical
|
|
30
|
+
else
|
|
31
|
+
File.join(language.to_s, canonical)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def candidate_paths(path)
|
|
36
|
+
@languages.to_h { |lang| [lang.to_sym, localized_path(path, lang)] }
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
data/lib/isola/site.rb
CHANGED
|
@@ -1,48 +1,67 @@
|
|
|
1
1
|
require "yaml"
|
|
2
2
|
require "fileutils"
|
|
3
|
+
require "delegate"
|
|
4
|
+
|
|
3
5
|
module Isola
|
|
4
6
|
class Site
|
|
5
7
|
attr_accessor :config
|
|
6
8
|
DEFAULT_CONFIG = {url: "http://example.com",
|
|
7
9
|
title: "my awesome site",
|
|
8
10
|
destination: "_site",
|
|
9
|
-
default_language:
|
|
11
|
+
default_language: :en,
|
|
10
12
|
host: "127.0.0.1",
|
|
13
|
+
languages: {},
|
|
11
14
|
port: 4444}.freeze
|
|
12
|
-
SUPPORTED_TILT_EXT = [".erb", ".md", ".markdown", ".mkd"]
|
|
13
|
-
EXT_MAP = {".md" => ".html", ".mkd" => ".html", ".markdown" => ".html", "" => ".html"}
|
|
15
|
+
SUPPORTED_TILT_EXT = [".erb", ".md", ".markdown", ".mkd", ".html"]
|
|
16
|
+
EXT_MAP = {".md" => ".html", ".mkd" => ".html", ".markdown" => ".html", ".html" => ".html", "" => ".html"}
|
|
14
17
|
def initialize(config)
|
|
15
18
|
@config = DEFAULT_CONFIG.merge(YAML.safe_load(config, symbolize_names: true) || {})
|
|
19
|
+
@config[:default_language] = @config[:default_language].to_sym
|
|
16
20
|
@config[:root_dir] ||= Dir.pwd
|
|
17
21
|
@config[:excludes] ||= []
|
|
22
|
+
@lang_router = LanguagePathRouter.new(
|
|
23
|
+
default_language: default_language,
|
|
24
|
+
languages: languages.keys
|
|
25
|
+
)
|
|
18
26
|
collect_files
|
|
19
27
|
end
|
|
20
28
|
|
|
21
29
|
def [] key
|
|
22
|
-
if key == :lang
|
|
23
|
-
key = :default_language
|
|
24
|
-
end
|
|
25
30
|
@config[key]
|
|
26
31
|
end
|
|
27
32
|
|
|
28
|
-
def
|
|
33
|
+
def default_language
|
|
34
|
+
@config[:default_language]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def languages
|
|
38
|
+
@config[:languages]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def ext_to_process_with_tilt? ext
|
|
29
42
|
SUPPORTED_TILT_EXT.include? ext
|
|
30
43
|
end
|
|
31
44
|
|
|
32
|
-
def
|
|
33
|
-
|
|
45
|
+
def process_extensions(path)
|
|
46
|
+
path = path.dup
|
|
47
|
+
last_ext = nil
|
|
48
|
+
while ext_to_process_with_tilt?(ext = File.extname(path))
|
|
49
|
+
yield(path, ext) if block_given?
|
|
50
|
+
path.delete_suffix!(ext)
|
|
51
|
+
last_ext = ext
|
|
52
|
+
end
|
|
53
|
+
ext.empty? ? path + result_ext_for(last_ext) : path
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def output_path_for path
|
|
57
|
+
process_extensions path
|
|
34
58
|
end
|
|
35
59
|
|
|
36
60
|
def build
|
|
37
|
-
dest_dir = File.join(@file_handler.root_dir, @config[:destination])
|
|
38
61
|
FileUtils.rm_rf(dest_dir)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
rendered, path = Context.new(page, self).render
|
|
43
|
-
dest_path = File.join(dest_dir, path)
|
|
44
|
-
FileUtils.mkdir_p(File.dirname(dest_path))
|
|
45
|
-
File.write(dest_path, rendered)
|
|
62
|
+
entries.each do |name, entry|
|
|
63
|
+
puts "building #{name}..."
|
|
64
|
+
render_to_dest entry
|
|
46
65
|
end
|
|
47
66
|
puts "done."
|
|
48
67
|
end
|
|
@@ -52,35 +71,100 @@ module Isola
|
|
|
52
71
|
build
|
|
53
72
|
end
|
|
54
73
|
|
|
74
|
+
def url_path_for(path)
|
|
75
|
+
# will support base_url for the future.
|
|
76
|
+
File.join("/", path)
|
|
77
|
+
end
|
|
78
|
+
|
|
55
79
|
def ignore?(path)
|
|
56
80
|
@file_handler.ignore?(path)
|
|
57
81
|
end
|
|
58
82
|
|
|
59
|
-
def layout name
|
|
60
|
-
|
|
83
|
+
def layout name, lang: nil
|
|
84
|
+
find_entry(name, @parsed_layouts, @file_handler.layouts, lang: lang)
|
|
61
85
|
end
|
|
62
86
|
|
|
63
|
-
def include name
|
|
64
|
-
|
|
87
|
+
def include name, lang: nil
|
|
88
|
+
find_entry(name, @parsed_includes, @file_handler.includes, lang: lang)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def entry name
|
|
92
|
+
find_entry(name, @parsed_entries, @file_handler.entries)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def entries
|
|
96
|
+
Enumerator.new do |yielder|
|
|
97
|
+
@file_handler.entries.each_key do |name|
|
|
98
|
+
yielder.yield name, entry(name)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
65
101
|
end
|
|
66
102
|
|
|
67
103
|
private
|
|
68
104
|
|
|
105
|
+
def dest_dir
|
|
106
|
+
File.join(@file_handler.root_dir, @config[:destination])
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def render_to_dest entry
|
|
110
|
+
if entry.instance_of? Source
|
|
111
|
+
rendered, path = Context.new(entry, self, languages: languages).render
|
|
112
|
+
dest_path = File.join(dest_dir, path)
|
|
113
|
+
FileUtils.mkdir_p(File.dirname(dest_path))
|
|
114
|
+
File.write(dest_path, rendered)
|
|
115
|
+
elsif entry.instance_of? StaticFile
|
|
116
|
+
path = entry.path
|
|
117
|
+
src_path = File.join(config[:root_dir], path)
|
|
118
|
+
dest_path = File.join(dest_dir, path)
|
|
119
|
+
FileUtils.mkdir_p(File.dirname(dest_path))
|
|
120
|
+
FileUtils.copy(src_path, dest_path)
|
|
121
|
+
else
|
|
122
|
+
raise "can't render class #{entry.class}"
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def result_ext_for ext
|
|
127
|
+
return "" if ext.nil?
|
|
128
|
+
EXT_MAP[ext]
|
|
129
|
+
end
|
|
130
|
+
|
|
69
131
|
def collect_files
|
|
70
|
-
@file_handler = FileHandler.new(config[:root_dir], excludes: @config[:excludes])
|
|
132
|
+
@file_handler = FileHandler.new(config[:root_dir], output_path_func: method(:output_path_for), excludes: @config[:excludes])
|
|
71
133
|
@parsed_layouts = {}
|
|
72
134
|
@parsed_includes = {}
|
|
135
|
+
@parsed_entries = {}
|
|
73
136
|
end
|
|
74
137
|
|
|
75
|
-
def
|
|
76
|
-
|
|
138
|
+
def find_entry(name, cache, store, lang: nil)
|
|
139
|
+
resolved = resolve_localized(name, store, lang)
|
|
140
|
+
lang = @lang_router.language_for(resolved)
|
|
141
|
+
cache[resolved] ||=
|
|
77
142
|
begin
|
|
78
|
-
p = store[
|
|
143
|
+
p = store[resolved]
|
|
79
144
|
return nil unless p
|
|
80
|
-
|
|
145
|
+
if ext_to_process_with_tilt?(File.extname(p))
|
|
146
|
+
translations = translations_for(resolved, store)
|
|
147
|
+
Source.new(p, read_in_site(p), lang: lang, translations: translations)
|
|
148
|
+
else
|
|
149
|
+
StaticFile.new(p)
|
|
150
|
+
end
|
|
81
151
|
end
|
|
82
152
|
end
|
|
83
153
|
|
|
154
|
+
def resolve_localized(name, store, lang)
|
|
155
|
+
return name unless lang && @lang_router.language_for(name) != lang
|
|
156
|
+
localized = @lang_router.localized_path(name, lang)
|
|
157
|
+
store[localized] ? localized : name
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def translations_for(path, store)
|
|
161
|
+
@lang_router.candidate_paths(path).select do |_, candidate|
|
|
162
|
+
store.key?(candidate)
|
|
163
|
+
end.transform_values do |candidate|
|
|
164
|
+
url_path_for(candidate)
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
84
168
|
def read_in_site(p)
|
|
85
169
|
File.read(File.join(config[:root_dir], p))
|
|
86
170
|
end
|
data/lib/isola/source.rb
CHANGED
|
@@ -3,13 +3,15 @@ require "yaml"
|
|
|
3
3
|
module Isola
|
|
4
4
|
class Source
|
|
5
5
|
attr_reader :filepath, :meta, :content
|
|
6
|
-
def initialize filepath, text
|
|
6
|
+
def initialize filepath, text, lang:, translations: {}
|
|
7
7
|
@filepath = filepath
|
|
8
8
|
@meta, @content = if (m = text.match(/\A---\s*\n(.+?)^---\s*\n(.*)\z/m))
|
|
9
|
-
[YAML.safe_load(m[1], symbolize_names: true), m[2]]
|
|
9
|
+
[YAML.safe_load(m[1], symbolize_names: true) || {}, m[2]]
|
|
10
10
|
else
|
|
11
11
|
[{}, text]
|
|
12
12
|
end
|
|
13
|
+
@meta[:lang] = lang
|
|
14
|
+
@meta[:translations] = translations
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
def [] key
|
|
@@ -17,20 +19,11 @@ module Isola
|
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
def render(context, site, params = {})
|
|
20
|
-
path = @filepath.dup
|
|
21
22
|
rendered = @content.dup
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
rendered = Tilt.new(path) { rendered }.render(context, params)
|
|
25
|
-
path.delete_suffix! ext
|
|
26
|
-
last_ext = ext
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
if ext.empty?
|
|
30
|
-
[rendered, path + site.result_ext_for(last_ext)]
|
|
31
|
-
else
|
|
32
|
-
[rendered, path]
|
|
23
|
+
output_path = site.process_extensions(@filepath) do |current_path, _ext|
|
|
24
|
+
rendered = Tilt.new(current_path) { rendered }.render(context, params)
|
|
33
25
|
end
|
|
26
|
+
[rendered, output_path]
|
|
34
27
|
end
|
|
35
28
|
end
|
|
36
29
|
end
|
data/lib/isola/version.rb
CHANGED
data/lib/isola.rb
CHANGED
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative "isola/version"
|
|
4
4
|
require_relative "isola/site"
|
|
5
|
+
require_relative "isola/language_path_router"
|
|
5
6
|
require_relative "isola/file_handler"
|
|
6
7
|
require_relative "isola/source"
|
|
8
|
+
require_relative "isola/static_file"
|
|
7
9
|
require_relative "isola/context"
|
|
8
10
|
require_relative "isola/watcher"
|
|
9
11
|
require_relative "isola/dev_server"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: isola
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Satoshi Kojima
|
|
@@ -87,6 +87,7 @@ executables:
|
|
|
87
87
|
extensions: []
|
|
88
88
|
extra_rdoc_files: []
|
|
89
89
|
files:
|
|
90
|
+
- ".rubocop.yml"
|
|
90
91
|
- LICENSE
|
|
91
92
|
- README.md
|
|
92
93
|
- Rakefile
|
|
@@ -97,8 +98,10 @@ files:
|
|
|
97
98
|
- lib/isola/context.rb
|
|
98
99
|
- lib/isola/dev_server.rb
|
|
99
100
|
- lib/isola/file_handler.rb
|
|
101
|
+
- lib/isola/language_path_router.rb
|
|
100
102
|
- lib/isola/site.rb
|
|
101
103
|
- lib/isola/source.rb
|
|
104
|
+
- lib/isola/static_file.rb
|
|
102
105
|
- lib/isola/version.rb
|
|
103
106
|
- lib/isola/watcher.rb
|
|
104
107
|
homepage: https://github.com/skoji/isola
|