and plugins are prefixed with ``M_``. Configuration variables without
prefix are builtin Pelican options.
-.. note-warning::
-
- The above configuration should be enough to produce a (mostly empty)
- version of your website using the theme without any errors during
- processing. If that's not the case, please :gh:`report a bug <mosra/m.css/issues/new>`.
- Thank you!
-
`Configuration`_
================
--- /dev/null
+import os
+import shutil
+import unittest
+
+from pelican import read_settings, Pelican
+
+class MinimalTestCase(unittest.TestCase):
+ def __init__(self, path, dir, *args, **kwargs):
+ unittest.TestCase.__init__(self, *args, **kwargs)
+ # Source files for test_something.py are in something_{dir}/ subdirectory
+ self.path = os.path.join(os.path.dirname(os.path.realpath(path)), os.path.splitext(os.path.basename(path))[0][5:] + ('_' + dir if dir else ''))
+
+ # Display ALL THE DIFFS
+ self.maxDiff = None
+
+ def setUp(self):
+ if os.path.exists(os.path.join(self.path, 'output')): shutil.rmtree(os.path.join(self.path, 'output'))
+
+ def run_pelican(self, settings):
+ implicit_settings = {
+ # Contains just stuff that isn't required by the m.css theme itself,
+ # but is needed to have the test setup working correctly
+ 'RELATIVE_URLS': True,
+ 'TIMEZONE': 'UTC',
+ 'READERS': {'html': None},
+ 'SITEURL': '.',
+ 'PATH': os.path.join(self.path),
+ 'OUTPUT_PATH': os.path.join(self.path, 'output'),
+ 'PAGE_EXCLUDES': [os.path.join(self.path, 'output')],
+ 'ARTICLE_EXCLUDES': [os.path.join(self.path, 'output')],
+ 'FEED_ALL_ATOM': None, # Don't render feeds, we're not testing them *ever*
+ }
+ settings = read_settings(path=None, override={**implicit_settings, **settings})
+ pelican = Pelican(settings=settings)
+ pelican.run()
+
+ def actual_expected_contents(self, actual, expected = None):
+ if not expected: expected = actual
+
+ with open(os.path.join(self.path, expected)) as f:
+ expected_contents = f.read().strip()
+ with open(os.path.join(self.path, 'output', actual)) as f:
+ actual_contents = f.read().strip()
+ return actual_contents, expected_contents
+
+class BaseTestCase(MinimalTestCase):
+ def run_pelican(self, settings):
+ implicit_settings = {
+ 'THEME': '.',
+ 'PLUGIN_PATHS': ['../pelican-plugins'],
+ 'PLUGINS': ['m.htmlsanity'],
+ 'THEME_STATIC_DIR': 'static',
+ 'M_CSS_FILES': ['https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i',
+ 'static/m-dark.css'],
+ # i.e., not rendering the category, tag and author lists as they
+ # are not supported anyway
+ 'DIRECT_TEMPLATES': ['index', 'archives'],
+ 'SLUGIFY_SOURCE': 'basename'
+ }
+ MinimalTestCase.run_pelican(self, {**implicit_settings, **settings})
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>Features | Your Brand</title>
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i" />
+ <link rel="stylesheet" href="static/m-dark.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta property="og:title" content="Features" />
+ <meta name="twitter:title" content="Features" />
+ <meta property="og:url" content="features.html" />
+ <meta name="twitter:url" content="features.html" />
+ <meta name="twitter:card" content="summary" />
+ <meta property="og:type" content="website" />
+</head>
+<body>
+<header><nav id="navigation">
+ <div class="m-container">
+ <div class="m-row">
+ <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">Your.brand</a>
+ <a id="m-navbar-show" href="#navigation" title="Show navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+ <a id="m-navbar-hide" href="#" title="Hide navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+ <div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
+ <div class="m-row">
+ <ol class="m-col-t-6 m-col-m-none">
+ <li><a href="features.html" id="m-navbar-current">Features</a></li>
+ <li>
+ <a href="./">Showcase</a>
+ <ol>
+ <li><a href="showcase-requirements.html">Requirements</a></li>
+ <li><a href="http://demo.your.brand/">Live demo</a></li>
+ <li><a href="mailto:you@your.brand">Get a quote</a></li>
+ </ol>
+ </li>
+ <li><a href="./">Download</a></li>
+ </ol>
+ <ol class="m-col-t-6 m-col-m-none" start="4">
+ <li>
+ <a href="archives.html">Blog</a>
+ <ol>
+ <li><a href="./">News</a></li>
+ <li><a href="./">Archive</a></li>
+ <li><a href="guest-post-howto.html">Write a guest post</a></li>
+ </ol>
+ </li>
+ <li><a href="./">Contact</a></li>
+ </ol>
+ </div>
+ </div>
+ </div>
+ </div>
+</nav></header>
+<main>
+<article>
+ <div class="m-container m-container-inflatable">
+ <div class="m-row">
+ <div class="m-col-l-10 m-push-l-1">
+ <h1>Features</h1>
+ </div>
+ </div>
+ </div>
+</article>
+</main>
+<footer><nav>
+ <div class="m-container">
+ <div class="m-row">
+ <div class="m-col-s-3 m-col-t-6">
+ <h3><a href="index.html">Your Brand</a></h3>
+ <ul>
+ <li><a href="./">Mission</a></li>
+ <li> </li>
+ <li><a href="./">The People</a></li>
+ </ul>
+ </div>
+ <div class="m-col-s-3 m-col-t-6">
+ <h3><a href="features.html">Features</a></h3>
+ <ul>
+ <li> </li>
+ <li><a href="http://demo.your.brand/">Live demo</a></li>
+ <li><a href="showcase-requirements.html">Requirements</a></li>
+ </ul>
+ </div>
+ <div class="m-clearfix-t"></div>
+ <div class="m-col-s-3 m-col-t-6">
+ <h3>Download</h3>
+ <ul>
+ <li><a href="./">Packages</a></li>
+ <li> </li>
+ <li><a href="./">Source</a></li>
+ </ul>
+ </div>
+ <div class="m-col-s-3 m-col-t-6">
+ <h3>Contact</h3>
+ <ul>
+ <li><a href="mailto:you@your.brand">E-mail</a></li>
+ <li> </li>
+ <li><a href="https://github.com/your-brand">GitHub</a></li>
+ </ul>
+ </div>
+ </div>
+ <div class="m-row">
+ <div class="m-col-l-10 m-push-l-1">
+ <p>Your Brand. Copyright © <a href="mailto:you@your.brand">You</a>, 2017.
+ All rights reserved.</p>
+ </div>
+ </div>
+ </div>
+</nav></footer>
+</body>
+</html>
--- /dev/null
+Features
+########
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>Guest post howto | Your Brand</title>
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i" />
+ <link rel="stylesheet" href="static/m-dark.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta property="og:title" content="Guest post howto" />
+ <meta name="twitter:title" content="Guest post howto" />
+ <meta property="og:url" content="guest-post-howto.html" />
+ <meta name="twitter:url" content="guest-post-howto.html" />
+ <meta name="twitter:card" content="summary" />
+ <meta property="og:type" content="website" />
+</head>
+<body>
+<header><nav id="navigation">
+ <div class="m-container">
+ <div class="m-row">
+ <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">Your.brand</a>
+ <a id="m-navbar-show" href="#navigation" title="Show navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+ <a id="m-navbar-hide" href="#" title="Hide navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+ <div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
+ <div class="m-row">
+ <ol class="m-col-t-6 m-col-m-none">
+ <li><a href="features.html">Features</a></li>
+ <li>
+ <a href="./">Showcase</a>
+ <ol>
+ <li><a href="showcase-requirements.html">Requirements</a></li>
+ <li><a href="http://demo.your.brand/">Live demo</a></li>
+ <li><a href="mailto:you@your.brand">Get a quote</a></li>
+ </ol>
+ </li>
+ <li><a href="./">Download</a></li>
+ </ol>
+ <ol class="m-col-t-6 m-col-m-none" start="4">
+ <li>
+ <a href="archives.html">Blog</a>
+ <ol>
+ <li><a href="./">News</a></li>
+ <li><a href="./">Archive</a></li>
+ <li><a href="guest-post-howto.html" id="m-navbar-current">Write a guest post</a></li>
+ </ol>
+ </li>
+ <li><a href="./">Contact</a></li>
+ </ol>
+ </div>
+ </div>
+ </div>
+ </div>
+</nav></header>
+<main>
+<article>
+ <div class="m-container m-container-inflatable">
+ <div class="m-row">
+ <div class="m-col-l-10 m-push-l-1">
+ <h1>Guest post howto</h1>
+ </div>
+ </div>
+ </div>
+</article>
+</main>
+<footer><nav>
+ <div class="m-container">
+ <div class="m-row">
+ <div class="m-col-s-3 m-col-t-6">
+ <h3><a href="index.html">Your Brand</a></h3>
+ <ul>
+ <li><a href="./">Mission</a></li>
+ <li> </li>
+ <li><a href="./">The People</a></li>
+ </ul>
+ </div>
+ <div class="m-col-s-3 m-col-t-6">
+ <h3><a href="features.html">Features</a></h3>
+ <ul>
+ <li> </li>
+ <li><a href="http://demo.your.brand/">Live demo</a></li>
+ <li><a href="showcase-requirements.html">Requirements</a></li>
+ </ul>
+ </div>
+ <div class="m-clearfix-t"></div>
+ <div class="m-col-s-3 m-col-t-6">
+ <h3>Download</h3>
+ <ul>
+ <li><a href="./">Packages</a></li>
+ <li> </li>
+ <li><a href="./">Source</a></li>
+ </ul>
+ </div>
+ <div class="m-col-s-3 m-col-t-6">
+ <h3>Contact</h3>
+ <ul>
+ <li><a href="mailto:you@your.brand">E-mail</a></li>
+ <li> </li>
+ <li><a href="https://github.com/your-brand">GitHub</a></li>
+ </ul>
+ </div>
+ </div>
+ <div class="m-row">
+ <div class="m-col-l-10 m-push-l-1">
+ <p>Your Brand. Copyright © <a href="mailto:you@your.brand">You</a>, 2017.
+ All rights reserved.</p>
+ </div>
+ </div>
+ </div>
+</nav></footer>
+</body>
+</html>
--- /dev/null
+Guest post howto
+################
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>Your Brand Blog</title>
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i" />
+ <link rel="stylesheet" href="static/m-dark.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</head>
+<body>
+<header><nav id="navigation">
+ <div class="m-container">
+ <div class="m-row">
+ <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">Your.brand</a>
+ <a id="m-navbar-show" href="#navigation" title="Show navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+ <a id="m-navbar-hide" href="#" title="Hide navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+ <div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
+ <div class="m-row">
+ <ol class="m-col-t-6 m-col-m-none">
+ <li><a href="features.html">Features</a></li>
+ <li>
+ <a href="./">Showcase</a>
+ <ol>
+ <li><a href="showcase-requirements.html">Requirements</a></li>
+ <li><a href="http://demo.your.brand/">Live demo</a></li>
+ <li><a href="mailto:you@your.brand">Get a quote</a></li>
+ </ol>
+ </li>
+ <li><a href="./">Download</a></li>
+ </ol>
+ <ol class="m-col-t-6 m-col-m-none" start="4">
+ <li>
+ <a href="archives.html" id="m-navbar-current">Blog</a>
+ <ol>
+ <li><a href="./">News</a></li>
+ <li><a href="./">Archive</a></li>
+ <li><a href="guest-post-howto.html">Write a guest post</a></li>
+ </ol>
+ </li>
+ <li><a href="./">Contact</a></li>
+ </ol>
+ </div>
+ </div>
+ </div>
+ </div>
+</nav></header>
+<main>
+<div class="m-container">
+ <div class="m-row">
+ <div class="m-col-m-10">
+ <div class="m-note m-success">
+ <h3>Congratulations!</h3>
+ The m.css theme is alive and kicking! Now, feed it some articles so it doesn't feel so empty :)
+ </div>
+ </div>
+ <nav class="m-navpanel m-col-m-2">
+ <h3>Categories</h3>
+ <ol class="m-block-bar-m">
+ <li><em class="m-text m-dim">(none yet)</em></li>
+ </ol>
+ </nav>
+ </div>
+</div>
+</main>
+<footer><nav>
+ <div class="m-container">
+ <div class="m-row">
+ <div class="m-col-s-3 m-col-t-6">
+ <h3><a href="index.html">Your Brand</a></h3>
+ <ul>
+ <li><a href="./">Mission</a></li>
+ <li> </li>
+ <li><a href="./">The People</a></li>
+ </ul>
+ </div>
+ <div class="m-col-s-3 m-col-t-6">
+ <h3><a href="features.html">Features</a></h3>
+ <ul>
+ <li> </li>
+ <li><a href="http://demo.your.brand/">Live demo</a></li>
+ <li><a href="showcase-requirements.html">Requirements</a></li>
+ </ul>
+ </div>
+ <div class="m-clearfix-t"></div>
+ <div class="m-col-s-3 m-col-t-6">
+ <h3>Download</h3>
+ <ul>
+ <li><a href="./">Packages</a></li>
+ <li> </li>
+ <li><a href="./">Source</a></li>
+ </ul>
+ </div>
+ <div class="m-col-s-3 m-col-t-6">
+ <h3>Contact</h3>
+ <ul>
+ <li><a href="mailto:you@your.brand">E-mail</a></li>
+ <li> </li>
+ <li><a href="https://github.com/your-brand">GitHub</a></li>
+ </ul>
+ </div>
+ </div>
+ <div class="m-row">
+ <div class="m-col-l-10 m-push-l-1">
+ <p>Your Brand. Copyright © <a href="mailto:you@your.brand">You</a>, 2017.
+ All rights reserved.</p>
+ </div>
+ </div>
+ </div>
+</nav></footer>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>Showcase requirements | Your Brand</title>
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i" />
+ <link rel="stylesheet" href="static/m-dark.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta property="og:title" content="Showcase requirements" />
+ <meta name="twitter:title" content="Showcase requirements" />
+ <meta property="og:url" content="showcase-requirements.html" />
+ <meta name="twitter:url" content="showcase-requirements.html" />
+ <meta name="twitter:card" content="summary" />
+ <meta property="og:type" content="website" />
+</head>
+<body>
+<header><nav id="navigation">
+ <div class="m-container">
+ <div class="m-row">
+ <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">Your.brand</a>
+ <a id="m-navbar-show" href="#navigation" title="Show navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+ <a id="m-navbar-hide" href="#" title="Hide navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+ <div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
+ <div class="m-row">
+ <ol class="m-col-t-6 m-col-m-none">
+ <li><a href="features.html">Features</a></li>
+ <li>
+ <a href="./">Showcase</a>
+ <ol>
+ <li><a href="showcase-requirements.html" id="m-navbar-current">Requirements</a></li>
+ <li><a href="http://demo.your.brand/">Live demo</a></li>
+ <li><a href="mailto:you@your.brand">Get a quote</a></li>
+ </ol>
+ </li>
+ <li><a href="./">Download</a></li>
+ </ol>
+ <ol class="m-col-t-6 m-col-m-none" start="4">
+ <li>
+ <a href="archives.html">Blog</a>
+ <ol>
+ <li><a href="./">News</a></li>
+ <li><a href="./">Archive</a></li>
+ <li><a href="guest-post-howto.html">Write a guest post</a></li>
+ </ol>
+ </li>
+ <li><a href="./">Contact</a></li>
+ </ol>
+ </div>
+ </div>
+ </div>
+ </div>
+</nav></header>
+<main>
+<article>
+ <div class="m-container m-container-inflatable">
+ <div class="m-row">
+ <div class="m-col-l-10 m-push-l-1">
+ <h1>Showcase requirements</h1>
+ </div>
+ </div>
+ </div>
+</article>
+</main>
+<footer><nav>
+ <div class="m-container">
+ <div class="m-row">
+ <div class="m-col-s-3 m-col-t-6">
+ <h3><a href="index.html">Your Brand</a></h3>
+ <ul>
+ <li><a href="./">Mission</a></li>
+ <li> </li>
+ <li><a href="./">The People</a></li>
+ </ul>
+ </div>
+ <div class="m-col-s-3 m-col-t-6">
+ <h3><a href="features.html">Features</a></h3>
+ <ul>
+ <li> </li>
+ <li><a href="http://demo.your.brand/">Live demo</a></li>
+ <li><a href="showcase-requirements.html">Requirements</a></li>
+ </ul>
+ </div>
+ <div class="m-clearfix-t"></div>
+ <div class="m-col-s-3 m-col-t-6">
+ <h3>Download</h3>
+ <ul>
+ <li><a href="./">Packages</a></li>
+ <li> </li>
+ <li><a href="./">Source</a></li>
+ </ul>
+ </div>
+ <div class="m-col-s-3 m-col-t-6">
+ <h3>Contact</h3>
+ <ul>
+ <li><a href="mailto:you@your.brand">E-mail</a></li>
+ <li> </li>
+ <li><a href="https://github.com/your-brand">GitHub</a></li>
+ </ul>
+ </div>
+ </div>
+ <div class="m-row">
+ <div class="m-col-l-10 m-push-l-1">
+ <p>Your Brand. Copyright © <a href="mailto:you@your.brand">You</a>, 2017.
+ All rights reserved.</p>
+ </div>
+ </div>
+ </div>
+</nav></footer>
+</body>
+</html>
--- /dev/null
+Showcase requirements
+#####################
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>A Pelican Blog</title>
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i" />
+ <link rel="stylesheet" href="static/m-dark.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</head>
+<body>
+<header><nav id="navigation">
+ <div class="m-container">
+ <div class="m-row">
+ <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">A Pelican Blog</a>
+ </div>
+ </div>
+</nav></header>
+<main>
+<div class="m-container">
+ <div class="m-row">
+ <div class="m-col-m-10">
+ <div class="m-note m-success">
+ <h3>Congratulations!</h3>
+ The m.css theme is alive and kicking! Now, feed it some articles so it doesn't feel so empty :)
+ </div>
+ </div>
+ <nav class="m-navpanel m-col-m-2">
+ <h3>Categories</h3>
+ <ol class="m-block-bar-m">
+ <li><em class="m-text m-dim">(none yet)</em></li>
+ </ol>
+ </nav>
+ </div>
+</div>
+</main>
+<footer><nav>
+ <div class="m-container">
+ <div class="m-row">
+ <div class="m-col-s-3 m-col-t-6">
+ <h3><a href="index.html">Your Brand</a></h3>
+ <ul>
+ </ul>
+ </div>
+ <div class="m-col-s-3 m-col-t-6">
+ </div>
+ <div class="m-clearfix-t"></div>
+ <div class="m-col-s-3 m-col-t-6">
+ </div>
+ <div class="m-col-s-3 m-col-t-6">
+ </div>
+ </div>
+ <div class="m-row">
+ <div class="m-col-l-10 m-push-l-1">
+ <p>A Pelican Blog. Powered by <a href="https://getpelican.com">Pelican</a> and <a href="http://mcss.mosra.cz">m.css</a>.</p>
+ </div>
+ </div>
+ </div>
+</nav></footer>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>A Pelican Blog</title>
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i" />
+ <link rel="stylesheet" href="static/m-dark.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</head>
+<body>
+<header><nav id="navigation">
+ <div class="m-container">
+ <div class="m-row">
+ <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">A Pelican Blog</a>
+ </div>
+ </div>
+</nav></header>
+<main>
+<div class="m-container">
+ <div class="m-row">
+ <div class="m-col-m-10">
+ <div class="m-note m-success">
+ <h3>Congratulations!</h3>
+ The m.css theme is alive and kicking! Now, feed it some articles so it doesn't feel so empty :)
+ </div>
+ </div>
+ <nav class="m-navpanel m-col-m-2">
+ <h3>Categories</h3>
+ <ol class="m-block-bar-m">
+ <li><em class="m-text m-dim">(none yet)</em></li>
+ </ol>
+ </nav>
+ </div>
+</div>
+</main>
+<footer><nav>
+ <div class="m-container">
+ <div class="m-row">
+ <div class="m-col-s-3 m-col-t-6">
+ <h3><a href="index.html">Your Brand</a></h3>
+ <ul>
+ </ul>
+ </div>
+ <div class="m-col-s-3 m-col-t-6">
+ </div>
+ <div class="m-clearfix-t"></div>
+ <div class="m-col-s-3 m-col-t-6">
+ </div>
+ <div class="m-col-s-3 m-col-t-6">
+ <h3><a href="./">Blog</a></h3>
+ <ul>
+ </ul>
+ </div>
+ </div>
+ </div>
+</nav></footer>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>A Pelican Blog</title>
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i" />
+ <link rel="stylesheet" href="static/m-dark.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta name="theme-color" content="#22272e" />
+</head>
+<body>
+<header><nav id="navigation">
+ <div class="m-container">
+ <div class="m-row">
+ <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">A Pelican Blog</a>
+ </div>
+ </div>
+</nav></header>
+<main>
+<div class="m-container">
+ <div class="m-row">
+ <div class="m-col-m-10">
+ <div class="m-note m-success">
+ <h3>Congratulations!</h3>
+ The m.css theme is alive and kicking! Now, feed it some articles so it doesn't feel so empty :)
+ </div>
+ </div>
+ <nav class="m-navpanel m-col-m-2">
+ <h3>Categories</h3>
+ <ol class="m-block-bar-m">
+ <li><em class="m-text m-dim">(none yet)</em></li>
+ </ol>
+ </nav>
+ </div>
+</div>
+</main>
+<footer><nav>
+ <div class="m-container">
+ <div class="m-row">
+ <div class="m-col-l-10 m-push-l-1">
+ <p>A Pelican Blog. Powered by <a href="https://getpelican.com">Pelican</a> and <a href="http://mcss.mosra.cz">m.css</a>.</p>
+ </div>
+ </div>
+ </div>
+</nav></footer>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>A Pelican Blog</title>
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i" />
+ <link rel="stylesheet" href="static/m-dark.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</head>
+<body>
+<header><nav id="navigation">
+ <div class="m-container">
+ <div class="m-row">
+ <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">A Pelican Blog</a>
+ </div>
+ </div>
+</nav></header>
+<main>
+<div class="m-container">
+ <div class="m-row">
+ <div class="m-col-m-10">
+ <div class="m-note m-success">
+ <h3>Congratulations!</h3>
+ The m.css theme is alive and kicking! Now, feed it some articles so it doesn't feel so empty :)
+ </div>
+ </div>
+ <nav class="m-navpanel m-col-m-2">
+ <h3>Categories</h3>
+ <ol class="m-block-bar-m">
+ <li><em class="m-text m-dim">(none yet)</em></li>
+ </ol>
+ </nav>
+ </div>
+</div>
+</main>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>A Pelican Blog</title>
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i" />
+ <link rel="stylesheet" href="static/m-dark.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</head>
+<body>
+<header><nav id="navigation">
+ <div class="m-container">
+ <div class="m-row">
+ <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">A Pelican Blog</a>
+ <a id="m-navbar-show" href="#navigation" title="Show navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+ <a id="m-navbar-hide" href="#" title="Hide navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+ <div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
+ <div class="m-row">
+ <ol class="m-col-t-12 m-col-m-none">
+ <li><a href="./">Features</a></li>
+ <li><a href="./">A long item caption that really should not wrap on small screen</a></li>
+ <li><a href="archives.html" id="m-navbar-current">Blog</a></li>
+ </ol>
+ </div>
+ </div>
+ </div>
+ </div>
+</nav></header>
+<main>
+<div class="m-container">
+ <div class="m-row">
+ <div class="m-col-m-10">
+ <div class="m-note m-success">
+ <h3>Congratulations!</h3>
+ The m.css theme is alive and kicking! Now, feed it some articles so it doesn't feel so empty :)
+ </div>
+ </div>
+ <nav class="m-navpanel m-col-m-2">
+ <h3>Categories</h3>
+ <ol class="m-block-bar-m">
+ <li><em class="m-text m-dim">(none yet)</em></li>
+ </ol>
+ </nav>
+ </div>
+</div>
+</main>
+<footer><nav>
+ <div class="m-container">
+ <div class="m-row">
+ <div class="m-col-l-10 m-push-l-1">
+ <p>A Pelican Blog. Powered by <a href="https://getpelican.com">Pelican</a> and <a href="http://mcss.mosra.cz">m.css</a>.</p>
+ </div>
+ </div>
+ </div>
+</nav></footer>
+</body>
+</html>
--- /dev/null
+import os
+
+from test import MinimalTestCase, BaseTestCase
+
+class Layout(BaseTestCase):
+ def __init__(self, *args, **kwargs):
+ super().__init__(__file__, '', *args, **kwargs)
+
+ def test(self):
+ self.run_pelican({
+ 'SITENAME': 'Your Brand',
+ 'M_BLOG_NAME': 'Your Brand Blog',
+ 'M_SITE_LOGO_TEXT': 'Your.brand',
+ 'M_LINKS_NAVBAR1': [
+ ('Features', 'features.html', 'features', []),
+ ('Showcase', '#', 'showcase', [
+ ('Requirements', 'showcase-requirements.html', 'showcase-requirements'),
+ ('Live demo', 'http://demo.your.brand/', ''),
+ ('Get a quote', 'mailto:you@your.brand', '')]),
+ ('Download', '#', 'download', [])],
+ 'M_LINKS_NAVBAR2': [('Blog', 'archives.html', '[blog]', [
+ ('News', '#', ''),
+ ('Archive', '#', ''),
+ ('Write a guest post', 'guest-post-howto.html', 'guest-post-howto')]),
+ ('Contact', '#', 'contact', [])],
+ 'M_LINKS_FOOTER1': [('Your Brand', 'index.html'),
+ ('Mission', '#'),
+ ('', ''),
+ ('The People', '#')],
+ 'M_LINKS_FOOTER2':[('Features', 'features.html'),
+ ('', ''),
+ ('Live demo', 'http://demo.your.brand/'),
+ ('Requirements', 'showcase-requirements.html')],
+ 'M_LINKS_FOOTER3': [('Download', ''),
+ ('Packages', '#'),
+ ('', ''),
+ ('Source', '#')],
+ 'M_LINKS_FOOTER4':[('Contact', ''),
+ ('E-mail', 'mailto:you@your.brand'),
+ ('', ''),
+ ('GitHub', 'https://github.com/your-brand')],
+ # multiline to test indentation
+ 'M_FINE_PRINT': """
+Your Brand. Copyright © `You <mailto:you@your.brand>`_, 2017.
+All rights reserved.
+""",
+ 'PAGE_PATHS': ['.'],
+ 'PAGE_SAVE_AS': '{slug}.html',
+ 'PAGE_URL': '{slug}.html',
+ 'ARTICLE_PATHS': ['articles'] # doesn't exist
+ })
+
+ # - page title is M_BLOG_NAME for index, as it is a blog page
+ # - the Blog entry should be highlighted
+ # - mailto and external URL links should not have SITEURL prepended in
+ # both top navbar and bottom navigation
+ # - footer spacers should put there
+ # - again, the archives page and index page should be exactly the same
+ self.assertEqual(*self.actual_expected_contents('index.html'))
+ self.assertEqual(*self.actual_expected_contents('archives.html', 'index.html'))
+
+ # - page title is SITENAME, as these are pages
+ # - corresponding items in top navbar should be highlighted
+ self.assertEqual(*self.actual_expected_contents('features.html'))
+ self.assertEqual(*self.actual_expected_contents('showcase-requirements.html'))
+ self.assertEqual(*self.actual_expected_contents('guest-post-howto.html'))
+
+class Minimal(MinimalTestCase):
+ def __init__(self, *args, **kwargs):
+ super().__init__(__file__, 'minimal', *args, **kwargs)
+
+ def test(self):
+ self.run_pelican({
+ # This is the minimal that's required. Not even the M_THEME_COLOR
+ # is required.
+ 'THEME': '.',
+ 'PLUGIN_PATHS': ['../pelican-plugins'],
+ 'PLUGINS': ['m.htmlsanity'],
+ 'THEME_STATIC_DIR': 'static',
+ 'M_CSS_FILES': ['https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i',
+ 'static/m-dark.css'],
+ 'M_THEME_COLOR': '#22272e'})
+
+ # The archives and index page should be exactly the same
+ self.assertEqual(*self.actual_expected_contents('index.html'))
+ self.assertEqual(*self.actual_expected_contents('archives.html', 'index.html'))
+
+ # Verify that we're *really* using the default setup and not disabling
+ # any pages -- but don't verify the page content, as these are not
+ # supported anyway
+ self.assertTrue(os.path.exists(os.path.join(self.path, 'output/authors.html')))
+ self.assertTrue(os.path.exists(os.path.join(self.path, 'output/categories.html')))
+ self.assertTrue(os.path.exists(os.path.join(self.path, 'output/tags.html')))
+
+ # The CSS files should be copied along
+ self.assertTrue(os.path.exists(os.path.join(self.path, 'output/static/m-grid.css')))
+ self.assertTrue(os.path.exists(os.path.join(self.path, 'output/static/m-components.css')))
+ self.assertTrue(os.path.exists(os.path.join(self.path, 'output/static/m-dark.css')))
+ self.assertTrue(os.path.exists(os.path.join(self.path, 'output/static/pygments-dark.css')))
+
+class OneColumnNavbar(BaseTestCase):
+ def __init__(self, *args, **kwargs):
+ super().__init__(__file__, 'one_column_navbar', *args, **kwargs)
+
+ def test(self):
+ self.run_pelican({
+ 'M_LINKS_NAVBAR1': [
+ ('Features', '#', 'features', []),
+ ('A long item caption that really should not wrap on small screen', '#', '', []),
+ ('Blog', 'archives.html', '[blog]', [])]
+ })
+
+ # The navbar should be full 12 columns
+ self.assertEqual(*self.actual_expected_contents('index.html'))
+
+class NoFooter(BaseTestCase):
+ def __init__(self, *args, **kwargs):
+ super().__init__(__file__, 'no_footer', *args, **kwargs)
+
+ def test(self):
+ self.run_pelican({
+ 'M_FINE_PRINT': None
+ })
+
+ # There should be no footer at all
+ self.assertEqual(*self.actual_expected_contents('index.html'))
+
+class DisableFinePrint(BaseTestCase):
+ def __init__(self, *args, **kwargs):
+ super().__init__(__file__, 'disable_fine_print', *args, **kwargs)
+
+ def test(self):
+ self.run_pelican({
+ 'M_LINKS_FOOTER1': [('Your Brand', 'index.html')],
+ 'M_FINE_PRINT': None
+ })
+
+ # There should be footer with just the first and last column and no
+ # fine print
+ self.assertEqual(*self.actual_expected_contents('index.html'))
+
+class DisableBlogLinks(BaseTestCase):
+ def __init__(self, *args, **kwargs):
+ super().__init__(__file__, 'disable_blog_links', *args, **kwargs)
+
+ def test(self):
+ self.run_pelican({
+ 'M_LINKS_FOOTER1': [('Your Brand', 'index.html')],
+ 'M_LINKS_FOOTER4': None,
+ })
+
+ # There should be just the first column
+ self.assertEqual(*self.actual_expected_contents('index.html'))
-__pycache__
*.pid
output
published