ichiban 1.0.0 → 1.0.6
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.
- data/bin/ichiban +9 -0
- data/empty_project/Capfile +19 -0
- data/empty_project/assets/css/screen.scss +1 -0
- data/empty_project/assets/js/interaction.js +1 -0
- data/empty_project/assets/misc/readme.txt +6 -0
- data/empty_project/compiled/css/screen.css +1 -0
- data/empty_project/compiled/index.html +12 -0
- data/empty_project/compiled/js/interaction.js +1 -0
- data/empty_project/config.rb +3 -0
- data/empty_project/data/readme.txt +2 -0
- data/empty_project/helpers/readme.txt +10 -0
- data/empty_project/html/index.html +3 -0
- data/empty_project/layouts/default.html +12 -0
- data/empty_project/models/readme.txt +3 -0
- data/empty_project/scripts/readme.txt +6 -0
- data/empty_project/webserver/htaccess.txt +24 -0
- data/lib/ichiban/asset_compiler.rb +21 -0
- data/lib/ichiban/bundle.rb +7 -0
- data/lib/ichiban/command.rb +13 -3
- data/lib/ichiban/config.rb +2 -2
- data/lib/ichiban/deleter.rb +4 -7
- data/lib/ichiban/dependencies.rb +28 -7
- data/lib/ichiban/file.rb +122 -17
- data/lib/ichiban/helpers.rb +16 -47
- data/lib/ichiban/html_compiler.rb +62 -12
- data/lib/ichiban/loader.rb +53 -0
- data/lib/ichiban/logger.rb +37 -3
- data/lib/ichiban/markdown.rb +11 -2
- data/lib/ichiban/nav_helper.rb +175 -0
- data/lib/ichiban/project_generator.rb +16 -0
- data/lib/ichiban/scripts.rb +91 -0
- data/lib/ichiban/watcher.rb +36 -19
- data/lib/ichiban.rb +16 -4
- metadata +54 -4
data/bin/ichiban
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
load 'deploy'
|
2
|
+
|
3
|
+
set :scm, :git # Or: `accurev`, `bzr`, `cvs`, `darcs`, `git`, `mercurial`, `perforce`, `subversion` or `none`
|
4
|
+
set :repository, 'ssh://user@example.com/my_site.git'
|
5
|
+
set :branch, 'master'
|
6
|
+
set :keep_releases, 2
|
7
|
+
set :deploy_via, :remote_cache
|
8
|
+
|
9
|
+
role :web, 'example.com'
|
10
|
+
set :user, 'username'
|
11
|
+
set :use_sudo, false
|
12
|
+
set :deploy_to, '/home/username/my_site'
|
13
|
+
|
14
|
+
namespace :deploy do
|
15
|
+
task(:restart) {}
|
16
|
+
end
|
17
|
+
|
18
|
+
set :keep_releases, 2
|
19
|
+
after "deploy:update", "deploy:cleanup"
|
@@ -0,0 +1 @@
|
|
1
|
+
body {font-family: sans-serif;}
|
@@ -0,0 +1 @@
|
|
1
|
+
// Nothing here yet. This JS file is referenced from the default layout.
|
@@ -0,0 +1,6 @@
|
|
1
|
+
Put PDFs, PPTs, and whatever other miscellaneous asset files here. Paths in this folder map to paths
|
2
|
+
in the compiled folder. For example, assets/about_us.pdf would be copied to compiled/about_us.pdf.
|
3
|
+
|
4
|
+
Remember that everything you put here will be checked into git. If you're deploying with Capistrano,
|
5
|
+
a large repository will slow down your deployment. For this reason, and for better download times
|
6
|
+
for your users, it's often better to host your large asset files on a CDN instead.
|
@@ -0,0 +1 @@
|
|
1
|
+
body {font-family: sans-serif;}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Home - Site Name Here</title>
|
5
|
+
<link rel="stylesheet" type="text/css" href="/css/screen.css"/>
|
6
|
+
<script type="text/javascript" src="/js/interaction.js"></script>
|
7
|
+
</head>
|
8
|
+
|
9
|
+
<body>
|
10
|
+
<h1>Home</h1>
|
11
|
+
</body>
|
12
|
+
</html>
|
@@ -0,0 +1 @@
|
|
1
|
+
// Nothing here yet. This JS file is referenced from the default layout.
|
@@ -0,0 +1,6 @@
|
|
1
|
+
This folder is for scripts that generate pages.
|
2
|
+
|
3
|
+
If you want some auto-generated code *within a single page*, it's easy: Just use some <% %> tags.
|
4
|
+
But suppose you have an XML file describing every employee in your company, and you want an
|
5
|
+
*individual* page for each one. That's where this folder coms in. You need to create a script
|
6
|
+
that generates each page based on a template. See the documentation for more details.
|
@@ -0,0 +1,24 @@
|
|
1
|
+
RewriteEngine On
|
2
|
+
|
3
|
+
# Force the trailing slash for all pages unless they end in .html
|
4
|
+
RewriteCond %{REQUEST_FILENAME} !-f
|
5
|
+
RewriteCond %{REQUEST_FILENAME} !-d
|
6
|
+
# Skipping pages with the .html extension is necessary to avoid an infinite chain of .html. See the note at the bottom.
|
7
|
+
RewriteCond %{REQUEST_URI} !\.html$
|
8
|
+
RewriteRule ^(.*[^/])$ /$1/ [R=301,L]
|
9
|
+
|
10
|
+
RewriteCond %{REQUEST_FILENAME} !-f
|
11
|
+
RewriteCond %{REQUEST_FILENAME} !-d
|
12
|
+
# If the HTML file doesn't exist don't attempt to rewrite, or we'll get an infinite loop
|
13
|
+
RewriteCond %{REQUEST_FILENAME}.html -f
|
14
|
+
# If we've already tried appending HTML and the file still doesn't exist, don't do it again. See the note at the bottom.
|
15
|
+
RewriteCond %{REQUEST_URI} !\.html$
|
16
|
+
RewriteRule ^(.*)/$ $1.html
|
17
|
+
|
18
|
+
ErrorDocument 404 /404.html
|
19
|
+
ErrorDocument 422 /422.html
|
20
|
+
ErrorDocument 500 /500.html
|
21
|
+
|
22
|
+
# Note on infinite .html appending loops: We have to take pains to ensure that if a certain file, say foo.html, exists,
|
23
|
+
# then a path like /foo/bar won't get .html appended an infinite number of times. This can happen because %{REQUEST_FILENAME}
|
24
|
+
# would match /foo/bar/ to foo.html. Our redirect to force trailing slashes then sends us through an infinite loop.
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Ichiban
|
2
|
+
class AssetCompiler
|
3
|
+
def initialize(file)
|
4
|
+
@file = file
|
5
|
+
end
|
6
|
+
|
7
|
+
def compile
|
8
|
+
dir = File.dirname @file.dest
|
9
|
+
unless File.directory? dir
|
10
|
+
FileUtils.mkdir_p dir
|
11
|
+
end
|
12
|
+
case @file
|
13
|
+
when Ichiban::SCSSFile
|
14
|
+
Sass.compile_file @file.abs, @file.dest
|
15
|
+
else
|
16
|
+
FileUtils.cp @file.abs, @file.dest
|
17
|
+
end
|
18
|
+
Ichiban.logger.compilation(@file.abs, @file.dest)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/ichiban/command.rb
CHANGED
@@ -6,15 +6,25 @@ module Ichiban
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def print_usage
|
9
|
-
puts
|
10
|
-
|
9
|
+
puts(
|
10
|
+
"Usage: ichiban [command]\n" +
|
11
|
+
"Available commands: \n" +
|
12
|
+
" watch\n" +
|
13
|
+
" new [path]"
|
14
|
+
)
|
11
15
|
end
|
12
16
|
|
13
17
|
def run
|
14
|
-
Ichiban.project_root = Dir.getwd
|
15
18
|
case @task
|
16
19
|
when 'watch'
|
20
|
+
Ichiban.project_root = Dir.getwd
|
21
|
+
Ichiban.load_bundle
|
17
22
|
Ichiban::Watcher.new.start
|
23
|
+
when 'new'
|
24
|
+
Ichiban::ProjectGenerator.new(
|
25
|
+
File.expand_path(@args[0])
|
26
|
+
).generate
|
27
|
+
puts "Initialized Ichiban project in #{@args[0]}"
|
18
28
|
else
|
19
29
|
print_usage
|
20
30
|
end
|
data/lib/ichiban/config.rb
CHANGED
@@ -9,8 +9,8 @@ module Ichiban
|
|
9
9
|
attr_writer :relative_url_root
|
10
10
|
|
11
11
|
def self.load_file
|
12
|
-
config_file =
|
13
|
-
raise "#{config_file} must exist" unless
|
12
|
+
config_file = File.join(Ichiban.project_root, 'config.rb')
|
13
|
+
raise "#{config_file} must exist" unless File.exists?(config_file)
|
14
14
|
load config_file
|
15
15
|
end
|
16
16
|
|
data/lib/ichiban/deleter.rb
CHANGED
@@ -2,19 +2,16 @@ module Ichiban
|
|
2
2
|
class Deleter
|
3
3
|
# Deletes a file's associated destination file, if any.
|
4
4
|
def delete_dest(path)
|
5
|
-
file = Ichiban::
|
6
|
-
# file will be nil if the path doesn't map to a known subclass of
|
7
|
-
# even if file is not nil, it may be a kind of
|
5
|
+
file = Ichiban::ProjectFile.from_abs(path)
|
6
|
+
# file will be nil if the path doesn't map to a known subclass of IchibanFile. Furthermore,
|
7
|
+
# even if file is not nil, it may be a kind of IchibanFile that does not have a destination.
|
8
8
|
if file and file.has_dest?
|
9
9
|
dest = file.dest
|
10
10
|
else
|
11
11
|
dest = nil
|
12
12
|
end
|
13
|
-
if dest and
|
14
|
-
puts 'yep'
|
13
|
+
if dest and File.exists?(dest)
|
15
14
|
FileUtils.rm(dest)
|
16
|
-
else
|
17
|
-
puts 'nope'
|
18
15
|
end
|
19
16
|
|
20
17
|
# Log the deletion(s)
|
data/lib/ichiban/dependencies.rb
CHANGED
@@ -2,32 +2,53 @@ module Ichiban
|
|
2
2
|
module Dependencies
|
3
3
|
@graphs = {}
|
4
4
|
|
5
|
-
#
|
5
|
+
# Does not delete the files. Just clears the graphs from memory. This gets called whenever
|
6
|
+
# Ichiban.project_root is changed.
|
7
|
+
def self.clear_graphs
|
8
|
+
@graphs = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.delete_dep(graph_file_path, dep)
|
12
|
+
ensure_graph_initialized(graph_file_path)
|
13
|
+
graph = @graphs[graph_file_path]
|
14
|
+
graph.each do |ind, deps|
|
15
|
+
deps.delete dep
|
16
|
+
end
|
17
|
+
save_graph_file(graph_file_path, graph)
|
18
|
+
end
|
19
|
+
|
20
|
+
# graph_file_path is a relative path
|
6
21
|
def self.graph(graph_file_path)
|
7
22
|
ensure_graph_initialized(graph_file_path)
|
8
23
|
@graphs[graph_file_path]
|
9
24
|
end
|
10
25
|
|
26
|
+
# graph_file_path is a relative path
|
11
27
|
def self.ensure_graph_initialized(graph_file_path)
|
12
28
|
unless @graphs[graph_file_path]
|
13
|
-
|
14
|
-
|
29
|
+
abs = File.join(Ichiban.project_root, graph_file_path)
|
30
|
+
if File.exists?(abs)
|
31
|
+
@graphs[graph_file_path] = JSON.parse(File.read(abs))
|
15
32
|
else
|
16
33
|
@graphs[graph_file_path] = {}
|
17
34
|
end
|
18
35
|
end
|
19
36
|
end
|
20
37
|
|
38
|
+
def self.save_graph_file(graph_file_path, graph)
|
39
|
+
File.open(File.join(Ichiban.project_root, graph_file_path), 'w') do |f|
|
40
|
+
f << JSON.generate(graph)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
21
44
|
# Loads the graph from disk if it's not already in memory. Updates the graph. Writes the new
|
22
|
-
# graph to disk. graph_file_path is
|
45
|
+
# graph to disk. graph_file_path is a relative path.
|
23
46
|
def self.update(graph_file_path, ind, dep)
|
24
47
|
ensure_graph_initialized(graph_file_path)
|
25
48
|
graph = @graphs[graph_file_path]
|
26
49
|
graph[ind] ||= []
|
27
50
|
graph[ind] << dep unless graph[ind].include?(dep)
|
28
|
-
|
29
|
-
f << JSON.generate(graph)
|
30
|
-
end
|
51
|
+
save_graph_file(graph_file_path, graph)
|
31
52
|
end
|
32
53
|
end
|
33
54
|
end
|
data/lib/ichiban/file.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
module Ichiban
|
2
|
-
class
|
2
|
+
class ProjectFile
|
3
3
|
attr_reader :abs
|
4
4
|
|
5
5
|
# Returns an absolute path in the compiled directory
|
6
6
|
def dest
|
7
|
-
|
7
|
+
File.join(Ichiban.project_root, 'compiled', dest_rel_to_compiled)
|
8
8
|
end
|
9
9
|
|
10
10
|
# Returns a new instance based on an absolute path. Will automatically pick the right subclass.
|
@@ -12,10 +12,14 @@ module Ichiban
|
|
12
12
|
def self.from_abs(abs)
|
13
13
|
rel = abs.slice(Ichiban.project_root.length..-1) # Relative to project root
|
14
14
|
rel.sub!(/^\//, '') # Remove leading slash
|
15
|
-
if rel.start_with?('html') and rel.end_with?('.html')
|
16
|
-
|
15
|
+
if rel.start_with?('html') and (rel.end_with?('.html') or rel.end_with?('.md') or rel.end_with?('.markdown'))
|
16
|
+
if File.basename(rel).start_with?('_')
|
17
|
+
Ichiban::PartialHTMLFile.new(rel)
|
18
|
+
else
|
19
|
+
Ichiban::HTMLFile.new(rel)
|
20
|
+
end
|
17
21
|
elsif rel.start_with?('layouts') and rel.end_with?('.html')
|
18
|
-
Ichiban::
|
22
|
+
Ichiban::LayoutFile.new(rel)
|
19
23
|
elsif rel.start_with?('assets/js')
|
20
24
|
Ichiban::JSFile.new(rel)
|
21
25
|
elsif rel.start_with?('assets/css') and rel.end_with?('.css')
|
@@ -34,6 +38,8 @@ module Ichiban
|
|
34
38
|
Ichiban::ScriptFile.new(rel)
|
35
39
|
elsif rel.start_with?('helpers')
|
36
40
|
Ichiban::HelperFile.new(rel)
|
41
|
+
elsif rel == 'webserver/htaccess.txt'
|
42
|
+
Ichiban::HtaccessFile.new(rel)
|
37
43
|
else
|
38
44
|
nil
|
39
45
|
end
|
@@ -45,16 +51,18 @@ module Ichiban
|
|
45
51
|
|
46
52
|
def initialize(rel)
|
47
53
|
@rel = rel
|
48
|
-
@abs =
|
54
|
+
@abs = File.join(Ichiban.project_root, rel)
|
49
55
|
end
|
50
56
|
|
57
|
+
attr_reader :rel
|
58
|
+
|
51
59
|
# Returns a new path where the old extension is replaced with new_ext
|
52
60
|
def replace_ext(path, new_ext)
|
53
61
|
path.sub(/\..+$/, '.' + new_ext)
|
54
62
|
end
|
55
63
|
end
|
56
64
|
|
57
|
-
class HTMLFile <
|
65
|
+
class HTMLFile < ProjectFile
|
58
66
|
def dest_rel_to_compiled
|
59
67
|
d = @rel.slice('html/'.length..-1)
|
60
68
|
(d.end_with?('.markdown') or d.end_with?('.md')) ? replace_ext(d, 'html') : d
|
@@ -63,53 +71,150 @@ module Ichiban
|
|
63
71
|
def update
|
64
72
|
Ichiban::HTMLCompiler.new(self).compile
|
65
73
|
end
|
74
|
+
|
75
|
+
def web_path
|
76
|
+
d = dest_rel_to_compiled
|
77
|
+
'/' + File.basename(d, File.extname(d)) + '/'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class PartialHTMLFile < ProjectFile
|
82
|
+
# Returns something like 'foo/bar'
|
83
|
+
def partial_name
|
84
|
+
File.basename(
|
85
|
+
@abs.slice(Ichiban.project_root.length + 1..-1),
|
86
|
+
File.extname(@abs)
|
87
|
+
)
|
88
|
+
end
|
89
|
+
|
90
|
+
def update
|
91
|
+
# Normal HTML files that depend on this partial
|
92
|
+
if deps = Ichiban::Dependencies.graph('.partial_dependencies.json')[partial_name]
|
93
|
+
deps.each do |dep|
|
94
|
+
# dep will be a path relative to the html directory. It looks like this: 'folder/file.html'
|
95
|
+
Ichiban::HTMLFile.new(File.join('html', dep)).update
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Scripts that depend on this partial
|
100
|
+
dep_key = "html/#{partial_name}.html"
|
101
|
+
if deps = Ichiban::Dependencies.graph('.script_dependencies.json')[dep_key]
|
102
|
+
deps.each do |dep|
|
103
|
+
# dep will be a path relative to the html directory. It looks like this: 'folder/file.html'
|
104
|
+
script_path = File.join(Ichiban.project_root, dep)
|
105
|
+
Ichiban.logger.script_run(@abs, script_path)
|
106
|
+
script = Ichiban::Script.new(script_path).run
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
66
110
|
end
|
67
111
|
|
68
|
-
class LayoutFile <
|
112
|
+
class LayoutFile < ProjectFile
|
113
|
+
def layout_name
|
114
|
+
File.basename(@abs, File.extname(@abs))
|
115
|
+
end
|
116
|
+
|
117
|
+
def update
|
118
|
+
Ichiban.logger.layout(@abs)
|
119
|
+
if deps = Ichiban::Dependencies.graph('.layout_dependencies.json')[layout_name]
|
120
|
+
deps.each do |dep|
|
121
|
+
# dep is a path relative to the project root
|
122
|
+
if File.exists?(File.join(Ichiban.project_root, dep))
|
123
|
+
Ichiban::HTMLFile.new(dep).update
|
124
|
+
else
|
125
|
+
Dependencies.delete_dep('.layout_dependencies.json', dep)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
69
130
|
end
|
70
131
|
|
71
|
-
class JSFile <
|
132
|
+
class JSFile < ProjectFile
|
72
133
|
def dest_rel_to_compiled
|
73
134
|
File.join('js', @rel.slice('assets/js/'.length..-1))
|
74
135
|
end
|
136
|
+
|
137
|
+
def update
|
138
|
+
Ichiban::AssetCompiler.new(self).compile
|
139
|
+
end
|
75
140
|
end
|
76
141
|
|
77
|
-
class CSSFile <
|
142
|
+
class CSSFile < ProjectFile
|
78
143
|
def dest_rel_to_compiled
|
79
144
|
File.join('css', @rel.slice('assets/css/'.length..-1))
|
80
145
|
end
|
146
|
+
|
147
|
+
def update
|
148
|
+
Ichiban::AssetCompiler.new(self).compile
|
149
|
+
end
|
81
150
|
end
|
82
151
|
|
83
|
-
class SCSSFile <
|
152
|
+
class SCSSFile < ProjectFile
|
84
153
|
def dest_rel_to_compiled
|
85
154
|
replace_ext(
|
86
155
|
File.join('css', @rel.slice('assets/css/'.length..-1)),
|
87
156
|
'css'
|
88
157
|
)
|
89
158
|
end
|
159
|
+
|
160
|
+
def update
|
161
|
+
Ichiban::AssetCompiler.new(self).compile
|
162
|
+
end
|
90
163
|
end
|
91
164
|
|
92
|
-
class ImageFile <
|
165
|
+
class ImageFile < ProjectFile
|
93
166
|
def dest_rel_to_compiled
|
94
167
|
File.join('img', @rel.slice('assets/img/'.length..-1))
|
95
168
|
end
|
169
|
+
|
170
|
+
def update
|
171
|
+
Ichiban::AssetCompiler.new(self).compile
|
172
|
+
end
|
96
173
|
end
|
97
174
|
|
98
|
-
class MiscAssetFile <
|
175
|
+
class MiscAssetFile < ProjectFile
|
99
176
|
def dest_rel_to_compiled
|
100
177
|
@rel.slice('assets/misc/'.length..-1)
|
101
178
|
end
|
179
|
+
|
180
|
+
def update
|
181
|
+
Ichiban::AssetCompiler.new(self).compile
|
182
|
+
end
|
102
183
|
end
|
103
184
|
|
104
|
-
class
|
185
|
+
class HtaccessFile < ProjectFile
|
186
|
+
def dest_rel_to_compiled
|
187
|
+
'.htaccess'
|
188
|
+
end
|
189
|
+
|
190
|
+
def update
|
191
|
+
Ichiban::AssetCompiler.new(self).compile
|
192
|
+
end
|
105
193
|
end
|
106
194
|
|
107
|
-
class
|
195
|
+
class ModelFile < ProjectFile
|
196
|
+
def update
|
197
|
+
# No-op. The watcher hands the path to each changed model file to the Loader instance.
|
198
|
+
# So we don't have to worry about that here.
|
199
|
+
end
|
108
200
|
end
|
109
201
|
|
110
|
-
class
|
202
|
+
class HelperFile < ProjectFile
|
203
|
+
def update
|
204
|
+
# No-op. The watcher hands the path to each changed model file to the Loader instance.
|
205
|
+
# So we don't have to worry about that here.
|
206
|
+
end
|
111
207
|
end
|
112
208
|
|
113
|
-
class
|
209
|
+
class DataFile < ProjectFile
|
210
|
+
def update
|
211
|
+
Ichiban.script_runner.data_file_changed(@abs)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
class ScriptFile < ProjectFile
|
216
|
+
def update
|
217
|
+
Ichiban.script_runner.script_file_changed(@abs)
|
218
|
+
end
|
114
219
|
end
|
115
220
|
end
|
data/lib/ichiban/helpers.rb
CHANGED
@@ -21,14 +21,14 @@ module Ichiban
|
|
21
21
|
output << tag_attrs(options) << ">#{content}</#{name}>"
|
22
22
|
end
|
23
23
|
|
24
|
-
# Returns the path relative to site root
|
24
|
+
# Returns the path relative to site root. Includes leading and trailing slash.
|
25
25
|
def current_path
|
26
26
|
@_current_path
|
27
27
|
end
|
28
28
|
|
29
29
|
def javascript_include_tag(js_file)
|
30
30
|
js_file = js_file + '.js' unless js_file.end_with?('.js')
|
31
|
-
path = normalize_path(
|
31
|
+
path = normalize_path(File.join('/js', js_file))
|
32
32
|
content_tag 'script', 'type' => 'text/javascript', 'src' => path
|
33
33
|
end
|
34
34
|
|
@@ -62,58 +62,16 @@ module Ichiban
|
|
62
62
|
content_tag 'a', text, options.merge('href' => url)
|
63
63
|
end
|
64
64
|
|
65
|
-
#
|
66
|
-
#
|
67
|
-
# [
|
68
|
-
# ['Link Text', '/path/from/relative/url/root/']
|
69
|
-
# ['Link Text', '/path/from/relative/url/root/', {'id' => 'foo'}]
|
70
|
-
# ]
|
71
|
-
#
|
72
|
-
# You can also do this, as a convenience:
|
73
|
-
#
|
74
|
-
# nav([
|
75
|
-
# ['Link Text', 'path/from/section/root/']
|
76
|
-
# ], :section => 'section-name')
|
77
|
-
#
|
78
|
-
# Which will generate this href:
|
79
|
-
#
|
80
|
-
# /section-name/path/from/section/root/
|
81
|
-
#
|
82
|
-
# If you don't specify a section, and your URLs don't have leading slashes,
|
83
|
-
# the hrefs will use relative URLs.
|
84
|
-
def nav(items, options = {})
|
85
|
-
ul_options = _limit_options(options, %w(id class)) { |key, value| key.to_s.start_with?('data-') }
|
86
|
-
content_tag('ul', ul_options) do
|
87
|
-
items.inject('') do |lis, (text, path, attrs)|
|
88
|
-
if options[:section]
|
89
|
-
path = ::File.join(options[:section], path)
|
90
|
-
end
|
91
|
-
path = normalize_path(path)
|
92
|
-
lis + content_tag('li', (attrs or {})) do
|
93
|
-
if path_with_slashes(current_path) == path_with_slashes(path)
|
94
|
-
content_tag('span', text, 'class' => 'selected')
|
95
|
-
else
|
96
|
-
link_to(text, path)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
# If the path has a trailing slash, it will be made absolute using relative_url_root.
|
65
|
+
# If the path has a leading slash, it will be made absolute using relative_url_root.
|
104
66
|
# Otherwise, it will remain relative.
|
105
67
|
def normalize_path(path)
|
106
68
|
if path.start_with?('/')
|
107
|
-
|
69
|
+
File.join(relative_url_root, path)
|
108
70
|
else
|
109
71
|
path
|
110
72
|
end
|
111
73
|
end
|
112
74
|
|
113
|
-
def page_title(title)
|
114
|
-
@page_title = title
|
115
|
-
end
|
116
|
-
|
117
75
|
# Adds leading and trailing slashes if none are present
|
118
76
|
def path_with_slashes(path)
|
119
77
|
path = '/' + path unless path.start_with?('/')
|
@@ -121,13 +79,24 @@ module Ichiban
|
|
121
79
|
path
|
122
80
|
end
|
123
81
|
|
82
|
+
def partial(path)
|
83
|
+
file = Ichiban::PartialHTMLFile.new(
|
84
|
+
File.join('html', path)
|
85
|
+
)
|
86
|
+
# Record the dependency like this: 'folder/partial-name' => 'folder/included-file.html'
|
87
|
+
Ichiban::Dependencies.update('.partial_dependencies.json', file.partial_name, @_template_path)
|
88
|
+
compiler = Ichiban::HTMLCompiler.new(file)
|
89
|
+
compiler.ivars = to_hash # to_hash is inherited from Erubis::Context. It's a hash of the instance variables.
|
90
|
+
compiler.compile_to_str
|
91
|
+
end
|
92
|
+
|
124
93
|
def relative_url_root
|
125
94
|
Ichiban.config.relative_url_root
|
126
95
|
end
|
127
96
|
|
128
97
|
def stylesheet_link_tag(css_file, media = 'screen')
|
129
98
|
css_file = css_file + '.css' unless css_file.end_with?('.css')
|
130
|
-
href = normalize_path(
|
99
|
+
href = normalize_path(File.join('/css', css_file))
|
131
100
|
tag 'link', 'href' => href, 'type' => 'text/css', 'rel' => 'stylesheet', 'media' => media
|
132
101
|
end
|
133
102
|
|