jekyll-datapage_gen-rocha-patch-001

Created Diff never expires
0 removals
Lines
Total
Removed
Words
Total
Removed
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
211 lines
22 additions
Lines
Total
Added
Words
Total
Added
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
228 lines
# coding: utf-8
# coding: utf-8
# Generate pages from individual records in yml files
# Generate pages from individual records in yml files
# (c) 2014-2020 Adolfo Villafiorita
# (c) 2014-2020 Adolfo Villafiorita
# Distributed under the conditions of the MIT License
# Distributed under the conditions of the MIT License


module Jekyll
module Jekyll


module Sanitizer
module Sanitizer
# strip characters and whitespace to create valid filenames, also lowercase
# strip characters and whitespace to create valid filenames, also lowercase
def sanitize_filename(name)
def sanitize_filename(name)
if(name.is_a? Integer)
if(name.is_a? Integer)
return name.to_s
return name.to_s
end
end
return name.tr(
return name.tr(
"ÀÁÂÃÄÅàáâãäåĀāĂ㥹ÇçĆćĈĉĊċČčÐðĎďĐđÈÉÊËèéêëĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħÌÍÎÏìíîïĨĩĪīĬĭĮįİıĴĵĶķĸĹĺĻļĽľĿŀŁłÑñŃńŅņŇňʼnŊŋÑñÒÓÔÕÖØòóôõöøŌōŎŏŐőŔŕŖŗŘřŚśŜŝŞşŠšſŢţŤťŦŧÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųŴŵÝýÿŶŷŸŹźŻżŽž",
"ÀÁÂÃÄÅàáâãäåĀāĂ㥹ÇçĆćĈĉĊċČčÐðĎďĐđÈÉÊËèéêëĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħÌÍÎÏìíîïĨĩĪīĬĭĮįİıĴĵĶķĸĹĺĻļĽľĿŀŁłÑñŃńŅņŇňʼnŊŋÑñÒÓÔÕÖØòóôõöøŌōŎŏŐőŔŕŖŗŘřŚśŜŝŞşŠšſŢţŤťŦŧÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųŴŵÝýÿŶŷŸŹźŻżŽž",
"AAAAAAaaaaaaAaAaAaCcCcCcCcCcDdDdDdEEEEeeeeEeEeEeEeEeGgGgGgGgHhHhIIIIiiiiIiIiIiIiIiJjKkkLlLlLlLlLlNnNnNnNnnNnNnOOOOOOooooooOoOoOoRrRrRrSsSsSsSssTtTtTtUUUUuuuuUuUuUuUuUuUuWwYyyYyYZzZzZz"
"AAAAAAaaaaaaAaAaAaCcCcCcCcCcDdDdDdEEEEeeeeEeEeEeEeEeGgGgGgGgHhHhIIIIiiiiIiIiIiIiIiJjKkkLlLlLlLlLlNnNnNnNnnNnNnOOOOOOooooooOoOoOoRrRrRrSsSsSsSssTtTtTtUUUUuuuuUuUuUuUuUuUuWwYyyYyYZzZzZz"
).downcase.strip.gsub(' ', '-').gsub(/[^\w.-]/, '')
).downcase.strip.gsub(' ', '-').gsub(/[^\w.-]/, '')
end
end
end
end
# this class is used to tell Jekyll to generate a page
# this class is used to tell Jekyll to generate a page
class DataPage < Page
class DataPage < Page
include Sanitizer
include Sanitizer
# - site and base are copied from other plugins: to be honest, I am not sure what they do
# - site and base are copied from other plugins: to be honest, I am not sure what they do
#
#
# - `index_files` specifies if we want to generate named folders (true) or not (false)
# - `index_files` specifies if we want to generate named folders (true) or not (false)
# - `dir` is the default output directory
# - `dir` is the default output directory
# - `dir_expr` is an expression for generating the output directory
# - `page_data_prefix` is the prefix used to output the page data
# - `page_data_prefix` is the prefix used to output the page data
# - `data` is the data of the record for which we are generating a page
# - `data` is the data of the record for which we are generating a page
# - `name` is the key in `data` which determines the output filename
# - `name` is the key in `data` which determines the output filename
# - `name_expr` is an expression for generating the output filename
# - `name_expr` is an expression for generating the output filename
# - `title` is the key in `data` which determines the page title
# - `title` is the key in `data` which determines the page title
# - `title_expr` is an expression for generating the page title
# - `title_expr` is an expression for generating the page title
# - `template` is the name of the template for generating the page
# - `template` is the name of the template for generating the page
# - `extension` is the extension for the generated file
# - `extension` is the extension for the generated file
def initialize(site, base, index_files, dir, page_data_prefix, data, name, name_expr, title, title_expr, template, extension, debug)
def initialize(site, base, index_files, dir, dir_expr, page_data_prefix, data, name, name_expr, title, title_expr, template, extension, debug)
@site = site
@site = site
@base = base
@base = base
if debug
if debug
puts "debug (datapage-gen) Record read:"
puts "debug (datapage-gen) Record read:"
puts ">> #{data}"
puts ">> #{data}"
puts "debug (datapage-gen) Configuration variables:"
puts "debug (datapage-gen) Configuration variables:"
[:index_files, :dir, :page_data_prefix, :name, :name_expr, :title, :title_expr, :template, :extension].each do |variable|
[:index_files, :dir, :dir_expr, :page_data_prefix, :name, :name_expr, :title, :title_expr, :template, :extension].each do |variable|
puts ">> #{variable}: #{eval(variable.to_s)}"
puts ">> #{variable}: #{eval(variable.to_s)}"
end
end
end
end
# @dir is the directory where we want to output the page
# @dir is the directory where we want to output the page
# @name is the name of the page to generate
# @name is the name of the page to generate
# @name_expr is an expression for generating the name of the page
# @name_expr is an expression for generating the name of the page
#
#
# the value of these variables changes according to whether we
# the value of these variables changes according to whether we
# want to generate named folders or not
# want to generate named folders or not
if name_expr
if name_expr
record = data
record = data
raw_filename = eval(name_expr)
raw_filename = eval(name_expr)
if raw_filename == nil
if raw_filename == nil
puts "error (datapage-gen). name_expr '#{name_expr}' generated an empty value in record #{data}"
puts "error (datapage-gen). name_expr '#{name_expr}' generated an empty value in record #{data}"
return
return
end
end
puts "debug (datapage-gen). using name_expr: '#{raw_filename}' (sanitized) will be used as the filename" if debug
puts "debug (datapage-gen). using name_expr: '#{raw_filename}' (sanitized) will be used as the filename" if debug
else
else
raw_filename = data[name]
raw_filename = data[name]
if raw_filename == nil
if raw_filename == nil
puts "error (datapage-gen). empty value for field '#{name}' in record #{data}"
puts "error (datapage-gen). empty value for field '#{name}' in record #{data}"
return
return
end
end
puts "debug (datapage-gen). using name field: '#{raw_filename}' (sanitized) will be used as the filename" if debug
puts "debug (datapage-gen). using name field: '#{raw_filename}' (sanitized) will be used as the filename" if debug
end
end
if title_expr
if title_expr
record = data
record = data
raw_title = eval(title_expr)
raw_title = eval(title_expr)
if raw_title == nil
if raw_title == nil
puts "error (datapage-gen). title_expr '#{title_expr}' generated an empty value in record #{data}"
puts "error (datapage-gen). title_expr '#{title_expr}' generated an empty value in record #{data}"
return
return
end
end
puts "debug (datapage-gen). using title_expr: '#{raw_title}' will be used the page title" if debug
puts "debug (datapage-gen). using title_expr: '#{raw_title}' will be used the page title" if debug
else
else
raw_title = data[title]
raw_title = data[title]
if raw_title == nil
if raw_title == nil
raw_title = raw_filename # for backwards compatibility
raw_title = raw_filename # for backwards compatibility
puts "debug (datapage-gen). empty title field: falling back to filename for the page title" if debug
puts "debug (datapage-gen). empty title field: falling back to filename for the page title" if debug
end
end
puts "debug (datapage-gen). will use '#{raw_title}' as the page title" if debug
puts "debug (datapage-gen). will use '#{raw_title}' as the page title" if debug
end
end
filename = sanitize_filename(raw_filename).to_s
filename = sanitize_filename(raw_filename).to_s
@dir = dir + (index_files ? "/" + filename + "/" : "")
# Old option, without dir_expr
# @dir = dir + (index_files ? "/" + filename + "/" : "")

if dir_expr
record = data
raw_dir = eval(dir_expr)
if raw_dir == nil
puts "error (datapage-gen). raw_dir '#{raw_dir}' generated an empty value in record #{data}"
return
end
@dir = raw_dir + (index_files ? "/" + filename + "/" : "")
puts "debug (datapage-gen). using raw_dir: '#{raw_dir}' will be used the directory output" if debug
else
@dir = dir + (index_files ? "/" + filename + "/" : "")
end

@name = (index_files ? "index" : filename) + "." + extension.to_s
@name = (index_files ? "index" : filename) + "." + extension.to_s
self.process(@name)
self.process(@name)
if @site.layouts[template].path.end_with? 'html'
if @site.layouts[template].path.end_with? 'html'
@path = @site.layouts[template].path.dup
@path = @site.layouts[template].path.dup
else
else
@path = File.join(@site.layouts[template].path, @site.layouts[template].name)
@path = File.join(@site.layouts[template].path, @site.layouts[template].name)
end
end
base_path = @site.layouts[template].path
base_path = @site.layouts[template].path
base_path.slice! @site.layouts[template].name
base_path.slice! @site.layouts[template].name
self.read_yaml(base_path, @site.layouts[template].name)
self.read_yaml(base_path, @site.layouts[template].name)
self.data['title'] = raw_title
self.data['title'] = raw_title
# add all the information defined in _data for the current record to the
# add all the information defined in _data for the current record to the
# current page (so that we can access it with liquid tags)
# current page (so that we can access it with liquid tags)
if page_data_prefix
if page_data_prefix
self.data[page_data_prefix] = data
self.data[page_data_prefix] = data
else
else
if data.key?('name')
if data.key?('name')
data['_name'] = data['name']
data['_name'] = data['name']
end
end
self.data.merge!(data)
self.data.merge!(data)
end
end
end
end
end
end
class JekyllDatapageGenerator < Generator
class JekyllDatapageGenerator < Generator
safe true
safe true
# the function =generate= loops over the =_config.yml/page_gen=
# the function =generate= loops over the =_config.yml/page_gen=
# specification, determining what sets of pages have to be generated,
# specification, determining what sets of pages have to be generated,
# reading the data for each set and invoking the =DataPage=
# reading the data for each set and invoking the =DataPage=
# constructor for each record found in the data
# constructor for each record found in the data
def generate(site)
def generate(site)
# page_gen-dirs is a global option which determines whether we want to
# page_gen-dirs is a global option which determines whether we want to
# generate index pages (name/index.html) or HTML files (name.html) for
# generate index pages (name/index.html) or HTML files (name.html) for
# all sets
# all sets
index_files = site.config['page_gen-dirs'] == true
index_files = site.config['page_gen-dirs'] == true
# data contains the specification of all the datasets for which we want
# data contains the specification of all the datasets for which we want
# to generate individual pages (look at the README file for its documentation)
# to generate individual pages (look at the README file for its documentation)
data = site.config['page_gen']
data = site.config['page_gen']
if data
if data
data.each do |data_spec|
data.each do |data_spec|
index_files_for_this_data = data_spec['index_files'] != nil ? data_spec['index_files'] : index_files
index_files_for_this_data = data_spec['index_files'] != nil ? data_spec['index_files'] : index_files
template = data_spec['template'] || data_spec['data']
template = data_spec['template'] || data_spec['data']
name = data_spec['name']
name = data_spec['name']
name_expr = data_spec['name_expr']
name_expr = data_spec['name_expr']
title = data_spec['title']
title = data_spec['title']
title_expr = data_spec['title_expr']
title_expr = data_spec['title_expr']
dir = data_spec['dir'] || data_spec['data']
dir = data_spec['dir'] || data_spec['data']
dir_expr = data_spec['dir_expr']
extension = data_spec['extension'] || "html"
extension = data_spec['extension'] || "html"
page_data_prefix = data_spec['page_data_prefix']
page_data_prefix = data_spec['page_data_prefix']
debug = data_spec['debug']
debug = data_spec['debug']
if not site.layouts.key? template
if not site.layouts.key? template
puts "error (datapage-gen). could not find template #{template}. Skipping dataset #{name}."
puts "error (datapage-gen). could not find template #{template}. Skipping dataset #{name}."
else
else
# records is the list of records for which we want to generate
# records is the list of records for which we want to generate
# individual pages
# individual pages
records = nil
records = nil
data_spec['data'].split('.').each do |level|
data_spec['data'].split('.').each do |level|
if records.nil?
if records.nil?
records = site.data[level]
records = site.data[level]
else
else
records = records[level]
records = records[level]
end
end
end
end
if (records.kind_of?(Hash))
if (records.kind_of?(Hash))
records = records.values
records = records.values
end
end
# apply filtering conditions:
# apply filtering conditions:
# - filter requires the name of a boolean field
# - filter requires the name of a boolean field
# - filter_condition evals a ruby expression which can use =record= as argument
# - filter_condition evals a ruby expression which can use =record= as argument
records = records.select { |record| record[data_spec['filter']] } if data_spec['filter']
records = records.select { |record| record[data_spec['filter']] } if data_spec['filter']
records = records.select { |record| eval(data_spec['filter_condition']) } if data_spec['filter_condition']
records = records.select { |record| eval(data_spec['filter_condition']) } if data_spec['filter_condition']
# we now have the list of all records for which we want to generate individual pages
# we now have the list of all records for which we want to generate individual pages
# iterate and call the constructor
# iterate and call the constructor
records.each do |record|
records.each do |record|
site.pages << DataPage.new(site, site.source, index_files_for_this_data, dir, page_data_prefix, record, name, name_expr, title, title_expr, template, extension, debug)
site.pages << DataPage.new(site, site.source, index_files_for_this_data, dir, dir_expr, page_data_prefix, record, name, name_expr, title, title_expr, template, extension, debug)
end
end
end
end
end
end
end
end
end
end
end
end
module DataPageLinkGenerator
module DataPageLinkGenerator
include Sanitizer
include Sanitizer
# use it like this: {{input | datapage_url: dir}}
# use it like this: {{input | datapage_url: dir}}
# to generate a link to a data_page.
# to generate a link to a data_page.
#
#
# the filter is smart enough to generate different link styles
# the filter is smart enough to generate different link styles
# according to the data_page-dirs directive ...
# according to the data_page-dirs directive ...
#
#
# ... however, the filter is not smart enough to support different
# ... however, the filter is not smart enough to support different
# extensions for filenames.
# extensions for filenames.
#
#
# Thus, if you use the `extension` feature of this plugin, you
# Thus, if you use the `extension` feature of this plugin, you
# need to generate the links by hand
# need to generate the links by hand
def datapage_url(input, dir)
def datapage_url(input, dir)
extension = @context.registers[:site].config['page_gen-dirs'] ? '/' : '.html'
extension = @context.registers[:site].config['page_gen-dirs'] ? '/' : '.html'
"#{dir}/#{sanitize_filename(input)}#{extension}"
"#{dir}/#{sanitize_filename(input)}#{extension}"
end
end
end
end
end
end
Liquid::Template.register_filter(Jekyll::DataPageLinkGenerator)
Liquid::Template.register_filter(Jekyll::DataPageLinkGenerator)