Class: Archival::Builder

Inherits:
Object
  • Object
show all
Defined in:
lib/archival/builder.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config, *_args) ⇒ Builder

Returns a new instance of Builder.



19
20
21
22
23
# File 'lib/archival/builder.rb', line 19

def initialize(config, *_args)
  @config = config
  refresh_config
  Asset.helper_port = @config.helper_port
end

Instance Attribute Details

#page_templatesObject (readonly)

Returns the value of attribute page_templates.



17
18
19
# File 'lib/archival/builder.rb', line 17

def page_templates
  @page_templates
end

Instance Method Details

#do_update_pages(dir, prefix = nil) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/archival/builder.rb', line 99

def do_update_pages(dir, prefix = nil)
  add_prefix = lambda { |entry|
    prefix ? File.join(prefix, entry) : entry
  }
  Dir.foreach(dir) do |entry|
    if File.directory? entry
      unless [
        '.', '..'
      ].include?(entry)
        update_pages(File.join(dir, entry),
                     add_prefix(entry))
      end
    elsif File.file? File.join(dir, entry)
      page_name = File.basename(entry, '.liquid')
      template_file = add_prefix.call(page_name)
      if dynamic? entry
        @dynamic_templates[template_file] = template_for_page(template_file)
      elsif entry.end_with?('.liquid') && !(entry.start_with? '_')
        @page_templates[template_file] =
          template_for_page(template_file)
      end
    end
  end
end

#dynamic?(file) ⇒ Boolean

Returns:

  • (Boolean)


89
90
91
# File 'lib/archival/builder.rb', line 89

def dynamic?(file)
  @dynamic_types.include? File.basename(file, '.liquid')
end

#full_rebuildObject



52
53
54
55
# File 'lib/archival/builder.rb', line 52

def full_rebuild
  Layout.reset_cache
  refresh_config
end

#objects_dirObject



29
30
31
# File 'lib/archival/builder.rb', line 29

def objects_dir
  File.join(@config.root, @config.objects_dir)
end

#objects_for_template(template_path) ⇒ Object



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/archival/builder.rb', line 144

def objects_for_template(template_path)
  objects = {}
  @object_types.each do |type, definition|
    objects[type] = {}
    is_dynamic = @dynamic_types.include? type
    read_objects type do |name, object|
      objects[type][name] = @parser.parse_object(
        object, definition, template_path
      )
      if is_dynamic
        path = path_for_template(name, type)
        objects[type][name]['path'] =
          path.relative_path_from(File.dirname(template_path)).to_s
      end
    end
    objects[type] = sort_objects(objects[type])
  end
  objects
end

#pages_dirObject



25
26
27
# File 'lib/archival/builder.rb', line 25

def pages_dir
  File.join(@config.root, @config.pages_dir)
end

#path_for_template(name, type) ⇒ Object



140
141
142
# File 'lib/archival/builder.rb', line 140

def path_for_template(name, type)
  Pathname.new(File.join(pages_dir, type, "#{name}.html"))
end

#read_objects(type) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/archival/builder.rb', line 124

def read_objects(type)
  obj_dir = File.join(objects_dir, type)
  return unless File.directory? obj_dir

  Dir.foreach(obj_dir) do |file|
    if file.end_with? '.toml'
      object = Tomlrb.load_file(File.join(
                                  obj_dir, file
                                ))
      object[:name] =
        File.basename(file, '.toml')
      yield object[:name], object
    end
  end
end

#refresh_configObject



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/archival/builder.rb', line 33

def refresh_config
  @file_system = Liquid::LocalFileSystem.new(
    pages_dir, '%s.liquid'
  )
  @object_types = {}
  @page_templates = {}
  @dynamic_types = Set.new
  @dynamic_templates = {}
  @parser = Archival::Parser.new(pages_dir)

  Liquid::Template.file_system = Liquid::LocalFileSystem.new(
    pages_dir, '_%s.liquid'
  )

  @objects_definition_file = File.join(@config.root, 'objects.toml')

  update_pages
end

#render(page) ⇒ Object



180
181
182
183
184
185
186
187
# File 'lib/archival/builder.rb', line 180

def render(page)
  dir = File.join(pages_dir, File.dirname(page))
  template = @page_templates[page]
  template_path = File.join(dir, page)
  parsed_objects = objects_for_template(template_path)
  template.render('objects' => parsed_objects,
                  'template_path' => template_path)
end

#render_dynamic(type, name) ⇒ Object



189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/archival/builder.rb', line 189

def render_dynamic(type, name)
  dir = File.join(pages_dir, type)
  template = @dynamic_templates[type]
  template_path = File.join(dir, name)
  parsed_objects = objects_for_template(template_path)
  obj = parsed_objects[type][name]
  vars = {}
         .merge(
           'objects' => parsed_objects,
           'template_path' => template_path
         )
         .merge({ type => obj })
  template.render(vars)
end

#sort_objects(objects) ⇒ Object



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/archival/builder.rb', line 164

def sort_objects(objects)
  # Sort by either 'order' key or object name, depending on what is
  # available.
  sorted_by_keys = objects.sort_by do |name, obj|
    obj.key?('order') ? obj['order'].to_s : name
  end
  sorted_objects = Archival::TemplateArray.new
  sorted_by_keys.each do |d|
    raise DuplicateKeyError if sorted_objects.key?(d[0])

    sorted_objects.push(d[1])
    sorted_objects[d[0]] = d[1]
  end
  sorted_objects
end

#template_for_page(template_file) ⇒ Object



93
94
95
96
97
# File 'lib/archival/builder.rb', line 93

def template_for_page(template_file)
  content = @file_system.read_template_file(template_file)
  content += dev_mode_content if @config.dev_mode
  Liquid::Template.parse(content)
end

#update_assets(changes) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/archival/builder.rb', line 76

def update_assets(changes)
  changes.each do |change|
    asset_path = File.join(@config.build_dir, change.path)
    case change.type
    when :removed
      FileUtils.rm_rf asset_path
    else
      puts change.path
      FileUtils.copy_entry File.join(@config.root, change.path), asset_path
    end
  end
end

#update_objects(_updated_objects = nil) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/archival/builder.rb', line 57

def update_objects(_updated_objects = nil)
  @object_types = {}
  if File.file? @objects_definition_file
    @object_types = Tomlrb.load_file(@objects_definition_file)
  end
  @dynamic_types = Set.new
  @object_types.each do |_name, definition|
    is_template = definition.key? 'template'
    @dynamic_types << definition['template'] if is_template
  end
  # TODO: remove deleted dynamic pages
end

#update_pages(_updated_pages = nil, _updated_objects = nil) ⇒ Object



70
71
72
73
74
# File 'lib/archival/builder.rb', line 70

def update_pages(_updated_pages = nil, _updated_objects = nil)
  update_objects
  # TODO: remove deleted pages
  do_update_pages(pages_dir)
end

#write_allObject



204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/archival/builder.rb', line 204

def write_all
  Dir.mkdir(@config.build_dir) unless File.exist? @config.build_dir
  @page_templates.each_key do |template|
    out_dir = File.join(@config.build_dir,
                        File.dirname(template))
    Dir.mkdir(out_dir) unless File.exist? out_dir
    out_path = File.join(out_dir, "#{template}.html")
    File.open(out_path, 'w+') do |file|
      file.write(render(template))
    end
  end
  @dynamic_types.each do |type|
    out_dir = File.join(@config.build_dir, type)
    Dir.mkdir(out_dir) unless File.exist? out_dir
    read_objects(type) do |name|
      out_path = File.join(out_dir, "#{name}.html")
      File.open(out_path, 'w+') do |file|
        file.write(render_dynamic(type, name))
      end
    end
  end

  # in production (or init), also copy all assets to the dist folder.
  # in dev, they will be copied as they change.
  @config.assets_dirs.each do |asset_dir|
    asset_path = File.join(@config.build_dir, asset_dir)
    next if @config.dev_mode && File.exist?(asset_path)

    source_path = File.join(@config.root, asset_dir)
    next unless File.exist?(source_path)

    FileUtils.copy_entry source_path, asset_path
  end

  copy_static
end