ferron

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

site.lua (5113B)


      1 -- site.lua
      2 local site = {}
      3 local sitemeta = {
      4   __call = function(self, key, vars)
      5     print(key)
      6   end
      7 }
      8 
      9 local lfs = require 'lfs'
     10 local config = require 'ferron.config'
     11 local tb = require 'ferron.utilities.table-utils'
     12 local fl = require 'ferron.utilities.file-utils'
     13 
     14 -- Create a simple array with the directory name of the sites
     15 local function getsitelist()
     16   local location = config.sites
     17 
     18   return tb.map(
     19     function(site)
     20       if fl.isDirectory(location .. site)
     21         and fl.isNotDotDirectory(site)
     22       then
     23         return site
     24       end
     25     end,
     26     tb.from(lfs.dir(location))
     27   )
     28 end
     29 
     30 -- Check if the value of the arg[1] (sitename) exists in the table
     31 -- returns by getsitelist method.
     32 local function isSite(sitename)
     33   if tb.hasvalue(getsitelist(), sitename) then
     34     return sitename
     35   end
     36 
     37   return false
     38 end
     39 
     40 -- Get the configuration file of the selected website.
     41 local function getsiteconfig(sitename)
     42   package.path = package.path .. ';sites/'.. sitename ..'/?.lua'
     43 
     44   return require 'config'
     45 end
     46 
     47 local function setsiteconfig(sitename)
     48   local thatsite = assert(isSite(sitename), "That is not a valid site")
     49 
     50   site.config = tb.extend({}, config, getsiteconfig(thatsite))
     51 
     52   return site.config
     53 end
     54 
     55 local function setsitepath(sitename)
     56   local thatsite = assert(isSite(sitename), "That is not a valid site")
     57 
     58   return config.sites .. thatsite
     59 end
     60 
     61 local function makepaths(sitepath, siteconfig)
     62   for k, _ in pairs(siteconfig.paths) do
     63     site[k] = sitepath .. siteconfig['paths'][k]
     64   end
     65 
     66   return
     67 end
     68 
     69 local function choosesite(siteslist)
     70   local whichsite
     71 
     72   assert(type(siteslist) == 'table', 'The argument "siteslist" must be a table')
     73 
     74   if #siteslist > 1 then
     75     repeat
     76       io.write('For which website do you want to proceed? \n')
     77 
     78       for k, v in ipairs(siteslist) do
     79         io.write(k .. ') ' .. v .. '\n')
     80       end
     81 
     82       io.write('Please enter the number... \n')
     83       io.flush()
     84 
     85       whichsite=io.read()
     86     until (tb.haskey(siteslist, tonumber(whichsite))) == true
     87   elseif #siteslist == 1 then
     88     whichsite = 1
     89   else
     90     return 'Something is wrong!'
     91   end
     92 
     93   return siteslist[tonumber(whichsite)]
     94 end
     95 
     96 local function setnavigation(contentlocation, baseurl)
     97   local navigation = tb.map(
     98     function(f)
     99       local meta = fl.getpageconf(f)
    100 
    101       if meta.navigation then
    102         local label = meta.navigation.label and meta.navigation.label or meta.title
    103         local location = baseurl .. fl.removeextension(fl.getrelpath(f, contentlocation)) .. '.html'
    104         local attributes = meta.navigation.attributes
    105         local order = meta.navigation.order
    106         local current = false
    107 
    108         if fl.getbasename(location) == 'index.html' then
    109           location = fl.getdirname(location)
    110         end
    111 
    112         return {label = label, location = location, attributes = attributes, order = order, current = current}
    113       end
    114     end,
    115     -- The data table
    116     tb.filter(fl.isMarkdown, tb.from(fl.getdirtree(contentlocation)))
    117   )
    118 
    119   -- It's a dumb way to sort but it works for now.
    120   -- Maybe it should be coroutines.
    121   local function sortnavigation(tbl)
    122     local _tbl = {}
    123 
    124     -- First, add those who get an navigation.order property sets
    125     for _, val in ipairs(tbl) do
    126       if val.order then
    127         _tbl[val.order] = val
    128       end
    129     end
    130 
    131     --- Then add the rest
    132     for _, val in ipairs(tbl) do
    133       if not val.order then
    134         _tbl[#_tbl+1] = val
    135       end
    136     end
    137 
    138     return _tbl
    139   end
    140 
    141   return tb.extend({}, sortnavigation(navigation))
    142 end
    143 
    144 function site.setsite(sitename)
    145   local thatsite = sitename and sitename or choosesite(getsitelist())
    146 
    147   tb.build{
    148     -- Assign values to site.path and site.config
    149     setsitepath(thatsite),
    150     setsiteconfig(thatsite),
    151     -- Create absolute path properties for the chosen site's folders
    152     makepaths(setsitepath(thatsite), setsiteconfig(thatsite)),
    153   }
    154 
    155   -- Store all site nodes in one table
    156   site.nodes = tb.from(fl.getdirtree(fl.isDirectory(site.content)))
    157   -- Have different values if devmode is at true or not
    158   site.config.baseurl = (Ferron.devmode == true and site.config.urldev or site.config.url)
    159   -- Create the main navigation menu
    160   site.navigation = setnavigation(site.content, site.config.baseurl)
    161 
    162   return site
    163 end
    164 
    165 function site.startsite(samplelocation)
    166   local newsite = {
    167     domain = nil,
    168     name = nil,
    169     location = nil,
    170     config = nil,
    171     sample = config.sites .. 'sample',
    172   }
    173   local location = samplelocation or newsite.sample
    174 
    175   io.write('How do you want names your new website? \n')
    176   io.write('Please enter that name below... \n')
    177   io.flush()
    178 
    179   newsite.name = io.read()
    180   newsite.location = config.sites .. newsite.name
    181 
    182   fl.mkdir(newsite.location)
    183 
    184   os.execute('cp -Rp ' .. lfs.currentdir() .. '/' .. location .. '/*' .. ' ' .. newsite.location)
    185 
    186   if fl.isDirectory(newsite.location) then
    187     return print('Your new website is ready to be cutomize here "' .. newsite.location .. '"!')
    188   else
    189     return print('!! Error, something went wrong !')
    190   end
    191 end
    192 
    193 -- Init a site before generates it
    194 -- function site.init()
    195 -- end
    196 return setmetatable(site, sitemeta)