module StaticCMS
VERSION = '1.1.0'
require 'scms/scms_utils.rb'
require 'scms/s3deploy.rb'
require 'erb'
require 'ostruct'
require 'yaml'
require 'sass'
require 'packr'
include YAML
def StaticCMS.build(pub, config, mode)
@pub = pub
@cleanpub = true
@configdir = config
@mode = mode
@webroot = "public"
@source = File.join($website, @webroot)
ScmsUtils.log("_Mode: #{mode}_")
StaticCMS.sassall(@source)
yamlpath=File.join(@configdir, "config.yml")
ScmsUtils.log("**[Getting Config](#{ScmsUtils.uriEncode("file:///#{yamlpath}")})**")
$settings = StaticCMS.getsettings(yamlpath)
if $settings
if $settings["options"] != nil
if ENV["SCMS_PUBLISH_FOLDER"] == nil && $settings["options"]["build_dir"] != nil
ScmsUtils.log("_Setting pub dir from config.yml_")
@pub = $settings["options"]["build_dir"]
end
if $settings["options"]["clean_build_dir"] == false
@cleanpub = false
end
end
if @cleanpub
StaticCMS.cleanpubdir(@pub)
@cleanpub = false
else
ScmsUtils.log("Skipping cleaning \n#{@pub}")
end
#Bootstrap here
if $settings["bootstrap"] != nil
bootstrap = File.join($website, $settings["bootstrap"])
#ScmsUtils.log("Bootstrap is: #{$settings["bootstrap"]}")
if File.exists?(bootstrap)
begin
require_relative bootstrap
rescue Exception=>e
ScmsUtils.errLog( e )
end
else
ScmsUtils.log("_Bootstrap does not exist #{bootstrap}_")
end
end
#Bundle resources
scripts = StaticCMS.bundlescripts($settings["scripts"])
stylesheets = StaticCMS.bundlestylesheets($settings["stylesheets"])
#Generate pages
StaticCMS.parsetemplates(scripts, stylesheets)
else
ScmsUtils.errLog("Config is empty")
end
if File.exists?(@source)
ScmsUtils.log("_Merging 'public' folder_")
if @cleanpub
StaticCMS.cleanpubdir(@pub)
end
FileUtils.mkdir @pub unless Dir.exists? @pub
Dir.chdir(@source) do
#files = Dir.glob('*')
#FileUtils.cp_r files, @pub
Dir.glob("**/*").reject{|f| f['.svn']}.each do |oldfile|
newfile = File.join(@pub, oldfile.sub(@source, ''))
#puts newfile
File.file?(oldfile) ? FileUtils.copy(oldfile, newfile) : FileUtils.mkdir(newfile) unless File.exist? newfile
end
end
else
ScmsUtils.log("**No 'public' folder in #{@source} - skiping merge**")
end
ScmsUtils.successLog("**Compiled :)**")
ScmsUtils.log("[_#{@pub}_](#{ScmsUtils.uriEncode("file:///#{@pub}")})")
return @pub
end
def StaticCMS.parsetemplates(scripts, stylesheets)
# build views from templates
@template = $settings["template"]
if $settings["pages"] != nil
ScmsUtils.log("**Compiling Pages:**")
$settings["pages"].each do |page|
if page != nil
page.each do |option|
#ScmsUtils.log( "option (#{option.class}) = #{option[0]}" )
pageconfig = option[1]
#ScmsUtils.log( "Pageconfig = #{pageconfig}" )
if pageconfig["template"] == nil
skin = @template
else
skin = pageconfig["template"]
end
page = pageconfig["generate"]
ScmsUtils.successLog("#{page}")
resource = Hash.new
if pageconfig["resource"] != nil
resourcepath = File.join($website, pageconfig["resource"])
if File.exists?(resourcepath)
#ScmsUtils.log( "_Resource found: #{pageconfig["resource"]}_" )
resource = YAML.load_file(resourcepath)
else
ScmsUtils.errLog( "Resource not found: #{resourcepath}" )
end
end
hasHandler = nil
if pageconfig["handler"] != nil
handlerpath = File.join($website, pageconfig["handler"])
if File.exists?(handlerpath)
#ScmsUtils.log( "Handler found: #{pageconfig["handler"]}" )
require handlerpath
funDefined = defined? Handler.render
if funDefined != nil
hasHandler = "yes"
else
ScmsUtils.errLog( "Handler doesnt have a render method" )
end
else
ScmsUtils.errLog( "**Handler not found: #{handlerpath}**" )
end
end
views = Hash.new
pageconfig["views"].each do |view|
views[view[0]] = ""
viewpath = File.join($website, view[1])
if File.exists?(viewpath)
htmlsnipet = File.read(viewpath)
if !htmlsnipet.empty?
model = Hash.new
model = { :page => page, :sitedir => $website, :resource => resource }
if hasHandler == "yes"
ScmsUtils.log("_Rendering with handler_")
viewSnippet = Handler.render(viewpath)
else
viewSnippet = File.read(viewpath)
end
if @mode == "cms"
views[view[0]] = "
#{StaticCMS.parsetemplate(viewSnippet, model)}
"
else
views[view[0]] = StaticCMS.parsetemplate(viewSnippet, model)
end
else
ScmsUtils.writelog(@pub, "Empty file: #{viewpath}")
end
else
ScmsUtils.errLog("View not found: #{view[0]} - #{view[1]} [#{viewpath}]")
ScmsUtils.writelog(@pub, "View not found: #{view[0]} - #{view[1]} [#{viewpath}]")
end
#ScmsUtils.log( "view = #{view[0]} - #{view[1]}" )
end
monkeyhook = "";
if @mode == "cms"
monkeyhook = ""
end
hash = {
:page => page,
:views => views,
:resource => resource,
:config => pageconfig,
:scripts => scripts,
:stylesheets => stylesheets,
:sitedir => $website,
:monkeyhook => monkeyhook
}
erb = File.join($website, skin)
out = File.join(@pub, pageconfig["generate"])
if File.exists?(erb)
pubsubdir = File.dirname(out)
Dir.mkdir(pubsubdir, 755) unless File::directory?(pubsubdir)
html = StaticCMS.parsetemplate(File.read(erb), hash)
File.open(out, 'w') {|f| f.write(html) }
else
ScmsUtils.errLog("Template doesn't exist: #{erb}")
end
end
end
#ScmsUtils.log( out )
end
end
end
def StaticCMS.bundlescripts(scriptsConfig)
scripts = Hash.new
if scriptsConfig != nil
ScmsUtils.log("**Bundeling Scripts:**")
scriptsConfig.each do |script|
#ScmsUtils.log( "script (#{script.class}) = #{script}" )
script.each do |option|
name = option[0]
if option[1]["version"] != nil
scriptversion = option[1]["version"]
else
scriptversion = 1
end
scriptname = "#{name}-v#{scriptversion}.js"
scriptsdir = File.join(@pub, "scripts")
puts scriptsdir
FileUtils.mkdir_p(scriptsdir) unless File::directory?(scriptsdir)
#Dir.mkdir_p(scriptsdir, 755 ) if !File::directory?(scriptsdir)
out = File.join(scriptsdir, scriptname)
ScmsUtils.successLog("#{scriptname}")
content = ""
assetList = ""
bundle = option[1]["bundle"]
bundle.each do |asset|
assetList += "\t#{asset}\n"
assetname = File.join(@source, asset)
if File::exists?(assetname)
content = content + "\n" + File.read(assetname)
else
ScmsUtils.errLog( "Error: No such file #{assetname}" )
end
end
ScmsUtils.log("#{assetList}")
scripts[name] = "scripts/#{scriptname}"
File.open(out, 'w') {|f| f.write(content) }
end
end
end
return scripts
end
def StaticCMS.bundlestylesheets(styleConfig)
stylesheets = Hash.new
if styleConfig != nil
ScmsUtils.log("**Bundeling Stylesheets:**")
styleConfig.each do |stylesheet|
#ScmsUtils.log( "stylesheet (#{stylesheet.class}) = #{stylesheet}" )
stylesheet.each do |option|
name = option[0]
if option[1]["version"] != nil
stylesheetversion = option[1]["version"]
else
stylesheetversion = 1
end
stylesheetname = "#{name}-v#{stylesheetversion}.css"
Dir.mkdir(File.join(@pub, "stylesheets"), 755 ) if ! File::directory?(File.join(@pub, "stylesheets"))
out = File.join(@pub, "stylesheets", stylesheetname)
ScmsUtils.successLog("#{stylesheetname}")
content = ""
bundle = option[1]["bundle"]
assetList = ""
bundle.each do |asset|
assetList += "\t #{asset}\n"
assetname = File.join(@source, asset)
if File::exists?(assetname)
content = content + "\n" + File.read(assetname)
else
ScmsUtils.errLog( "Error: No such file #{assetname}" )
end
end
ScmsUtils.log( "#{assetList}" )
stylesheets[name] = "stylesheets/#{stylesheetname}"
File.open(out, 'w') {|f| f.write(content) }
end
end
end
return stylesheets
end
def StaticCMS.parsetemplate(template, hash)
data = OpenStruct.new(hash)
result = ""
begin
result = ERB.new(template).result(data.instance_eval { binding })
rescue Exception => e
ScmsUtils.errLog("**Critical Error: Could not parse template**")
ScmsUtils.log( "_(if your using resources make sure their not empty)_" )
ScmsUtils.errLog( e.message )
end
return result
end
def StaticCMS.getsettings(yamlpath)
config = nil
if File.exist?(yamlpath)
tree = File.read(yamlpath)
begin
myconfig = ERB.new(tree).result()
#puts "Conf = #{myconfig}"
config = YAML.load(myconfig)
#config = YAML.load_file(yamlpath)
rescue Exception => e
ScmsUtils.errLog("Error Loading config.yml (check there are no tabs in the file)")
ScmsUtils.log( "_[Verify your config](http://yaml-online-parser.appspot.com/)_")
ScmsUtils.errLog( e.message )
ScmsUtils.errLog( e.backtrace.inspect )
end
else
ScmsUtils.errLog("Config file does not exist: #{yamlpath}")
end
return config
end
def StaticCMS.cleanpubdir(pub)
ScmsUtils.log("_Cleaning pub folder #{pub}_")
FileUtils.rm_rf pub
#FileUtils.remove_dir(pub, force = true)
sleep 0.5 # seconds
FileUtils.mkdir_p(pub) unless File.exist? pub
FileUtils.chmod 0755, pub
end
def StaticCMS.crunch(crunchDir)
ScmsUtils.log( "Starting crunching CSS and JavaScript in:\n#{crunchDir}\n\n" )
#StaticCMS.sassall(crunchDir)
Dir.chdir(crunchDir) do
Dir.glob("**/*.js").reject{|f| /-min/.match(f) != nil || /\.min/.match(f) != nil || /\.pack/.match(f) != nil }.each do |asset|
StaticCMS.packr(asset)
end
#Dir.glob("**/*.{css, js}").each do |asset|
# #fullFileName = File.basename(asset)
# #ScmsUtils.log( "Crunching #{fullFileName}" )
# ext = File.extname(asset)
# StaticCMS.yuicompress(asset, ext)
#end
end
end
def StaticCMS.sassall(crunchDir)
ScmsUtils.log( "**Minimising Sass Files (.scss) **" )
Dir.chdir(crunchDir) do
Dir.glob("**/*.{scss}").each do |asset|
StaticCMS.sass(asset)
end
end
end
def StaticCMS.sass(asset)
if File.exists?(asset)
begin
template = File.read(asset)
sass_engine = Sass::Engine.new(template, {
:style => :compressed,
:cache => false,
:syntax => :scss
}.freeze)
output = sass_engine.to_css
css_file = "#{File.dirname(asset)}/#{File.basename(asset,'.*')}.css"
File.open(css_file, 'w') { |file| file.write(output) }
ScmsUtils.log( "_Sassed: #{css_file}_" )
rescue Exception => e
ScmsUtils.errLog( "Error processing: #{asset}" )
ScmsUtils.errLog( e.message )
end
end
end
def StaticCMS.packr(asset)
if File.exists?(asset)
begin
code = File.read(asset)
compressed = Packr.pack(code)
File.open(asset, 'w') { |f| f.write(compressed) }
ScmsUtils.log( "_Packed #{File.basename(asset)}_" )
rescue Exception => e
ScmsUtils.errLog( "Error processing: #{asset}" )
ScmsUtils.errLog( e.message )
end
end
end
def StaticCMS.yuicompress(asset, ext)
if File.exists?(asset)
#ScmsUtils.log( " Encoding: #{asset.encoding}" )
enc = "--charset utf-8"
enc = ""
cmd = "java"
params = "-jar \"#{File.join(Folders[:tools], "yuicompressor", "yuicompressor-2.4.7.jar")}\" #{enc} --type #{ext.gsub(".","")} \"#{asset}\" -o \"#{asset}\""
##Need to check if asset exists
if system("#{cmd} #{params}")
ScmsUtils.log( "_Crunched #{File.basename(asset)}_" )
else
ScmsUtils.errLog( "Error crunching: #{asset}" )
end
else
ScmsUtils.errLog( "#{asset} does not exist" )
end
end
def StaticCMS.deploy(pub, config)
yamlpath=File.join(config, "s3config.yml")
if File.exists?(yamlpath)
S3Deploy.sync(pub, config)
else
raise "The following file doesn't exist #{yamlpath}"
end
end
end