diff --git a/.babelrc b/.babelrc index 684fff6..744c7d6 100644 --- a/.babelrc +++ b/.babelrc @@ -1 +1,13 @@ -{ "presets": ["env"] } +{ + "presets": [], + "plugins": [ + [ + "prismjs", + { + "languages": ["html", "markdown", "markup"], + "theme": "okaidia", + "css": false + } + ] + ] +} diff --git a/.gitignore b/.gitignore index e82f135..8107c7f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ node_modules/ src/node_modules/ +.parcel-cache/ .sass-cache/ .cache/ .nova/ diff --git a/brain/App.inc.php b/brain/App.inc.php index 6c48278..0ac8161 100644 --- a/brain/App.inc.php +++ b/brain/App.inc.php @@ -13,6 +13,7 @@ include "../brain/data/Member.inc.php"; include "../brain/data/Auth.inc.php"; include "../brain/data/Render.inc.php"; include "../brain/data/Themes.inc.php"; +include "../brain/data/Contents.inc.php"; include "../brain/utility/StringTools.inc.php"; include "../brain/utility/FileUploader.inc.php"; include "../brain/utility/DocTools.inc.php"; @@ -24,24 +25,24 @@ include "../brain/utility/HandleCors.inc.php"; class App { - public function __construct() - { - // set up cors - new HandleCors(); - $app = AppFactory::create(); - $twig = Twig::create("../brain/views/"); - $app->add(TwigMiddleware::create($app, $twig)); - //set up routing - $app->get( - "/[{first}[/{second}[/{third}[/{fourth}[/{fifth}]]]]]", - "\RouteControl:get" - ); - $app->post( - "/[{first}[/{second}[/{third}[/{fourth}]]]]", - "\RouteControl:post" - ); - //start the app + public function __construct() + { + // set up cors + new HandleCors(); + $app = AppFactory::create(); + $twig = Twig::create("../brain/views/"); + $app->add(TwigMiddleware::create($app, $twig)); + //set up routing + $app->get( + "/[{first}[/{second}[/{third}[/{fourth}[/{fifth}]]]]]", + "\RouteControl:get" + ); + $app->post( + "/[{first}[/{second}[/{third}[/{fourth}]]]]", + "\RouteControl:post" + ); + //start the app - $app->run(); - } + $app->run(); + } } diff --git a/brain/controller/DashControl.inc.php b/brain/controller/DashControl.inc.php index 1c26877..360bedc 100644 --- a/brain/controller/DashControl.inc.php +++ b/brain/controller/DashControl.inc.php @@ -76,11 +76,7 @@ class DashControl if (Session::active()) { $currentPage = isset($args["fourth"]) ? $args["fourth"] : 1; $filter = isset($args["third"]) ? $args["third"] : "all"; - $data = (new Book("../content/pages"))->getPages( - $currentPage, - 4, - $filter - ); + $data = (new Book())->getPages($currentPage, 4, $filter); $template = "dash/book.twig"; $pageOptions = [ "entryCount" => $data["entryCount"], @@ -102,9 +98,10 @@ class DashControl $template = "dash/page-edit.twig"; $mode = $args["third"]; $uuid = $args["fourth"]; + switch ($mode) { case "edit": - $page = (new Book("../content/pages"))->findPageById($uuid); + $page = (new Book())->findPageById($uuid); $views = []; if (str_contains($page["layout"], "index")) { $views = (new Themes())->getCustomIndex(); @@ -128,7 +125,7 @@ class DashControl ); $display = new \Twig\Environment($loader, []); - $book = new Book("../content/pages"); + $book = new Book(); $page = $book->findPageById($uuid); $pageOptions = Sorting::page($page); $preview = @@ -172,7 +169,7 @@ class DashControl $pageOptions = [ "title" => "Welcome Back", "status" => Session::active(), - "data" => (new Book("../content/pages"))->getPages(1, 4), + "data" => (new Book())->getPages(1, 4), ]; } else { $pageOptions = [ diff --git a/brain/controller/IndexControl.inc.php b/brain/controller/IndexControl.inc.php index 5643d85..615c4e6 100644 --- a/brain/controller/IndexControl.inc.php +++ b/brain/controller/IndexControl.inc.php @@ -63,18 +63,25 @@ class IndexControl break; default: - //check layout to see what page should be rendered - $template = $settings["global"]["theme"] . "/page.twig"; - $book = new Book("../content/pages"); - $page = $book->findPageBySlug($args["third"]); + //check if page is a menu item, if not render along path as usual + $page = []; + $book = new Book(); + if (is_numeric($args["first"])) { + $page = $book->findPageBySlug($args["third"]); + } else { + $page = $book->findPageBySlug($args["first"]); + } + $template = + $settings["global"]["theme"] . "/" . $page["layout"] . ".twig"; $pageOptions = Sorting::page($page); break; } } else { //index - $template = $settings["global"]["theme"] . "/index.twig"; - $book = new Book("../content/pages"); + $template = + $settings["global"]["theme"] . "/" . $page["layout"] . ".twig"; + $book = new Book(""); $page = $book->findPageBySlug(); $pageOptions = Sorting::page($page); } @@ -83,6 +90,7 @@ class IndexControl $response->getBody()->write($html); return $response; } else { + //if dynamic flag is false, load up html $view = Twig::fromRequest($request); $html = file_get_contents("../public/index.html"); $response->getBody()->write($html); diff --git a/brain/data/Book.inc.php b/brain/data/Book.inc.php index 03fc412..c4c40ce 100644 --- a/brain/data/Book.inc.php +++ b/brain/data/Book.inc.php @@ -1,29 +1,12 @@ read($folder); - } - public function read($folder) + public function __construct() { - $folders = glob("$folder/*", GLOB_ONLYDIR); - foreach ($folders as $folder) { - //$this->files[] = $folder . "/"; - $this->read($folder); - } - $files = array_filter(glob("$folder/*md"), "is_file"); - foreach ($files as $file) { - $this->files[] = $file; - } } public function findPageById(string $uuid) @@ -274,49 +257,9 @@ class Book } public function getContents() { - //move page collection to utiltiy class - $parser = new Parser(); - $contents = []; - foreach ($this->files as $file) { - $doc = $parser->parse(file_get_contents($file), false); - $meta = $doc->getYAML(); - $page = [ - "id" => $meta["id"], - "uuid" => $meta["uuid"], - "title" => $meta["title"], - "feature" => $meta["feature"], - "path" => $meta["path"], - "layout" => $meta["layout"], - "tags" => $meta["tags"], - "author" => $meta["author"], - "created" => date("Y M D d", $meta["created"]), - "updated" => date("Y M D d", $meta["updated"]), - "rawCreated" => $meta["created"], - "rawUpdated" => $meta["updated"], - "createdYear" => date("Y", $meta["created"]), - "createdMonth" => date("m", $meta["created"]), - "deleted" => $meta["deleted"], - "menu" => $meta["menu"], - "featured" => $meta["featured"], - "published" => $meta["published"], - "slug" => $meta["slug"], - "filePath" => $file, - "content" => $doc->getContent(), - ]; - //checks for duplicates - $uuid = $meta["uuid"]; - $found = current( - array_filter($contents, function ($item) use ($uuid) { - return isset($item["uuid"]) && $uuid == $item["uuid"]; - }) - ); - - // if uuid is not present, add it - if (!$found) { - array_push($contents, $page); - } - } - $contents = orderBy($contents, ["id"], ["desc"]); + //test new contents data class + //$new = (new Contents("../content/pages"))->getAll(); + $contents = (new Contents("../content/pages"))->getAll(); return $contents; } } diff --git a/brain/data/Contents.inc.php b/brain/data/Contents.inc.php new file mode 100644 index 0000000..00091f7 --- /dev/null +++ b/brain/data/Contents.inc.php @@ -0,0 +1,120 @@ +read($folder); + } + public function read($folder) + { + $folders = glob("$folder/*", GLOB_ONLYDIR); + foreach ($folders as $folder) { + //$this->files[] = $folder . "/"; + $this->read($folder); + } + $files = array_filter(glob("$folder/*md"), "is_file"); + foreach ($files as $file) { + $this->files[] = $file; + } + } + + function getAll() + { + $environment = new Environment($this->config); + $environment->addExtension(new CommonMarkCoreExtension()); + + // Add the extension + $environment->addExtension(new FrontMatterExtension()); + + //Add Strikethrough rendering + $environment->addExtension(new StrikethroughExtension()); + + //add attributes to elements in markdown + $environment->addExtension(new AttributesExtension()); + + // Instantiate the converter engine and start converting some Markdown! + $converter = new MarkdownConverter($environment); + + $contents = []; + foreach ($this->files as $file) { + //get meta and html from file + $result = $converter->convertToHtml(file_get_contents($file)); + $meta = []; + if ($result instanceof RenderedContentWithFrontMatter) { + $meta = $result->getFrontMatter(); + } + + //get raw markdown from file + $frontMatterExtension = new FrontMatterExtension(); + $parsed = $frontMatterExtension + ->getFrontMatterParser() + ->parse(file_get_contents($file)); + + //never trust the front end. clean it up + $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($result->getContent()); + + //sort attributes into page object + $page = [ + "id" => $meta["id"], + "uuid" => $meta["uuid"], + "title" => $meta["title"], + "feature" => $meta["feature"], + "path" => $meta["path"], + "layout" => $meta["layout"], + "tags" => $meta["tags"], + "author" => $meta["author"], + "created" => date("Y M D d", $meta["created"]), + "updated" => date("Y M D d", $meta["updated"]), + "rawCreated" => $meta["created"], + "rawUpdated" => $meta["updated"], + "createdYear" => date("Y", $meta["created"]), + "createdMonth" => date("m", $meta["created"]), + "deleted" => $meta["deleted"], + "menu" => $meta["menu"], + "featured" => $meta["featured"], + "published" => $meta["published"], + "slug" => $meta["slug"], + "filePath" => $file, + "content" => $parsed->getContent(), + "html" => $scrubbed, + ]; + //checks for duplicates + $uuid = $meta["uuid"]; + $found = current( + array_filter($contents, function ($item) use ($uuid) { + return isset($item["uuid"]) && $uuid == $item["uuid"]; + }) + ); + + // if uuid is not present, add it + if (!$found) { + array_push($contents, $page); + } + } + $contents = orderBy($contents, ["id"], ["desc"]); + return $contents; + } +} diff --git a/brain/data/Render.inc.php b/brain/data/Render.inc.php index cb31f3d..e3b745d 100644 --- a/brain/data/Render.inc.php +++ b/brain/data/Render.inc.php @@ -69,129 +69,30 @@ class Render public function renderPages() { - $pages = (new Book("../content/pages"))->getContents(); + $pages = (new Book())->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"], - "feature" => $page["feature"], - ]); - } - - if ($page["featured"] == true) { - if (count($featured) < $limit) { - array_push($featured, [ - "path" => $page["path"], - "slug" => $page["slug"], - "title" => $page["title"], - "feature" => $page["feature"], - ]); - } - } - - $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, - ]; + $pageOptions = Sorting::page($page); + $template = $this->theme . "/" . $page["layout"] . ".twig"; + if (str_contains($page["layout"], "index")) { + $location = "../public/index.html"; + $dir = null; + } else { + // if page is a menu item, render the page on public root + if ($page["menu"] == "true") { + $location = "../public/" . $page["slug"] . ".html"; + $dir = "../public/"; } 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); } + + $html = $this->twig->render($template, $pageOptions); + DocTools::writeHTML($location, $html, $dir); } } @@ -247,7 +148,8 @@ class Render public function renderIndex() { - $pages = (new Book("../content/pages"))->getContents(); + //TODO: Need to fix this to account for new index templating system + $pages = (new Book())->getContents(); $index = find($pages, ["layout" => "index"]); $template = $this->theme . "/index.twig"; $location = "../public/index.html"; diff --git a/brain/utility/Sorting.inc.php b/brain/utility/Sorting.inc.php index 09bec8a..475a0ca 100644 --- a/brain/utility/Sorting.inc.php +++ b/brain/utility/Sorting.inc.php @@ -179,10 +179,13 @@ class Sorting $recent = []; $featured = []; $limit = 4; - $pages = (new Book("../content/pages"))->getContents(); + $pages = (new Book())->getContents(); foreach ($pages as $item) { - //TODO: Move page data organization to render to utility class - if (!$item["deleted"] && $item["published"]) { + if ( + !$item["deleted"] && + $item["published"] && + $item["menu"] != "true" + ) { if (count($recent) < $limit) { array_push($recent, [ "path" => $item["path"], @@ -206,7 +209,7 @@ class Sorting $pageOptions = [ "title" => $page["title"], "background" => $page["feature"], - "content" => $cleaned, + "content" => $page["html"], //$cleaned, "meta" => $meta, "recent" => $recent, "featured" => $featured, @@ -221,7 +224,7 @@ class Sorting $pageOptions = [ "title" => $page["title"], "background" => $page["feature"], - "content" => $cleaned, + "content" => $page["html"], //$cleaned, "meta" => $meta, "info" => $pageInfo, "menu" => $settings["menu"], diff --git a/brain/views/dash/book.twig b/brain/views/dash/book.twig index a769ff0..5cb33c5 100644 --- a/brain/views/dash/book.twig +++ b/brain/views/dash/book.twig @@ -120,5 +120,5 @@ {% endblock %} {% block javascripts %} - + {% endblock %} \ No newline at end of file diff --git a/brain/views/dash/init.twig b/brain/views/dash/init.twig index 3187c54..fcae15e 100644 --- a/brain/views/dash/init.twig +++ b/brain/views/dash/init.twig @@ -44,5 +44,5 @@ {% endblock %} {% block javascripts %} - + {% endblock %} \ No newline at end of file diff --git a/brain/views/dash/navigation.twig b/brain/views/dash/navigation.twig index 257e42f..e2d2e2c 100644 --- a/brain/views/dash/navigation.twig +++ b/brain/views/dash/navigation.twig @@ -39,5 +39,5 @@ {% endblock %} {% block javascripts %} - + {% endblock %} \ No newline at end of file diff --git a/brain/views/dash/page-edit.twig b/brain/views/dash/page-edit.twig index 9fc8d08..5a29d49 100644 --- a/brain/views/dash/page-edit.twig +++ b/brain/views/dash/page-edit.twig @@ -32,7 +32,7 @@ {% endblock %} {% block stylesheets %} - + {% endblock %} {% block mainContent %} @@ -106,7 +106,12 @@ {{ include("dash/partials/editor.twig") }} {% endapply %}
{{- content -}}
+
+
+
+
+
+