From 748f5f7a3ae1a33ef02d30e327c8b8c5c7177a8a Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 11 Oct 2016 21:59:00 +0200 Subject: * compilation executables bundled in repo --- bin/static-site.php | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100755 bin/static-site.php (limited to 'bin') diff --git a/bin/static-site.php b/bin/static-site.php new file mode 100755 index 0000000..b121964 --- /dev/null +++ b/bin/static-site.php @@ -0,0 +1,195 @@ +#!/usr/bin/env php + 1) ? $argv[1] : '.'); + +function compile_path($directory) { + global $workingDirectory; + return implode( + DIRECTORY_SEPARATOR, + array_merge([$workingDirectory], (array)($directory)) + ); +} + +function get_template_mtime($template) { + $templateDependencies = ['index.tpl', 'menu.tpl', 'content/' . $template]; + foreach ($templateDependencies as $template) { + $includes = []; + preg_match_all('/\{include .*\}/', + file_get_contents(compile_path(['template', $template])), + $includes); + foreach ($includes[0] as $include) { + $externalPath = []; + if (preg_match('/file="(.*)"/', $include, $externalPath)) { + $templateDependencies[] = $externalPath[1]; + } + } + } + foreach (glob(compile_path(['config', '*.json'])) as $configFile) { + $templateDependencies[] = '../config/' . basename($configFile); + } + return max( + array_map( + function($file) { + return filemtime(compile_path(['template', $file])); + }, + $templateDependencies + ) + ); +} + +$outputDirectory = compile_path('static'); + +if (!file_exists($outputDirectory)) { + mkdir($outputDirectory); +} else { + if (!is_dir($outputDirectory)) { + throw new Exception('Output path already exists, but not a directory'); + } +} + +$templateDirectory = compile_path(['template', 'content']); + +if (!(file_exists($templateDirectory) && is_dir($templateDirectory))) { + throw new Exception('Template directory not found'); +} + +$inputDirectory = compile_path('http'); +if (is_link($inputDirectory)) { + $inputDirectory = compile_path('src'); +} + +$dynamicFiles = ['.htaccess', 'index.php']; +exec( + 'rsync -urLp ' + . implode( + ' ', + array_map( + function($file) { + return '--exclude=' . $file; + }, + $dynamicFiles + ) + ) . ' ' + . escapeshellarg($inputDirectory . DIRECTORY_SEPARATOR) . ' ' + . escapeshellarg($outputDirectory)); + +exec('find ' . escapeshellarg(compile_path('caches')) . ' -type f -delete'); + +$bootstrapper = compile_path(['include', 'setup.php']); +require_once($bootstrapper); + +$indexTemplates = ['index.tpl', 'main.tpl', 'home.tpl']; + +$indexTemplate = array_search(TRUE, array_map( + function($template) { + return file_exists(compile_path(['template', 'content', $template])); + }, + $indexTemplates +)); +if ($indexTemplate === FALSE) { + throw new Exception('Index template not found'); +} + +$filesToRender = ['index.html' => $indexTemplates[$indexTemplate], + '404.html' => '../404.tpl']; + +$directory = opendir($templateDirectory); +while ($file = readdir($directory)) { + $fileMatch = array(); + if (preg_match('/^(.*)\.tpl$/', $file, $fileMatch)) { + $filesToRender[$fileMatch[1] . DIRECTORY_SEPARATOR . 'index.html'] = $file; + } +} + +$lang = ($argc > 2) ? $argv[2] : ''; +Env::setLang($lang); + +$renderer = new MySmarty(); +$renderer->assign('lang', Env::lang()); + +$basePath = ($argc > 3) ? $argv[3] : '/'; +$renderer->assign('base', $basePath); + +try { + $scripts = Env::get('resources', 'scripts'); +} catch(EnvNoSuchEntryException $e) { + $scripts = []; +} +try { + $sheets = Env::get('resources', 'sheets'); +} catch(EnvNoSuchEntryException $e) { + $sheets = []; +} +try { + $minify = (bool)Env::get('resources', 'minify'); +} catch(EnvNoSuchEntryException $e) { + $minify = FALSE; +} +if ($minify && class_exists('Minify')) { + $minifiedJSPath = compile_path(['static', '_js', 'scripts.js']); + $minifiedJSHash = Minify::minifyJS($scripts, $minifiedJSPath); + $outputScripts = [ + basename($minifiedJSPath) . '?mtime=' . $minifiedJSHash + ]; + $minifiedCSSPath = compile_path(['static', '_css', 'styles.css']); + $minifiedCSSHash = Minify::minifyCSS($sheets, $minifiedCSSPath); + $outputSheets = [ + basename($minifiedCSSPath) . '?mtime=' . $minifiedCSSHash + ]; + foreach ($scripts as $script) { + unlink(compile_path(['static', '_js', $script])); + } + foreach ($sheets as $sheet) { + unlink(compile_path(['static', '_css', $sheet])); + } +} else { + $outputScripts = $scripts; + $outputSheets = $sheets; +} +foreach ($filesToRender as $output => $template) { + + $outputPath = compile_path(['static', $output]); + + if (!file_exists($outputPath) + || filemtime($outputPath) < get_template_mtime($template) + || filemtime($outputPath) < filemtime(__FILE__) + || ($minify && class_exists('Minify') && (filemtime($outputPath) < Minify::getMTime($scripts, $sheets)))) { + + $content = new MySmarty(); + $content->assign('lang', Env::lang()); + $menu = new MySmarty(); + try { + if (class_exists('Menu')) { + $menu->assign('items', Menu::getItems()); + $menu->assign('content', Menu::getActiveLink(preg_replace('/\.tpl$/', '', $template))); + } + } catch(EnvNoSuchEntryException $e) {} + $renderer->assign('menu', $menu->fetch('menu.tpl')); + $renderer->assign('content', $content->fetch('content/' . $template)); + $title = NULL; + try { + $title = Env::get('titles', preg_replace('/\.tpl$/', '', $template)); + } catch(EnvNoSuchEntryException $e) {} + $renderer->assign('title', $title); + $renderer->assign('scripts', $outputScripts); + $renderer->assign('sheets', $outputSheets); + $outputDir = implode( + DIRECTORY_SEPARATOR, + array_slice(explode(DIRECTORY_SEPARATOR, $outputPath), 0, -1) + ); + if (!is_dir($outputDir)) { + mkdir($outputDir); + } + file_put_contents($outputPath, $renderer->fetch('index.tpl')); + + } + +} + +if (!file_exists(compile_path(['static', '.htaccess']))) { + file_put_contents(compile_path(['static', '.htaccess']), + 'ErrorDocument 404 ' . rtrim($basePath, '/') . '/404.html' . PHP_EOL); +} + +?> -- cgit v1.2.3