ferron

[ARCHIVED] Ferron is a fast and simple static website generator made with Lua.
Log | Files | Refs | Submodules | README | LICENSE

page.lua (4913B)


      1 -- page.lua
      2 local page = {}
      3 local pagemeta = {
      4   __call = function(self, key, vars)
      5     print(key)
      6   end
      7 }
      8 
      9 local inspect = require 'inspect'
     10 local lfs = require 'lfs'
     11 local json = require 'dkjson'
     12 local markdown = require 'discount'
     13 local fl = require 'ferron.utilities.file-utils'
     14 local tb = require 'ferron.utilities.table-utils'
     15 local tp = require 'ferron.utilities.template-utils'
     16 local feed = require 'ferron.feed'
     17 
     18 local function sortentries(entries_tb, list_mt)
     19   local list_length = list_mt.length or nil
     20   local entries_count = list_length and 0 or nil
     21 
     22   if entries_count then
     23     for k, v in tb.sortdescendingpairs(entries_tb) do
     24       if entries_count < list_length then
     25         table.insert(list_mt['entries'], v)
     26 
     27         entries_count = entries_count + 1
     28       end
     29     end
     30   else
     31     for k, v in tb.sortdescendingpairs(entries_tb) do
     32       table.insert(list_mt['entries'], v)
     33     end
     34   end
     35 
     36   return list_mt['entries']
     37 end
     38 
     39 local function setentries(directory, list_mt, sitedata)
     40   local entries_tb = {}
     41 
     42   tb.each(
     43     function(entry)
     44       local entry_metadatas  = fl.getpageconf(entry)
     45       local entry_key = entry_metadatas.date .. 'T' .. entry_metadatas.datetime .. ':' .. fl.getrelpath(fl.removeextension(entry), sitedata.content)
     46 
     47       entries_tb[entry_key] = Ferron.site.pagestable[entry_key]
     48     end,
     49     tb.filter(fl.isNotIndex, tb.from(fl.getdirtree(directory)))
     50   )
     51 
     52   sortentries(entries_tb, list_mt)
     53 
     54   return list_mt['entries']
     55 end
     56 
     57 local function setpagetable(meta, relpath)
     58   local pagekey = meta.date .. 'T' .. meta.datetime .. ':' .. relpath
     59 
     60   Ferron.site.pagestable[pagekey] = meta
     61 
     62   return
     63 end
     64 
     65 local function setpagemodel(page, sitedata)
     66   return {
     67     content = markdown(fl.pullfilecontent(page)),
     68     navigation = sitedata.navigation,
     69     permalink = fl.getpermalink(page, sitedata),
     70     rellink = fl.getrellink(page, sitedata.content),
     71     site = sitedata.config,
     72     id = fl.setpageid(page, sitedata),
     73     entries = {},
     74     updated = os.date('%Y-%m-%dT%H:%M:%S', lfs.attributes(page).modification),
     75     lastupdated = os.date('%Y-%m-%dT%H:%M:%S', fl.getlastupdateddate(sitedata.nodes))
     76   }
     77 end
     78 
     79 function page.render(page, sitedata)
     80   local pathRel = fl.getrelpath(fl.removeextension(page), sitedata.content)
     81   local pathToHtml = fl.sethtmlpath(fl.getrelpath(fl.getdirname(page), sitedata.content), sitedata.html)
     82   local metaTable = setmetatable(
     83     setpagemodel(page, sitedata), {__index = fl.getpageconf(page)}
     84   )
     85   local shortlinks_db
     86   local shortlinks_tb
     87 
     88   -- If draft is set to true
     89   -- Don't render the page
     90   if metaTable.draft then
     91     print(metaTable.draft, metaTable.title)
     92     return
     93   end
     94 
     95   -- If in among navigation location values the permalink exists
     96   -- Then set current parameter to true
     97   -- Else set it to false
     98   tb.each(
     99     function(i)
    100       if i.location == metaTable.permalink then
    101         i.current = true
    102       else
    103         i.current = false
    104       end
    105     end,
    106     metaTable.navigation
    107   )
    108 
    109   -- Populate Ferron.site.pagestable{}
    110   if fl.isNotIndex(page) then
    111     setpagetable(metaTable, pathRel)
    112   end
    113 
    114   -- If exists set the shortlink
    115   if fl.isNotIndex(page) then
    116     shortlinks_db = fl.isFile(sitedata.data .. '/shortlinks.json')
    117     shortlinks_tb = (shortlinks_db ~= false and json.decode(fl.pullfilecontent(shortlinks_db)) or nil)
    118 
    119     if shortlinks_tb and shortlinks_db then
    120       metaTable.shortlink = (shortlinks_tb[metaTable.rellink] and shortlinks_tb[metaTable.rellink] or nil)
    121     end
    122   end
    123 
    124   -- For index page set and get entries
    125   if fl.isIndex(page) and metaTable.listchildnodes ~= false then
    126     setentries(fl.getdirname(page), metaTable, sitedata)
    127   end
    128 
    129   -- If the ancestors of the page dosen't exists make it
    130   if not fl.isDirectory(pathToHtml) then
    131     fl.mkdir(pathToHtml)
    132   end
    133 
    134   -- For each index page create syndication feeds
    135   if fl.isIndex(page) and metaTable.feed ~= false then
    136     feed.makefeed(metaTable, pathToHtml)
    137   end
    138 
    139   -- Build and push the HTML page
    140   fl.pushfilecontent(
    141     pathToHtml .. fl.getplainname(page) .. '.html',
    142     tp.rendertemplate(
    143       tp.selecttemplate(fl.isIndex(page), metaTable.template, sitedata.templates),
    144       metaTable
    145     )
    146   )
    147 
    148   return fl.isFile(pathToHtml .. fl.getplainname(page) .. '.html')
    149     and print(pathToHtml .. fl.getplainname(page) .. '.html')
    150 end
    151 
    152 function page.makepages(sitedata)
    153   local singlepages = tb.filter(fl.isNotIndex, tb.from(fl.getdirtree(fl.isDirectory(sitedata.content))))
    154   local indexpages = tb.filter(fl.isIndex, tb.from(fl.getdirtree(fl.isDirectory(sitedata.content))))
    155 
    156   -- Render single pages
    157   tb.each(function(p) page.render(p, sitedata) end, singlepages)
    158 
    159   -- Render index pages
    160   tb.each(function(p) page.render(p, sitedata) end, indexpages)
    161 
    162   print('==========')
    163   print('ยง ' .. tb.length(Ferron.site.pagestable) .. ' HTML pages have been created.')
    164   print('==========')
    165 
    166   return
    167 end
    168 
    169 return setmetatable(page, pagemeta)