|
|
|
<?php
|
|
|
|
use Mni\FrontYAML\Parser;
|
|
|
|
use function _\find;
|
|
|
|
|
|
|
|
class Render
|
|
|
|
{
|
|
|
|
public $loader;
|
|
|
|
public $twig;
|
|
|
|
public $pageInfo;
|
|
|
|
public $menu;
|
|
|
|
public $background;
|
|
|
|
public function __construct()
|
|
|
|
{
|
|
|
|
$config = new Settings();
|
|
|
|
$this->loader = new \Twig\Loader\FilesystemLoader("../content/themes");
|
|
|
|
$this->twig = new \Twig\Environment($this->loader, []);
|
|
|
|
$settings = $config->getSettings();
|
|
|
|
$this->menu = $settings["menu"];
|
|
|
|
$this->theme = $settings["global"]["theme"];
|
|
|
|
$this->pageInfo = [
|
|
|
|
"keywords" => isset($settings["global"]["keywords"])
|
|
|
|
? $settings["global"]["keywords"]
|
|
|
|
: "fipamo, blog, jamstack, php, markdown, js",
|
|
|
|
"description" => $settings["global"]["descriptions"],
|
|
|
|
"image" =>
|
|
|
|
$settings["global"]["base_url"] . $settings["global"]["background"],
|
|
|
|
"baseURL" => $settings["global"]["base_url"],
|
|
|
|
];
|
|
|
|
//move global theme image assets to public folder
|
|
|
|
foreach (
|
|
|
|
new DirectoryIterator(
|
|
|
|
"../content/themes/" . $this->theme . "/assets/images/global/"
|
|
|
|
)
|
|
|
|
as $file
|
|
|
|
) {
|
|
|
|
if ($file->isDot()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!is_file("../public/assets/images/global/" . $file->getFileName())) {
|
|
|
|
copy(
|
|
|
|
"../content/themes/" .
|
|
|
|
$this->theme .
|
|
|
|
"/assets/images/global/" .
|
|
|
|
$file->getFileName(),
|
|
|
|
"../public/assets/images/global/" . $file->getFileName()
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
//image is already there, so chill
|
|
|
|
}
|
|
|
|
//print $file->getFilename() . "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
//copy current theme assets to public
|
|
|
|
if (is_file("../public/assets/css/base.css")) {
|
|
|
|
unlink("../public/assets/css/base.css");
|
|
|
|
}
|
|
|
|
copy(
|
|
|
|
"../content/themes/" . $this->theme . "/assets/css/base.css",
|
|
|
|
"../public/assets/css/base.css"
|
|
|
|
);
|
|
|
|
if (is_file("../public/assets/scripts/start.min.js")) {
|
|
|
|
unlink("../public/assets/scripts/start.min.js");
|
|
|
|
}
|
|
|
|
copy(
|
|
|
|
"../content/themes/" . $this->theme . "/assets/scripts/start.min.js",
|
|
|
|
"../public/assets/scripts/start.min.js"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function renderPages()
|
|
|
|
{
|
|
|
|
$pages = (new Book("../content/pages"))->getContents();
|
|
|
|
$recent = [];
|
|
|
|
$featured = [];
|
|
|
|
$limit = 4;
|
|
|
|
foreach ($pages as $page) {
|
|
|
|
//TODO: Move page data organization to render to utility class
|
|
|
|
if (!$page["deleted"] && $page["published"]) {
|
|
|
|
if (count($recent) < $limit) {
|
|
|
|
array_push($recent, [
|
|
|
|
"path" => $page["path"],
|
|
|
|
"slug" => $page["slug"],
|
|
|
|
"title" => $page["title"],
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($page["featured"] == true) {
|
|
|
|
if (count($featured) < $limit) {
|
|
|
|
array_push($featured, [
|
|
|
|
"path" => $page["path"],
|
|
|
|
"slug" => $page["slug"],
|
|
|
|
"title" => $page["title"],
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$taglist = explode(",", $page["tags"]);
|
|
|
|
$tags = [];
|
|
|
|
foreach ($taglist as $tag) {
|
|
|
|
$label = trim($tag);
|
|
|
|
array_push($tags, [
|
|
|
|
"label" => $label . " ",
|
|
|
|
"slug" => StringTools::safeString($label),
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
|
|
|
$meta = [
|
|
|
|
"who" => $page["author"],
|
|
|
|
"when" => $page["created"],
|
|
|
|
"tags" => $tags,
|
|
|
|
];
|
|
|
|
|
|
|
|
//render markdown content and clean it
|
|
|
|
$parser = new Parser();
|
|
|
|
$rendered = $parser->parse($page["content"]);
|
|
|
|
$sanitizer = HtmlSanitizer\Sanitizer::create([
|
|
|
|
"extensions" => ["basic", "image", "list", "code"],
|
|
|
|
"tags" => [
|
|
|
|
"img" => [
|
|
|
|
"allowed_attributes" => ["src", "alt", "title", "class"],
|
|
|
|
"allowed_hosts" => null,
|
|
|
|
"allow_relative_links" => true,
|
|
|
|
],
|
|
|
|
],
|
|
|
|
]);
|
|
|
|
|
|
|
|
$scrubbed = $sanitizer->sanitize($rendered->getContent());
|
|
|
|
|
|
|
|
//var_dump($scrubbed);
|
|
|
|
|
|
|
|
//just clean renderd string for now, Sanitize doesn't like relative img urls
|
|
|
|
//so another option is needed
|
|
|
|
$cleaned = strip_tags($rendered->getContent(), [
|
|
|
|
"a",
|
|
|
|
"br",
|
|
|
|
"p",
|
|
|
|
"strong",
|
|
|
|
"br",
|
|
|
|
"img",
|
|
|
|
"iframe",
|
|
|
|
"ul",
|
|
|
|
"li",
|
|
|
|
"i",
|
|
|
|
"em",
|
|
|
|
"h1",
|
|
|
|
"h2",
|
|
|
|
"h3",
|
|
|
|
"pre",
|
|
|
|
"code",
|
|
|
|
]);
|
|
|
|
//$cleaned = preg_replace('/(?:\r\n|[\r\n]){2,}/', "\n\n", $cleaned);
|
|
|
|
//$cleaned = html_entity_decode($cleaned, ENT_QUOTES, "UTF-8");
|
|
|
|
|
|
|
|
//if page feature isn't empty, replace page info meta image
|
|
|
|
if ($page["feature"] != "" || $page["feature"] != null) {
|
|
|
|
$this->pageInfo["image"] =
|
|
|
|
$this->pageInfo["baseURL"] . $page["feature"];
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($page["layout"] == "index") {
|
|
|
|
$template = $this->theme . "/index.twig";
|
|
|
|
$location = "../public/index.html";
|
|
|
|
$dir = null;
|
|
|
|
|
|
|
|
$pageOptions = [
|
|
|
|
"title" => $page["title"],
|
|
|
|
"background" => $page["feature"],
|
|
|
|
"content" => $scrubbed,
|
|
|
|
"meta" => $meta,
|
|
|
|
"recent" => $recent,
|
|
|
|
"featured" => $featured,
|
|
|
|
"info" => $this->pageInfo,
|
|
|
|
"menu" => $this->menu,
|
|
|
|
];
|
|
|
|
} else {
|
|
|
|
$template = $this->theme . "/" . $page["layout"] . ".twig";
|
|
|
|
$location =
|
|
|
|
"../public/" . $page["path"] . "/" . $page["slug"] . ".html";
|
|
|
|
$dir = "../public/" . $page["path"];
|
|
|
|
$pageOptions = [
|
|
|
|
"title" => $page["title"],
|
|
|
|
"background" => $page["feature"],
|
|
|
|
"content" => $cleaned,
|
|
|
|
"meta" => $meta,
|
|
|
|
"info" => $this->pageInfo,
|
|
|
|
"menu" => $this->menu,
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
$html = $this->twig->render($template, $pageOptions);
|
|
|
|
DocTools::writeHTML($location, $html, $dir);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function renderArchive()
|
|
|
|
{
|
|
|
|
$archive = Sorting::archive();
|
|
|
|
$template = $this->theme . "/archive.twig";
|
|
|
|
$pageOptions = [
|
|
|
|
"title" => "Archive",
|
|
|
|
"background" => $this->pageInfo["image"],
|
|
|
|
"archives" => $archive,
|
|
|
|
"info" => $this->pageInfo,
|
|
|
|
"menu" => $this->menu,
|
|
|
|
];
|
|
|
|
|
|
|
|
$html = $this->twig->render($template, $pageOptions);
|
|
|
|
$location = "../public/archives.html";
|
|
|
|
DocTools::writeHTML($location, $html);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function renderTags()
|
|
|
|
{
|
|
|
|
$list = Sorting::tags();
|
|
|
|
foreach ($list as $item) {
|
|
|
|
$template = $this->theme . "/tags.twig";
|
|
|
|
$pageOptions = [
|
|
|
|
"title" => "Pages Tagged as " . $item["tag_name"],
|
|
|
|
"background" => $this->pageInfo["image"],
|
|
|
|
"tag_list" => $item["pages"],
|
|
|
|
"info" => $this->pageInfo,
|
|
|
|
"menu" => $this->menu,
|
|
|
|
];
|
|
|
|
|
|
|
|
$html = $this->twig->render($template, $pageOptions);
|
|
|
|
|
|
|
|
$location = "../public/tags/" . $item["slug"] . ".html";
|
|
|
|
|
|
|
|
//if tags folder doesn't exist, make it
|
|
|
|
if (!is_dir("../public/tags")) {
|
|
|
|
mkdir("../public/tags", 0755, true);
|
|
|
|
} else {
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!is_file($location)) {
|
|
|
|
file_put_contents($location, $html);
|
|
|
|
} else {
|
|
|
|
($new = fopen($location, "w")) or die("Unable to open file!");
|
|
|
|
fwrite($new, $html);
|
|
|
|
fclose($new);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function renderIndex()
|
|
|
|
{
|
|
|
|
$pages = (new Book("../content/pages"))->getContents();
|
|
|
|
$index = find($pages, ["layout" => "index"]);
|
|
|
|
$template = $this->theme . "/index.twig";
|
|
|
|
$location = "../public/index.html";
|
|
|
|
$dir = null;
|
|
|
|
|
|
|
|
$meta = [
|
|
|
|
"who" => $index["author"],
|
|
|
|
"when" => $index["created"],
|
|
|
|
];
|
|
|
|
|
|
|
|
$pageOptions = [
|
|
|
|
"title" => $index["title"],
|
|
|
|
"background" => $index["feature"],
|
|
|
|
"meta" => $meta,
|
|
|
|
];
|
|
|
|
|
|
|
|
$html = $this->twig->render($template, $pageOptions);
|
|
|
|
DocTools::writeHTML($location, $html, $dir);
|
|
|
|
}
|
|
|
|
}
|