commit 4800ae897a22d20a7b05b1ea49abc2da979c6a45
parent 5704f9e57b06e7ac9de23159483ad2af3109f192
Author: Hugo Soucy <hugo@soucy.cc>
Date: Wed, 30 Nov 2022 14:47:23 -0500
Merge branch 'refactor_2022-nov'
Diffstat:
6 files changed, 224 insertions(+), 225 deletions(-)
diff --git a/satelito/file.lua b/satelito/file.lua
@@ -123,13 +123,13 @@ function file.get_rellink(filepath, dirname)
end
end
---
-function file.get_collection(filepath, dirname)
+-- Get a list of relative children paths from a filepath
+function file.get_list(filepath, dirname)
local collection = {}
for subfilepath in dirtree.get(file.get_dirname(filepath)) do
if subfilepath
- and (file.is_markdown(subfilepath) or file.is_html(subfilepath))
+ and file.is_content(subfilepath)
and not file.is_index(subfilepath)
then
collection[#collection+1] = file.get_relpath(subfilepath, dirname)
@@ -139,6 +139,26 @@ function file.get_collection(filepath, dirname)
return collection
end
+-- Get a table collection of contents
+function file.get_collection(collection)
+ if collection and type(collection) == 'table' then
+ local collection_list = {}
+ local contentdir = _G.Satelito.contentdir
+
+ for i = 1, #collection do
+ if lfs.attributes(contentdir..collection[i]).mode == 'directory' then
+ collection_list[#collection_list+1] = file.get_list(contentdir..collection[i], contentdir)
+ else
+ collection_list[#collection_list+1] = { collection[i] }
+ end
+ end
+
+ return lume.concat(table.unpack(collection_list))
+ end
+
+ return
+end
+
-- Create a dirtree
function file.mkdir(filepath)
local sep, pStr = package.config:sub(1, 1), ''
diff --git a/satelito/init.lua b/satelito/init.lua
@@ -8,7 +8,6 @@ local lume = require 'satelito.lib.lume.lume'
local model = require 'satelito.model'
local dirtree = require 'satelito.dirtree'
local file = require 'satelito.file'
-local sitemapxml = require 'satelito.sitemapxml'
local site = require 'satelito.site'
--
local init
@@ -36,6 +35,47 @@ exec:argument 'bin name'
args = parser:parse()
+-- Started
+print('=> Satelito is here ...')
+
+-------------
+-- GLOBALS --
+-------------
+
+-- Set the Satelito global table
+_G.Satelito = {}
+_G.Satelito.timestart = os.time()
+
+-- Put config.lua in a table
+print('=> Fetching the configuration file content ...')
+_G.Satelito.config = dofile(site.get_config(lfs.currentdir()..'/'))
+
+-- Change current directory for the config.lua's directory
+print('=> Moving where the site configuration file is located ...')
+lfs.chdir(file.get_dirname(site.get_config(lfs.currentdir()..'/')))
+
+-- Then add the current directory to the package.path
+package.path = package.path .. ';'.. lfs.currentdir() ..'/?.lua'
+
+-- Get the absolute path for the 'content' directory
+_G.Satelito.contentdir = lfs.currentdir()..'/'.._G.Satelito.config.paths.content
+
+-- Get the absolute path for the 'public_html' directory
+_G.Satelito.publicdir = lfs.currentdir()..'/'.._G.Satelito.config.paths.public_html
+
+-- Get the list of templates
+print('=> Fetching the templates ...')
+_G.Satelito.templates = lume.array(dirtree.get(lfs.currentdir() .. '/' .. _G.Satelito.config.paths.templates))
+
+-- Get the arguments
+_G.Satelito.args = args
+
+--print(inspect(_G.Satelito))
+
+----------
+-- EXEC --
+----------
+
if args['exec'] then
package.path = package.path .. ';'.. lfs.currentdir() ..'/?.lua'
@@ -47,6 +87,11 @@ if args['exec'] then
end
+----------
+-- INIT --
+----------
+
+-- Initialize the satelito sample site in $HOME
-- Example '$ satelito init'
if args['init'] then
os.execute('mkdir ~/satelito-sample')
@@ -61,149 +106,65 @@ if args['init'] then
return
end
+----------
+-- PIPE --
+----------
+
+-- Pipe stdout into satelito
-- Example: '$ find site/content/ | satelito pipe'
if args['pipe'] then
- local configpath = false
- local config = false
- local contentdir = false
- local sitemap = {}
- local templates
- local timestart = os.time()
-
- print('=> Satelito is on ...')
+ local sitedata = {}
for filepath in (io.lines()) do
- if file.is_markdown(filepath) or file.is_html(filepath) then
- -- Get the site configuration's path
- if not configpath then
- print('=> Searching for the nearest config.lua ...')
- configpath = site.get_config(filepath)
- end
+ if file.is_content(filepath) then
+ -- Get the pagedata of the file
+ local pagedata = model.set(filepath)
- -- Change the current directory to the config's directory
- if lfs.currentdir()..'/' ~= file.get_dirname(configpath) then
- print('=> Moving where the configuration file is located ...')
- lfs.chdir(file.get_dirname(configpath))
+ -- Add the pagedata of the file into the sitedata table
+ if lume.count(sitedata) == 0 then
+ print('=> Fetching the markdown and HTML content ...')
end
- -- If the site configuration file exists
- if file.exists(configpath) then
- -- Add the currentdir to the package.path
- package.path = package.path .. ';'.. lfs.currentdir() ..'/?.lua'
-
- -- Set config.lua in a table
- if not config then
- print('=> Fetching the configuration file content ...')
- config = require 'config'
- end
-
- -- Absolute path to the 'content/' directory
- if not contentdir then
- contentdir = lfs.currentdir() .. '/' .. config.paths.content
- end
-
- -- Get the list of templates
- if not templates then
- print('=> Fetching the templates ...')
- templates = lume.array(dirtree.get(lfs.currentdir() .. '/' .. config.paths.templates))
- end
-
- -- Get the meta of the file
- local meta = model.set(filepath, lume.extend(config, {templates = templates}), contentdir)
-
- -- Collection
- -- Get the files of a collection (only for the pipe command)
- if meta.collection and type(meta.collection) == 'table' then
- for i = 1, #meta.collection do
- if lfs.attributes(contentdir..meta.collection[i]).mode == 'directory' then
- for collectable in dirtree.get(contentdir..meta.collection[i]) do
- if file.is_content(collectable) and file.get_metafile(collectable) then
- sitemap[#sitemap+1] = model.set(collectable, lume.extend(config, {templates = templates}), contentdir)
- end
- end
- else
- if file.is_content(contentdir..meta.collection[i])
- and file.get_metafile(contentdir..meta.collection[i])
- then
- sitemap[#sitemap+1] = model.set(contentdir..meta.collection[i], lume.extend(config, {templates = templates}), contentdir)
- end
- end
- end
- end
-
- -- Add the meta of the file into the sitemap table
- if lume.count(sitemap) == 0 then
- print('=> Fetching the markdown and HTML content ...')
- end
-
- sitemap[#sitemap+1] = meta
- end
+ sitedata[#sitedata+1] = pagedata
end
end
- print('=> '..lume.count(sitemap)..' content found')
-
+ print('=> '..lume.count(sitedata)..' content found')
print('=> Making the web site ...')
-- Sorting by alphanum
- table.sort(lume.unique(sitemap), function(a, b) return a.idorder > b.idorder end)
+ table.sort(lume.unique(sitedata), function(a, b) return a.idorder > b.idorder end)
- return site.make(sitemap, args['export'], timestart)
+ return site.make(sitedata)
end
+----------
+-- MAKE --
+----------
+
-- Make command
-- Example: '$ satelito make --export'
if args['make'] then
- local config
- local templates
- local timestart = os.time()
- local sitemap = {}
-
- print('=> Satelito is on ...')
-
- if file.exists('config.lua') then
- -- Add the currentdir to the package.path
- package.path = package.path .. ';'.. lfs.currentdir() ..'/?.lua'
-
- -- Set config.lua in a table
- print('=> Fetching the configuration file content ...')
- config = require 'config'
-
- -- Absolute path to the 'content/' directory
- local contentdir = lfs.currentdir() .. '/' .. config.paths.content
-
- print('=> Fetching the templates ...')
- templates = lume.array(dirtree.get(lfs.currentdir() .. '/' .. config.paths.templates))
+ local config = _G.Satelito.config;
+ local contentdir = _G.Satelito.contentdir
+ local templates = _G.Satelito.templates
+ local sitedata = {}
- print('=> Fetching the markdown and HTML content ...')
+ print('=> Fetching the markdown and HTML content ...')
- for filepath in dirtree.get(contentdir) do
- if file.is_markdown(filepath) or file.is_html(filepath) then
- local meta = model.set(filepath, lume.extend(config, {templates = templates}), contentdir)
+ for filepath in dirtree.get(contentdir) do
+ if file.is_content(filepath) then
+ local pagedata = model.set(filepath)
- sitemap[#sitemap+1] = meta
- end
+ sitedata[#sitedata+1] = pagedata
end
+ end
- print('=> '..lume.count(sitemap)..' content found')
- print('=> Making the web site ...')
-
- -- Sort before make the website
- table.sort(lume.unique(sitemap), function(a, b) return a.idorder > b.idorder end)
-
- site.make(sitemap, args['export'], timestart)
+ print('=> '..lume.count(sitedata)..' content found')
+ print('=> Making the web site ...')
- -- Make and export the sitemap.xml
- if config.sitemapxml and args['export'] then
- local sitemapxml_xml, sitemapxml_xml_path = sitemapxml.make(
- sitemap, templates, config.paths.public_html
- )
- file.export(sitemapxml_xml_path, sitemapxml_xml)
- end
+ -- Sort before make the website
+ table.sort(lume.unique(sitedata), function(a, b) return a.idorder > b.idorder end)
- return
- else
- print('There is no "config.lua" here.')
- os.exit()
- end
+ return site.make(sitedata, args['export'])
end
diff --git a/satelito/list.lua b/satelito/list.lua
@@ -3,8 +3,7 @@ local list = {}
--
local dirtree = require 'satelito.dirtree'
local file = require 'satelito.file'
-local inspect = require 'inspect'
-local lfs = require 'lfs' -- luafilesystem
+local model = require 'satelito.model'
local lume = require 'satelito.lib.lume.lume'
-- Pagination
@@ -29,16 +28,24 @@ function list.set_pagination(pagelist, len)
return slicedlist
end
--- Children
-function list.get_children(children_list, sitemap, asc)
+-- Get children contents
+function list.get_children(children_list, sitedata, asc)
local children = {}
+ local relpaths = {}
+ local contentdir = _G.Satelito.contentdir
if children_list then
- for i = 1, #sitemap do
- local is_child = lume.find(children_list, sitemap[i].relpath)
+ for i = 1, #sitedata do
+ relpaths[#relpaths+1] = sitedata[i].relpath
+ end
+
+ for i = 1, #children_list do
+ local is_exists = lume.find(relpaths, children_list[i])
- if is_child then
- children[#children+1] = sitemap[i]
+ if is_exists then
+ children[#children+1] = sitedata[is_exists]
+ else
+ children[#children+1] = model.set(contentdir..children_list[i])
end
end
@@ -53,25 +60,6 @@ function list.get_children(children_list, sitemap, asc)
return children
end
-function list.get_collection(collection, sitemap, asc)
- if collection and type(collection) == 'table' then
- local collection_list = {}
- local contentdir = lfs.currentdir()..'/'..sitemap[1].paths.content
-
- for i = 1, #collection do
- if lfs.attributes(contentdir..collection[i]).mode == 'directory' then
- collection_list[#collection_list+1] = file.get_collection(contentdir..collection[i], contentdir)
- else
- collection_list[#collection_list+1] = { collection[i] }
- end
- end
-
- return list.get_children(lume.concat(table.unpack(collection_list)), sitemap, asc)
- end
-
- return
-end
-
-- Archives
function list.get_archives(contentdir)
local archives_table = {}
diff --git a/satelito/model.lua b/satelito/model.lua
@@ -6,90 +6,89 @@ local lfs = require 'lfs' -- luafilesystem
local lume = require 'satelito.lib.lume.lume'
local dirtree = require 'satelito.dirtree'
local file = require 'satelito.file'
-local list = require 'satelito.list'
local markdown = require 'discount' -- lua-discount
local template = require 'satelito.template'
-function model.set(filepath, config, contentdir)
- local pagemeta = file.get_metafile(filepath) or {}
+function model.set(filepath)
+ local pagedata = file.get_metafile(filepath) or {}
+ local config = _G.Satelito.config
+ local contentdir = _G.Satelito.contentdir
+ local publicdir = _G.Satelito.publicdir
+ local templates = _G.Satelito.templates
local time_created
-- If required properties are nil
- pagemeta.title = pagemeta.title or file.get_basename(filepath):match('(.+)%..*')
- pagemeta.date = pagemeta.date or os.date('%Y-%m-%d', lfs.attributes(filepath).change)
- pagemeta.datetime = pagemeta.datetime or os.date('%H:%M:%S', lfs.attributes(filepath).change)
+ pagedata.title = pagedata.title or file.get_basename(filepath):match('(.+)%..*')
+ pagedata.date = pagedata.date or os.date('%Y-%m-%d', lfs.attributes(filepath).change)
+ pagedata.datetime = pagedata.datetime or os.date('%H:%M:%S', lfs.attributes(filepath).change)
-- Path properties
- pagemeta.contentdir = contentdir
- pagemeta.path = filepath
- pagemeta.relpath = file.get_relpath(filepath, contentdir)
- pagemeta.reldir = pagemeta.relpath:match("(.*/)")
+ pagedata.contentdir = contentdir
+ pagedata.path = filepath
+ pagedata.relpath = file.get_relpath(filepath, contentdir)
+ pagedata.reldir = pagedata.relpath:match("(.*/)")
-- Link properties
- pagemeta.rellink = file.get_rellink(filepath, contentdir)
- pagemeta.rellinkdir = '/'.. (pagemeta.reldir ~= nil and pagemeta.reldir or '')
- pagemeta.permalink = file.get_permalink(filepath, contentdir, config.siteurl)
- pagemeta.exportlink = file.get_exportlink(filepath, contentdir, config.paths.public_html)
- pagemeta.dirlink = file.get_permalink(filepath, contentdir, config.siteurl):match("(.*/)")
+ pagedata.rellink = file.get_rellink(filepath, contentdir)
+ pagedata.rellinkdir = '/'.. (pagedata.reldir ~= nil and pagedata.reldir or '')
+ pagedata.permalink = file.get_permalink(filepath, contentdir, config.siteurl)
+ pagedata.exportlink = file.get_exportlink(filepath, contentdir, publicdir)
+ pagedata.dirlink = file.get_permalink(filepath, contentdir, config.siteurl):match("(.*/)")
-- Time properties
- time_created = (pagemeta.date..pagemeta.datetime):gsub('%W','')
+ time_created = (pagedata.date..pagedata.datetime):gsub('%W','')
- pagemeta.time_created = time_created
- pagemeta.time_modification = lfs.attributes(filepath).modification
- pagemeta.time_modified_child = file.get_lastmodified(lume.array(dirtree.get(file.get_dirname(filepath))))
+ pagedata.time_created = time_created
+ pagedata.time_modification = lfs.attributes(filepath).modification
+ pagedata.time_modified_child = file.get_lastmodified(lume.array(dirtree.get(file.get_dirname(filepath))))
-- Unique page ID for the Atom feed
- pagemeta.id = 'tag:' .. config.siteurl:match('^%w+://([^/]+)') .. ',' .. pagemeta.date .. ':' .. pagemeta.rellink
- pagemeta.idorder = pagemeta.rellinkdir .. time_created
+ pagedata.id = 'tag:' .. config.siteurl:match('^%w+://([^/]+)') .. ',' .. pagedata.date .. ':' .. pagedata.rellink
+ pagedata.idorder = pagedata.rellinkdir .. time_created
-- HTML content
if file.is_markdown(filepath) then
- pagemeta.content = markdown(file.read(filepath))
+ pagedata.content = markdown(file.read(filepath))
elseif file.is_html(filepath) then
- pagemeta.content = file.read(filepath)
+ pagedata.content = file.read(filepath)
end
-- Summary
- if pagemeta.summary then
- pagemeta.summary = markdown(pagemeta.summary)
+ if pagedata.summary then
+ pagedata.summary = markdown(pagedata.summary)
end
-- List (and Feed)
- if file.is_index(filepath) and pagemeta.list ~= false then
- pagemeta.list = file.get_collection(filepath, contentdir)
+ if file.is_index(filepath) and pagedata.list ~= false then
+ pagedata.list = file.get_list(filepath, contentdir)
end
- -- Archives
- if pagemeta.archives then
- pagemeta.archives_children = list.get_archives(contentdir)
- end
-
- -- Tags
- if pagemeta.tags then
- pagemeta.tags_children = list.get_tags(contentdir)
+ -- Collection
+ -- File list
+ if pagedata.collection then
+ pagedata.collection_list = file.get_collection(pagedata.collection)
end
-- Change the language for a specific content
- pagemeta.language = pagemeta.language or config.language
+ pagedata.language = pagedata.language or config.language
-- Templates
- pagemeta.template = pagemeta.template or pagemeta.posttype or 'default'
- pagemeta.layout = pagemeta.layout or 'layout'
- pagemeta.head = pagemeta.head or 'head'
- pagemeta.navigation = pagemeta.navigation or 'navigation'
- pagemeta.footer = pagemeta.footer or 'footer'
- pagemeta.feed = pagemeta.feed or 'feed.xml'
+ pagedata.template = pagedata.template or pagedata.posttype or 'default'
+ pagedata.layout = pagedata.layout or 'layout'
+ pagedata.head = pagedata.head or 'head'
+ pagedata.navigation = pagedata.navigation or 'navigation'
+ pagedata.footer = pagedata.footer or 'footer'
+ pagedata.feed = pagedata.feed or 'feed.xml'
-- Include a partial template and compile it
-- @usage <%- include("test-partial") %>
- pagemeta.include = function(templatename)
- local inc = etlua.compile(file.read(template.find(config.templates, templatename)))
+ pagedata.include = function(templatename)
+ local inc = etlua.compile(file.read(template.find(templates, templatename)))
- return inc(lume.extend({}, config, pagemeta))
+ return inc(lume.extend({}, config, pagedata))
end
- return lume.extend({}, config, pagemeta)
+ return lume.extend({}, config, pagedata, {templates = templates})
end
return model
diff --git a/satelito/site.lua b/satelito/site.lua
@@ -10,6 +10,7 @@ local file = require 'satelito.file'
local list = require 'satelito.list'
local lume = require 'satelito.lib.lume.lume'
local page = require 'satelito.page'
+local sitemapxml = require 'satelito.sitemapxml'
--- From a filepath get the closest 'config.lua' by climbing the
-- directory tree
@@ -29,58 +30,79 @@ function site.get_config(filepath)
return site.get_config(dir_parent)
end
--- Make the site (from the sitemap)
-function site.make(sitemap, export, timestart)
+-- Make the site (from the sitedata)
+function site.make(sitedata)
local duration
-
- for i = 1, #sitemap do
+ local config = _G.Satelito.config
+ local contentdir = _G.Satelito.contentdir
+ local export = _G.Satelito.args['export']
+ local make = _G.Satelito.args['make']
+ local publicdir = _G.Satelito.publicdir
+ local templates = _G.Satelito.templates
+ local timestart = _G.Satelito.timestart
+
+ for i = 1, #sitedata do
local html, html_path
local feed_xml, feed_xml_path
local paginated
- sitemap[i].index = i
+ sitedata[i].index = i
+
+ -- Lists
+ -- Subpages from the actual index page
+ if sitedata[i].list ~= false and file.is_index(sitedata[i].path) then
+ sitedata[i].children = list.get_children(sitedata[i].list, sitedata, sitedata[i].asc)
+ end
+
+ -- Collections
+ -- Group of pages from specific relpaths
+ if sitedata[i].collection and sitedata[i].collection_list then
+ sitedata[i].collection = list.get_children(sitedata[i].collection_list, sitedata, sitedata[i].asc)
+ end
- if sitemap[i].list ~= false and file.is_index(sitemap[i].path) then
- sitemap[i].children = list.get_children(sitemap[i].list, sitemap, sitemap[i].asc)
+ -- Archives
+ if sitedata[i].archives then
+ sitedata[i].archives_children = list.get_archives(contentdir)
end
- if sitemap[i].collection then
- sitemap[i].collection = list.get_collection(sitemap[i].collection, sitemap, sitemap[i].asc)
+ -- Tags
+ if sitedata[i].tags then
+ sitedata[i].tags_children = list.get_tags(contentdir)
end
if i > 1 then
- sitemap[i].relprev = sitemap[i-1]
+ sitedata[i].relprev = sitedata[i-1]
end
- if i < #sitemap then
- sitemap[i].relnext = sitemap[i+1]
+ if i < #sitedata then
+ sitedata[i].relnext = sitedata[i+1]
end
-- If a pagination is requested
- if sitemap[i].pagination and file.is_index(sitemap[i].relpath) then
+ if sitedata[i].pagination and file.is_index(sitedata[i].relpath) then
print('=> A pagination is requested ...')
- sitemap[i].pagination.limit = sitemap[i].pagination.limit or 6
- sitemap[i].pagination.prefix = sitemap[i].pagination.prefix or 'pg-'
+ sitedata[i].pagination.limit = sitedata[i].pagination.limit or 6
+ sitedata[i].pagination.prefix = sitedata[i].pagination.prefix or 'pg-'
-- Split page children by pagination limit
- paginated = list.set_pagination(sitemap[i].collection or sitemap[i].children, sitemap[i].pagination.limit)
+ paginated = list.set_pagination(sitedata[i].collection or sitedata[i].children, sitedata[i].pagination.limit)
-- Set the pagination length
- sitemap[i].pagination.length = #paginated
+ sitedata[i].pagination.length = #paginated
print('=> Making the pagination pages ...')
for p = 1, #paginated do
- sitemap[i].children = paginated[p]
- sitemap[i].pagination.current = p
+ sitedata[i].children = paginated[p]
+ sitedata[i].pagination.current = p
-- Make the pagination pages
if p == 1 then
- html, html_path = page.make(sitemap[i])
+ html, html_path = page.make(sitedata[i])
else
html, html_path = page.make(
- sitemap[i],
- sitemap[i].exportlink:match("(.*/)")..sitemap[i].pagination.prefix..p..'.html'
+ sitedata[i],
+ sitedata[i].exportlink:match("(.*/)")..sitedata[i].pagination.prefix..p..'.html'
)
end
-- Export the pagination pages
@@ -93,7 +115,7 @@ function site.make(sitemap, export, timestart)
else
-- Make the page
- html, html_path = page.make(sitemap[i])
+ html, html_path = page.make(sitedata[i])
-- Export the page
if export then
@@ -104,23 +126,32 @@ function site.make(sitemap, export, timestart)
end
-- Feed
- if file.is_index(sitemap[i].relpath) and export then
- feed_xml, feed_xml_path = feed.make(sitemap[i])
+ if file.is_index(sitedata[i].relpath) and export then
+ feed_xml, feed_xml_path = feed.make(sitedata[i])
file.export(feed_xml_path, feed_xml)
end
-- Copy assets to the public_html/ folder
if export then
- assets.export(sitemap[i])
+ assets.export(sitedata[i])
end
end
+ -- Make and export the sitemap.xml
+ if config.sitemapxml and make and export then
+ local sitemapxml_xml, sitemapxml_xml_path = sitemapxml.make(
+ sitedata, templates, publicdir
+ )
+
+ file.export(sitemapxml_xml_path, sitemapxml_xml)
+ end
+
duration = os.difftime(os.time(), timestart) > 0
and 'in approximately '..os.difftime(os.time(), timestart)..' second(s).'
or 'in less than 1 second.'
print('--------------------------------------------------------------------------')
- print('Satelito built '..lume.count(sitemap)..' HTML page(s) '..duration)
+ print('Satelito built '..lume.count(sitedata)..' HTML page(s) '..duration)
end
return site
diff --git a/satelito/sitemapxml.lua b/satelito/sitemapxml.lua
@@ -5,9 +5,9 @@ local etlua = require 'etlua'
local file = require 'satelito.file'
local template = require 'satelito.template'
-function sitemapxml.make(sitemap, templates, destination)
+function sitemapxml.make(sitedata, templates, destination)
local _sitemapxml = etlua.compile(file.read(template.find(templates, 'sitemap.xml')))
- local sitemapxml_xml = _sitemapxml({sitemap = sitemap})
+ local sitemapxml_xml = _sitemapxml({sitemap = sitedata})
local sitemapxml_xml_path = destination..'sitemap.xml'
return sitemapxml_xml, sitemapxml_xml_path