- **Metadata** for title, description, and robots meta tag for each site (YAML font matter)
- Provides simple **Shortcodes** to arrange and style your content (e.g. columns, different backgrounds)
- Basic, responsive **Theme** which you can customize and enhance
+- Option to use individual **Templates** for single pages
## Demo
The [Demo Website](https://flatmark.elektrischerwalfisch.de) is an exact copy of the [GitHub Repository](https://github.com/elektrischerwalfisch/flatmark) and doubles as the documentation site.
- **title** → Sets the `<title>` of the page. Defaults to the filename if not provided.
- **description** → Used for the `<meta name="description">` tag (important for SEO). Defaults to an empty string if not set.
- **robots** → Controls search engine indexing (index, follow / noindex, nofollow). Defaults to index, follow.
+- **layout** → Sets individual template for the page, find further infos below under "Customization".
## Shortcodes
flatMark supports simple shortcodes for structured content. You can see all shortcodes in action on the [Examples-Page](https://flatmark.elektrischerwalfisch.de/en/examples) of theDemo Website. Here are just two examples:
## Customization
-All customizable parts of flatMark are located in the `theme/` folder. This includes the main stylesheet (`theme/css/style.css`), a JavaScript file for interactive behavior (`theme/js/presets.js`), and the `theme/functions.php` file where custom shortcodes can be defined. You can freely modify these files to match your design and functionality needs. Additional assets like images, fonts, or scripts can also be placed in this folder to keep everything neatly organized in one place.
+All customizable parts of flatMark are located in the `theme/` folder:
+- Styling with CSS main-stylesheet: `theme/css/style.css`
+- Interactive with JavaScript: `theme/js/presets.js`
+- Additional php-fuctions (like Shortcodes): `theme/functions.php`
+- Default HTML template: `theme/index.php`
+
+Additional assets like fonts, favicons and images can also be placed in the theme-folder to keep everything neatly organized in one place.
+
+**Templates**
+Further HTML-templates can be added in the theme folder and addressed via metadata. Example: For a page including the metadata `layout: blog.php` the template `theme/blog.php` would be used, instead of the default-template `theme/index.php`.
## flatMark as CMS
<?php
/**
* Project: flatMark
- * Version: 1.1.0
+ * Version: 1.1.1
*
* Project URI: https://github.com/elektrischerwalfisch/flatmark
* Author: elektrischerwalfisch
// Convert Markdown to HTML
$htmlContent = $Parsedown->text($markdown);
-?>
-
-<!DOCTYPE html>
-<html lang="<?= htmlspecialchars($lang) ?>">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title><?= htmlspecialchars($pageMeta['title']) ?></title>
- <meta name="description" content="<?= htmlspecialchars($pageMeta['description']) ?>">
- <meta name="robots" content="<?= htmlspecialchars($pageMeta['robots']) ?>">
- <link rel="stylesheet" href="/theme/css/style.css">
- </head>
- <body>
- <div id="wrapper">
- <header>
- <?= $headerContent ?>
- </header>
- <main id="main">
- <?= $htmlContent ?>
- </main>
- <footer>
- <?= $footerContent ?>
- </footer>
- <script src="/theme/js/presets.js"></script>
- </div>
- </body>
-</html>
+ // Load HTML template
+ $layout = $pageMeta['layout'] ?? 'index'; // Set template from pageMeta or use /theme/index.php as fallback
+ $templateFile = __DIR__ . "/theme/{$layout}.php"; // Build full path to template
+ // Show warning if template does not exist
+ if (!file_exists($templateFile)) {
+ http_response_code(500);
+ echo "Template '{$layout}.php' not found in theme folder.";
+ exit;
+ }
+ require $templateFile; // Load template
-<?php
- ob_end_flush(); // Flush output buffer
+ // Flush output buffer
+ ob_end_flush();
?>
\ No newline at end of file
header #main-nav ul a {display: block;font-size: var(--fontsize-m);line-height: 1.6;font-weight: 700;color: var(--colorlight); text-decoration: none;padding: 0 var(--side-space-01);border-bottom: 2px solid var(--color-01);border-top: 2px solid var(--color-01);}
header #main-nav ul a:is(:hover, :focus, .active) {background: var(--colorlight);color: var(--color-01); outline: 0;}
+/* Menu Subpages*/
+@media screen and (min-width: 782px) {
+ header #main-nav ul li:has(ul) {position: relative;}
+ header #main-nav ul > li > ul {position: absolute; display: block;}
+ header #main-nav ul > li > ul > li > a {white-space: nowrap;border: none;display: block; height: 0;overflow: hidden;transition: var(--animation-01);}
+ header #main-nav ul li:is(:hover, :focus-within) > ul > li > a {height: 26px;}
+}
+
#toggle-nav {display: none;}
main {padding: 0 var(--side-space-02) var(--space-below-01) var(--side-space-02);margin-bottom: var(--space-below-01);}
main .background .img-rounded {border: var(--space-below-01) solid var(--colorlight); margin-top: calc(0px - var(--space-below-02));}
main .img-rounded img {object-fit: cover;width: 100%;height: 100%;display: block;}
-main .button {}
main .button a {display: inline-block;background: var(--colordark);color: var(--colorlight);text-decoration:none;padding: var(--space-below-00) var(--side-space-01);font-weight: 700;}
main .button a:hover {opacity: 0.5;}
main .button.bg-color-01 a {background: var(--color-01);}
main code {font-family: courier 'Courier New', Courier, monospace;font-size: var(--fontsize-m);background: var(--color-gray-01);color: var(--colordark);}
-#main pre:has(code) {word-break: normal;word-wrap: normal;overflow: scroll;background: var(--color-gray-01);padding: var(--space-below-01) var(--space-below-01);border-radius: 10px;margin-bottom: var(--space-below-01);}
+main pre:has(code) {word-break: normal;word-wrap: normal;overflow: scroll;background: var(--color-gray-01);padding: var(--space-below-01) var(--space-below-01);border-radius: 10px;margin-bottom: var(--space-below-01);}
-#main .readme h1,
-#main .readme em {display: none;}
+main .readme h1,
+main .readme em {display: none;}
footer {text-align: center;font-size: var(--fontsize-s);}
footer p {margin-bottom: var(--space-below-00);}
header.menu-active #toggle-nav span:last-child {opacity: 1;transform: rotate(-45deg);}
header #main-nav {padding-top: 0;}
header #main-nav ul {display: block;}
- header #main-nav ul li {overflow: hidden;height: 0;transition: var(--animation-01);}
+ header #main-nav ul li a {overflow: hidden;height: 0;transition: var(--animation-01);}
header #main-nav ul a {font-size: var(--fontsize-l);border: none;}
- header.menu-active #main-nav ul li {height: 40px!important;}
+ header #main-nav ul ul a {font-size: var(--fontsize-m); padding-left: var(--side-space-02);}
+ header.menu-active #main-nav ul li a {height: 40px;}
+ header.menu-active #main-nav ul ul li a {height: 26px;}
h1 {font-size: var(--fontsize-xl);}
--- /dev/null
+<?php
+/**
+ * Main HTML Template
+ *
+ * This template outputs the complete HTML structure of the site.
+ * It is loaded by the main index.php as default template after parsing content and metadata.
+ *
+ * @package flatMark
+ * @subpackage Theme
+ *
+ */
+?>
+
+<!DOCTYPE html>
+<html lang="<?= htmlspecialchars($lang) ?>">
+ <head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title><?= htmlspecialchars($pageMeta['title']) ?></title>
+ <meta name="description" content="<?= htmlspecialchars($pageMeta['description']) ?>">
+ <meta name="robots" content="<?= htmlspecialchars($pageMeta['robots']) ?>">
+ <link rel="stylesheet" href="/theme/css/style.css">
+ </head>
+ <body>
+ <div id="wrapper">
+ <header>
+ <?= $headerContent ?>
+ </header>
+ <main id="main">
+ <?= $htmlContent ?>
+ </main>
+ <footer>
+ <?= $footerContent ?>
+ </footer>
+ <script src="/theme/js/presets.js"></script>
+ </div>
+ </body>
+</html>
\ No newline at end of file