├── mdweb ├── __init__.py ├── partials │ ├── google_analytics.html │ └── opengraph.html ├── metafields.py ├── Exceptions.py ├── Index.py ├── SiteMapView.py └── Page.py ├── sites ├── __init__.py ├── plugins │ └── .gitignore ├── .gitignore └── MySite.py ├── tests ├── __init__.py ├── test_debug_helper.py ├── test_baseobjects.py └── test_partials.py ├── themes ├── basic │ ├── assets │ │ ├── js │ │ │ └── site.js │ │ ├── favicon.ico │ │ ├── images │ │ │ ├── github.png │ │ │ └── MDWeb_logo.png │ │ └── css │ │ │ └── style.css │ └── templates │ │ ├── page.html │ │ ├── page_home.html │ │ ├── page_listing.html │ │ ├── 404.html │ │ ├── layout.html │ │ └── navigation.html ├── bootstrap │ ├── assets │ │ ├── favicon.ico │ │ ├── js │ │ │ ├── site.js │ │ │ ├── npm.js │ │ │ ├── ie10-viewport-bug-workaround.js │ │ │ └── bootstrap-submenu.min.js │ │ ├── apple-icon.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon-96x96.png │ │ ├── images │ │ │ ├── github.png │ │ │ └── MDWeb_logo.png │ │ ├── ms-icon-70x70.png │ │ ├── apple-icon-57x57.png │ │ ├── apple-icon-60x60.png │ │ ├── apple-icon-72x72.png │ │ ├── apple-icon-76x76.png │ │ ├── ms-icon-144x144.png │ │ ├── ms-icon-150x150.png │ │ ├── ms-icon-310x310.png │ │ ├── android-icon-36x36.png │ │ ├── android-icon-48x48.png │ │ ├── android-icon-72x72.png │ │ ├── android-icon-96x96.png │ │ ├── apple-icon-114x114.png │ │ ├── apple-icon-120x120.png │ │ ├── apple-icon-144x144.png │ │ ├── apple-icon-152x152.png │ │ ├── apple-icon-180x180.png │ │ ├── android-icon-144x144.png │ │ ├── android-icon-192x192.png │ │ ├── apple-icon-precomposed.png │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ ├── browserconfig.xml │ │ ├── css │ │ │ ├── style.css │ │ │ ├── ie10-viewport-bug-workaround.css │ │ │ └── bootstrap-submenu.min.css.map │ │ └── manifest.json │ └── templates │ │ ├── page.html │ │ ├── page_listing.html │ │ ├── 404.html │ │ ├── page_home.html │ │ └── navigation.html ├── alpha │ ├── assets │ │ ├── images │ │ │ ├── banner.jpg │ │ │ ├── github.png │ │ │ ├── pic01.jpg │ │ │ ├── pic02.jpg │ │ │ ├── pic03.jpg │ │ │ ├── pic04.jpg │ │ │ ├── pic05.jpg │ │ │ └── github-80x80.png │ │ ├── css │ │ │ ├── images │ │ │ │ └── overlay.png │ │ │ ├── style-narrow.css │ │ │ ├── style-wide.css │ │ │ ├── style-normal.css │ │ │ ├── style-mobilep.css │ │ │ ├── ie │ │ │ │ ├── html5shiv.js │ │ │ │ ├── v8.css │ │ │ │ └── backgroundsize.min.htc │ │ │ ├── style-mobile.css │ │ │ └── style-narrower.css │ │ ├── fonts │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.ttf │ │ │ └── fontawesome-webfont.woff │ │ ├── sass │ │ │ ├── style-narrow.scss │ │ │ ├── style-wide.scss │ │ │ ├── style-normal.scss │ │ │ ├── _mixins.scss │ │ │ ├── _vars.scss │ │ │ ├── style-mobilep.scss │ │ │ ├── style-mobile.scss │ │ │ ├── style-narrower.scss │ │ │ └── ie │ │ │ │ └── v8.scss │ │ └── js │ │ │ ├── jquery.scrollgress.min.js │ │ │ └── jquery.dropotron.min.js │ ├── templates │ │ ├── page.html │ │ ├── navigation.html │ │ ├── layout.html │ │ ├── page_home.html │ │ └── _old_files │ │ │ └── contact.html │ └── README.txt ├── mdweb │ ├── assets │ │ ├── images │ │ │ ├── banner.jpg │ │ │ ├── github.png │ │ │ ├── pic01.jpg │ │ │ ├── pic02.jpg │ │ │ ├── pic03.jpg │ │ │ ├── pic04.jpg │ │ │ ├── pic05.jpg │ │ │ └── github-80x80.png │ │ ├── css │ │ │ ├── images │ │ │ │ └── overlay.png │ │ │ ├── style-narrow.css │ │ │ ├── style-wide.css │ │ │ ├── style-normal.css │ │ │ ├── style-mobilep.css │ │ │ ├── ie │ │ │ │ ├── html5shiv.js │ │ │ │ ├── v8.css │ │ │ │ └── backgroundsize.min.htc │ │ │ ├── style-mobile.css │ │ │ └── style-narrower.css │ │ ├── fonts │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.ttf │ │ │ └── fontawesome-webfont.woff │ │ ├── sass │ │ │ ├── style-narrow.scss │ │ │ ├── style-wide.scss │ │ │ ├── style-normal.scss │ │ │ ├── _mixins.scss │ │ │ ├── _vars.scss │ │ │ ├── style-mobilep.scss │ │ │ ├── style-mobile.scss │ │ │ ├── style-narrower.scss │ │ │ └── ie │ │ │ │ └── v8.scss │ │ └── js │ │ │ ├── jquery.scrollgress.min.js │ │ │ └── jquery.dropotron.min.js │ ├── templates │ │ ├── page.html │ │ ├── navigation.html │ │ ├── layout.html │ │ ├── page_home.html │ │ └── _old_files │ │ │ └── contact.html │ └── README.txt └── .gitignore ├── content └── .gitignore ├── .gitattributes ├── demo-content ├── about │ ├── empty.md │ ├── _navlevel.txt │ ├── index.md │ ├── history.md │ └── license.md ├── download │ ├── _navlevel.txt │ └── index.md ├── examples │ ├── _navlevel.txt │ ├── embedding-html.md │ └── index.md ├── documentation │ ├── _navlevel.txt │ ├── Development │ │ ├── page.md │ │ ├── navigation.md │ │ └── events.md │ ├── devserver.md │ ├── quickstart.md │ └── writing-content.md ├── favicon.ico ├── assets │ ├── github.png │ ├── teaser.png │ ├── MDWeb_logo.png │ └── MDWeb_logo_275x190.png ├── robots.txt ├── 404.md ├── 500.md ├── 405.md ├── humans.txt ├── crossdomain.xml └── index.md ├── requirements ├── development.txt ├── production.txt ├── test.txt └── common.txt ├── docs ├── images │ └── MDWeb_logo_275x190.png ├── contributing.md ├── development.md └── reference.md ├── .gitignore ├── .dockerignore ├── .landscape.yaml ├── prospector.yml ├── requirements.txt ├── VERSIONS.md ├── Dockerfile ├── Dockerfile.test ├── bin ├── deploy.sh └── dev_server ├── LICENSE.txt ├── wsgi.py ├── prospector.txt └── .circleci └── config.yml /mdweb/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sites/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /themes/basic/assets/js/site.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /content/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | themes/* linguist-vendored 2 | -------------------------------------------------------------------------------- /demo-content/about/empty.md: -------------------------------------------------------------------------------- 1 | This is a page with no meta-inf 2 | -------------------------------------------------------------------------------- /requirements/development.txt: -------------------------------------------------------------------------------- 1 | -r common.txt 2 | -r test.txt 3 | -------------------------------------------------------------------------------- /demo-content/about/_navlevel.txt: -------------------------------------------------------------------------------- 1 | Nav Name: About 2 | Order: 1 3 | -------------------------------------------------------------------------------- /demo-content/download/_navlevel.txt: -------------------------------------------------------------------------------- 1 | Nav Name: Download 2 | Order: 5 3 | -------------------------------------------------------------------------------- /demo-content/examples/_navlevel.txt: -------------------------------------------------------------------------------- 1 | Nav Name: Examples 2 | Order: 15 3 | -------------------------------------------------------------------------------- /requirements/production.txt: -------------------------------------------------------------------------------- 1 | -r common.txt 2 | 3 | gunicorn==20.0.4 4 | -------------------------------------------------------------------------------- /demo-content/documentation/_navlevel.txt: -------------------------------------------------------------------------------- 1 | Nav Name: Documentation 2 | Order: 10 3 | -------------------------------------------------------------------------------- /demo-content/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/demo-content/favicon.ico -------------------------------------------------------------------------------- /sites/plugins/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore everything 2 | * 3 | 4 | # But not these files... 5 | !.gitignore -------------------------------------------------------------------------------- /demo-content/assets/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/demo-content/assets/github.png -------------------------------------------------------------------------------- /demo-content/assets/teaser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/demo-content/assets/teaser.png -------------------------------------------------------------------------------- /themes/basic/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/basic/assets/favicon.ico -------------------------------------------------------------------------------- /demo-content/assets/MDWeb_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/demo-content/assets/MDWeb_logo.png -------------------------------------------------------------------------------- /docs/images/MDWeb_logo_275x190.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/docs/images/MDWeb_logo_275x190.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/favicon.ico -------------------------------------------------------------------------------- /themes/bootstrap/assets/js/site.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function(){ 2 | $('[data-submenu]').submenupicker(); 3 | }); -------------------------------------------------------------------------------- /demo-content/robots.txt: -------------------------------------------------------------------------------- 1 | # www.robotstxt.org/ 2 | 3 | # Allow crawling of all content 4 | User-agent: * 5 | Disallow: 6 | -------------------------------------------------------------------------------- /themes/alpha/assets/images/banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/alpha/assets/images/banner.jpg -------------------------------------------------------------------------------- /themes/alpha/assets/images/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/alpha/assets/images/github.png -------------------------------------------------------------------------------- /themes/alpha/assets/images/pic01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/alpha/assets/images/pic01.jpg -------------------------------------------------------------------------------- /themes/alpha/assets/images/pic02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/alpha/assets/images/pic02.jpg -------------------------------------------------------------------------------- /themes/alpha/assets/images/pic03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/alpha/assets/images/pic03.jpg -------------------------------------------------------------------------------- /themes/alpha/assets/images/pic04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/alpha/assets/images/pic04.jpg -------------------------------------------------------------------------------- /themes/alpha/assets/images/pic05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/alpha/assets/images/pic05.jpg -------------------------------------------------------------------------------- /themes/basic/assets/images/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/basic/assets/images/github.png -------------------------------------------------------------------------------- /themes/basic/templates/page.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 | {{ page | safe}} 4 | {% endblock %} -------------------------------------------------------------------------------- /themes/mdweb/assets/images/banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/mdweb/assets/images/banner.jpg -------------------------------------------------------------------------------- /themes/mdweb/assets/images/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/mdweb/assets/images/github.png -------------------------------------------------------------------------------- /themes/mdweb/assets/images/pic01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/mdweb/assets/images/pic01.jpg -------------------------------------------------------------------------------- /themes/mdweb/assets/images/pic02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/mdweb/assets/images/pic02.jpg -------------------------------------------------------------------------------- /themes/mdweb/assets/images/pic03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/mdweb/assets/images/pic03.jpg -------------------------------------------------------------------------------- /themes/mdweb/assets/images/pic04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/mdweb/assets/images/pic04.jpg -------------------------------------------------------------------------------- /themes/mdweb/assets/images/pic05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/mdweb/assets/images/pic05.jpg -------------------------------------------------------------------------------- /themes/bootstrap/assets/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/apple-icon.png -------------------------------------------------------------------------------- /themes/bootstrap/templates/page.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 | {{ page | safe}} 4 | {% endblock %} -------------------------------------------------------------------------------- /demo-content/assets/MDWeb_logo_275x190.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/demo-content/assets/MDWeb_logo_275x190.png -------------------------------------------------------------------------------- /themes/alpha/assets/css/images/overlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/alpha/assets/css/images/overlay.png -------------------------------------------------------------------------------- /themes/alpha/assets/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/alpha/assets/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /themes/basic/assets/images/MDWeb_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/basic/assets/images/MDWeb_logo.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/favicon-16x16.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/favicon-32x32.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/favicon-96x96.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/images/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/images/github.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/ms-icon-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/ms-icon-70x70.png -------------------------------------------------------------------------------- /themes/mdweb/assets/css/images/overlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/mdweb/assets/css/images/overlay.png -------------------------------------------------------------------------------- /themes/mdweb/assets/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/mdweb/assets/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /themes/alpha/assets/images/github-80x80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/alpha/assets/images/github-80x80.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/apple-icon-57x57.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/apple-icon-60x60.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/apple-icon-72x72.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/apple-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/apple-icon-76x76.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/images/MDWeb_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/images/MDWeb_logo.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/ms-icon-144x144.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/ms-icon-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/ms-icon-150x150.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/ms-icon-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/ms-icon-310x310.png -------------------------------------------------------------------------------- /themes/mdweb/assets/images/github-80x80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/mdweb/assets/images/github-80x80.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/android-icon-36x36.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/android-icon-48x48.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/android-icon-72x72.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/android-icon-96x96.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/apple-icon-114x114.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/apple-icon-120x120.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/apple-icon-144x144.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/apple-icon-152x152.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/apple-icon-180x180.png -------------------------------------------------------------------------------- /demo-content/404.md: -------------------------------------------------------------------------------- 1 | ```metainf 2 | Title: Error 404 3 | ``` 4 | 5 | Error 404 6 | ========= 7 | 8 | Woops. Looks like this page doesn't exist. 9 | -------------------------------------------------------------------------------- /demo-content/500.md: -------------------------------------------------------------------------------- 1 | ```metainf 2 | Title: Error 500 3 | ``` 4 | 5 | Error 500 6 | ========= 7 | 8 | Woops. Something went wrong (our bad). 9 | -------------------------------------------------------------------------------- /themes/alpha/assets/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/alpha/assets/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /themes/alpha/assets/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/alpha/assets/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /themes/alpha/assets/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/alpha/assets/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /themes/bootstrap/assets/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/android-icon-144x144.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/android-icon-192x192.png -------------------------------------------------------------------------------- /themes/bootstrap/assets/apple-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/apple-icon-precomposed.png -------------------------------------------------------------------------------- /themes/mdweb/assets/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/mdweb/assets/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /themes/mdweb/assets/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/mdweb/assets/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /themes/mdweb/assets/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/mdweb/assets/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /demo-content/405.md: -------------------------------------------------------------------------------- 1 | ```metainf 2 | Title: Error 405 3 | ``` 4 | 5 | Error 405 6 | ========= 7 | 8 | Woops. Looks like something went wrong. Please try again. 9 | -------------------------------------------------------------------------------- /themes/bootstrap/assets/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /themes/bootstrap/assets/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /themes/bootstrap/assets/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /themes/bootstrap/assets/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crempp/mdweb/HEAD/themes/bootstrap/assets/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.pyc 3 | *.pyo 4 | env 5 | env* 6 | dist 7 | *.egg 8 | *.egg-info 9 | _mailinglist 10 | .tox 11 | .idea 12 | shippable 13 | nosetests.xml 14 | .coverage 15 | cover 16 | coverage 17 | -------------------------------------------------------------------------------- /themes/basic/templates/page_home.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 |
4 |
5 |

{{ page | safe}}

6 |
7 |
8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | #demo-content 2 | .coverage 3 | .dockerignore 4 | .git 5 | .gitignore 6 | .idea 7 | .landscape.yaml 8 | circle.yml 9 | LICENSE.txt 10 | README.md 11 | shippable.yml 12 | VERSIONS.md 13 | **/__pycache__ 14 | **/*.pyc 15 | **/.DS_Store 16 | -------------------------------------------------------------------------------- /.landscape.yaml: -------------------------------------------------------------------------------- 1 | doc-warnings: yes 2 | test-warnings: yes 3 | strictness: veryhigh 4 | max-line-length: 80 5 | autodetect: yes 6 | 7 | ignore-paths: 8 | - themes 9 | - content 10 | 11 | uses: 12 | - flask 13 | 14 | python-targets: 15 | - 2 16 | - 3 17 | -------------------------------------------------------------------------------- /sites/.gitignore: -------------------------------------------------------------------------------- 1 | # We ignore all sites except MySite.py so that we can create test sites without 2 | # accidentally commiting test sites. 3 | 4 | # Ignore everything 5 | * 6 | 7 | # But not these files... 8 | !.gitignore 9 | !plugins 10 | !__init__.py 11 | !MySite.py 12 | -------------------------------------------------------------------------------- /requirements/test.txt: -------------------------------------------------------------------------------- 1 | -r common.txt 2 | 3 | coverage==5.2.1 4 | fixtures==3.0.0 5 | Flask-Testing==0.8.0 6 | mock==3.0.5 7 | mox3==0.28.0 8 | nose==1.3.7 9 | nose-htmloutput==0.6.0 10 | pyfakefs==4.1.0 11 | requests-mock==1.8.0 12 | testtools==2.4.0 13 | unittest2==1.1.0 14 | -------------------------------------------------------------------------------- /demo-content/humans.txt: -------------------------------------------------------------------------------- 1 | # humanstxt.org/ 2 | # The humans responsible & technology colophon 3 | 4 | # TEAM 5 | 6 | -- -- 7 | 8 | # THANKS 9 | 10 | 11 | 12 | # TECHNOLOGY COLOPHON 13 | 14 | HTML5, CSS3 15 | jQuery, Modernizr 16 | -------------------------------------------------------------------------------- /themes/alpha/assets/css/style-narrow.css: -------------------------------------------------------------------------------- 1 | /* 2 | Alpha by HTML5 UP 3 | html5up.net | @n33co 4 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | */ 6 | 7 | /* Basic */ 8 | 9 | body, input, select, textarea { 10 | font-size: 11pt; 11 | } -------------------------------------------------------------------------------- /themes/mdweb/assets/css/style-narrow.css: -------------------------------------------------------------------------------- 1 | /* 2 | Alpha by HTML5 UP 3 | html5up.net | @n33co 4 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | */ 6 | 7 | /* Basic */ 8 | 9 | body, input, select, textarea { 10 | font-size: 11pt; 11 | } -------------------------------------------------------------------------------- /themes/basic/templates/page_listing.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 | {{ page | safe}} 4 | 5 | 6 | {# Section for each nav entry #} 7 | {% for nav in navigation.children if not nav.name == "About" -%} 8 | {{ nav.name }} 9 | {% endfor %} 10 | {% endblock %} 11 | -------------------------------------------------------------------------------- /themes/.gitignore: -------------------------------------------------------------------------------- 1 | # We ignore all themes except those listed so that we can create test themes 2 | # without accidentally commiting test sites. 3 | 4 | # Ignore everything 5 | * 6 | 7 | # But not these files... 8 | !.gitignore 9 | !alpha/**/* 10 | !basic/**/* 11 | !bootstrap/**/* 12 | !mdweb/**/* 13 | -------------------------------------------------------------------------------- /themes/basic/templates/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Page Not Found 6 | 7 | 8 |

Page Not Found

9 |

Sorry, but the page you were trying to view does not exist.

10 | 11 | 12 | -------------------------------------------------------------------------------- /themes/bootstrap/templates/page_listing.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 | {{ page | safe}} 4 | 5 | 6 | {# Section for each nav entry #} 7 | {% for nav in navigation.children if not nav.name == "About" -%} 8 | {{ nav.name }} 9 | {% endfor %} 10 | {% endblock %} 11 | -------------------------------------------------------------------------------- /prospector.yml: -------------------------------------------------------------------------------- 1 | output-format: text 2 | 3 | strictness: high 4 | test-warnings: true 5 | doc-warnings: false 6 | member-warnings: true 7 | 8 | ignore-paths: 9 | - docs 10 | 11 | uses: 12 | - flask 13 | 14 | pep8: 15 | disable: 16 | - E501 17 | options: 18 | max-line-length: 79 19 | 20 | -------------------------------------------------------------------------------- /mdweb/partials/google_analytics.html: -------------------------------------------------------------------------------- 1 | 2 | 9 | -------------------------------------------------------------------------------- /themes/bootstrap/assets/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff -------------------------------------------------------------------------------- /docs/contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing to MDWeb 2 | 3 | I am still working out the details on contributing to MDWeb. Until I finish the guidelines please report any bugs or feature requests in the issues section. 4 | 5 | If you just can't wait to have me merge your pull request send me an email and we'll figure something out. 6 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # For simplicity we use the base requirements.txt for setting up CircleCI 2 | # testing. 3 | # For other environments use 4 | # - requirements/development.txt 5 | # - requirements/production.txt 6 | # - requirements/test.txt 7 | 8 | -r requirements/production.txt 9 | -r requirements/test.txt 10 | -------------------------------------------------------------------------------- /VERSIONS.md: -------------------------------------------------------------------------------- 1 | MDWeb versions 2 | ==== 3 | 4 | v0.2 \[future\] 5 | ---- 6 | 1. Asset support in content directory 7 | 8 | v0.1 \[2016-02-22\] 9 | ---- 10 | 1. Basic markdown page hosting 11 | 1. File change watcher 12 | 1. Arbitrary depth navigation with page metadata definition 13 | 1. \>90% test coverage 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /themes/basic/assets/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | } 4 | 5 | /* Add a top margin to the container directly after the nav*/ 6 | nav + div.container { 7 | margin-top: 20px; 8 | } 9 | 10 | article.home-page div.jumbotron 11 | 12 | .starter-template { 13 | padding: 40px 15px; 14 | text-align: center; 15 | } 16 | -------------------------------------------------------------------------------- /themes/bootstrap/assets/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | } 4 | 5 | /* Add a top margin to the container directly after the nav*/ 6 | nav + div.container { 7 | margin-top: 20px; 8 | } 9 | 10 | article.home-page div.jumbotron 11 | 12 | .starter-template { 13 | padding: 40px 15px; 14 | text-align: center; 15 | } 16 | -------------------------------------------------------------------------------- /themes/alpha/assets/sass/style-narrow.scss: -------------------------------------------------------------------------------- 1 | @import 'vars'; 2 | @import 'mixins'; 3 | 4 | /* 5 | Alpha by HTML5 UP 6 | html5up.net | @n33co 7 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 8 | */ 9 | 10 | /* Basic */ 11 | 12 | body, input, select, textarea { 13 | font-size: 11pt; 14 | } -------------------------------------------------------------------------------- /themes/mdweb/assets/sass/style-narrow.scss: -------------------------------------------------------------------------------- 1 | @import 'vars'; 2 | @import 'mixins'; 3 | 4 | /* 5 | Alpha by HTML5 UP 6 | html5up.net | @n33co 7 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 8 | */ 9 | 10 | /* Basic */ 11 | 12 | body, input, select, textarea { 13 | font-size: 11pt; 14 | } -------------------------------------------------------------------------------- /themes/alpha/assets/css/style-wide.css: -------------------------------------------------------------------------------- 1 | /* 2 | Alpha by HTML5 UP 3 | html5up.net | @n33co 4 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | */ 6 | 7 | /* Basic */ 8 | 9 | body, input, select, textarea { 10 | font-size: 13pt; 11 | } 12 | 13 | /* Banner */ 14 | 15 | #banner { 16 | padding: 10em 0 18em 0; 17 | } -------------------------------------------------------------------------------- /themes/mdweb/assets/css/style-wide.css: -------------------------------------------------------------------------------- 1 | /* 2 | Alpha by HTML5 UP 3 | html5up.net | @n33co 4 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | */ 6 | 7 | /* Basic */ 8 | 9 | body, input, select, textarea { 10 | font-size: 13pt; 11 | } 12 | 13 | /* Banner */ 14 | 15 | #banner { 16 | padding: 10em 0 18em 0; 17 | } -------------------------------------------------------------------------------- /themes/alpha/templates/page.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 |
4 |
5 | {% if meta.title %} 6 |

{{ meta.title }}

7 | {% endif %} 8 | {% if meta.subtitle %} 9 |

{{ meta.subtitle }}

10 | {% endif %} 11 |
12 | {{ page | safe}} 13 |
14 | {% endblock %} -------------------------------------------------------------------------------- /themes/mdweb/templates/page.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 |
4 |
5 | {% if meta.title %} 6 |

{{ meta.title }}

7 | {% endif %} 8 | {% if meta.subtitle %} 9 |

{{ meta.subtitle }}

10 | {% endif %} 11 |
12 | {{ page | safe}} 13 |
14 | {% endblock %} -------------------------------------------------------------------------------- /themes/alpha/assets/sass/style-wide.scss: -------------------------------------------------------------------------------- 1 | @import 'vars'; 2 | @import 'mixins'; 3 | 4 | /* 5 | Alpha by HTML5 UP 6 | html5up.net | @n33co 7 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 8 | */ 9 | 10 | /* Basic */ 11 | 12 | body, input, select, textarea { 13 | font-size: 13pt; 14 | } 15 | 16 | /* Banner */ 17 | 18 | #banner { 19 | padding: 10em 0 18em 0; 20 | } -------------------------------------------------------------------------------- /themes/mdweb/assets/sass/style-wide.scss: -------------------------------------------------------------------------------- 1 | @import 'vars'; 2 | @import 'mixins'; 3 | 4 | /* 5 | Alpha by HTML5 UP 6 | html5up.net | @n33co 7 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 8 | */ 9 | 10 | /* Basic */ 11 | 12 | body, input, select, textarea { 13 | font-size: 13pt; 14 | } 15 | 16 | /* Banner */ 17 | 18 | #banner { 19 | padding: 10em 0 18em 0; 20 | } -------------------------------------------------------------------------------- /requirements/common.txt: -------------------------------------------------------------------------------- 1 | argh==0.26.2 2 | blinker==1.4 3 | dateparser==0.7.6 4 | extras==1.0.0 5 | Flask==1.1.2 6 | itsdangerous==1.1.0 7 | Jinja2==2.11.3 8 | linecache2==1.0.0 9 | Markdown==3.2.2 10 | MarkupSafe==1.1.1 11 | pathtools==0.1.2 12 | pbr==5.4.5 13 | pyrsistent==0.16.0 14 | python-dateutil==2.8.1 15 | python-mimeparse==1.6.0 16 | pytz==2020.1 17 | PyYAML==5.4 18 | six==1.15.0 19 | traceback2==1.4.0 20 | tzlocal==2.1 21 | watchdog==0.10.3 22 | Werkzeug==1.0.1 23 | wheel==0.35.1 24 | -------------------------------------------------------------------------------- /demo-content/download/index.md: -------------------------------------------------------------------------------- 1 | ```metainf 2 | Title: Download MDWeb 3 | Description: Download MDWeb 4 | Nav Name: Download 5 | Sitemap Priority: 0.9 6 | Sitemap Changefreq: weekly 7 | ``` 8 | 9 | # Download MDWeb 10 | 11 | MDWeb is ready for you to use. 12 | 13 | 14 | MDWeb on Github 15 | 16 | 17 | 18 | ## Requirements 19 | * Python 2.7+, 3.x 20 | * Pip 21 | * Virtualenv (optional) 22 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:alpine 2 | MAINTAINER Chad Rempp 3 | LABEL description="MDWeb production demo site" 4 | 5 | COPY . /opt/mdweb 6 | 7 | WORKDIR /opt/mdweb 8 | 9 | RUN apk add --no-cache --update --virtual .build-deps \ 10 | g++ \ 11 | gcc \ 12 | && pip install -r /opt/mdweb/requirements/production.txt \ 13 | && apk del .build-deps \ 14 | && rm -rf /var/cache/apk/* 15 | 16 | EXPOSE 5000 17 | 18 | CMD ["gunicorn", "--workers=4", "-b 0.0.0.0:5000","wsgi:app"] 19 | -------------------------------------------------------------------------------- /themes/alpha/assets/css/style-normal.css: -------------------------------------------------------------------------------- 1 | /* 2 | Alpha by HTML5 UP 3 | html5up.net | @n33co 4 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | */ 6 | 7 | /* Basic */ 8 | 9 | body, input, select, textarea { 10 | font-size: 11pt; 11 | } 12 | 13 | /* Header */ 14 | 15 | .dropotron.level-0 { 16 | font-size: 1em; 17 | } 18 | 19 | /* Banner */ 20 | 21 | #banner { 22 | background-attachment: scroll; 23 | } 24 | 25 | #banner h2 { 26 | font-size: 3.5em; 27 | } -------------------------------------------------------------------------------- /themes/mdweb/assets/css/style-normal.css: -------------------------------------------------------------------------------- 1 | /* 2 | Alpha by HTML5 UP 3 | html5up.net | @n33co 4 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | */ 6 | 7 | /* Basic */ 8 | 9 | body, input, select, textarea { 10 | font-size: 11pt; 11 | } 12 | 13 | /* Header */ 14 | 15 | .dropotron.level-0 { 16 | font-size: 1em; 17 | } 18 | 19 | /* Banner */ 20 | 21 | #banner { 22 | background-attachment: scroll; 23 | } 24 | 25 | #banner h2 { 26 | font-size: 3.5em; 27 | } -------------------------------------------------------------------------------- /themes/bootstrap/assets/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /themes/alpha/assets/sass/style-normal.scss: -------------------------------------------------------------------------------- 1 | @import 'vars'; 2 | @import 'mixins'; 3 | 4 | /* 5 | Alpha by HTML5 UP 6 | html5up.net | @n33co 7 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 8 | */ 9 | 10 | /* Basic */ 11 | 12 | body, input, select, textarea { 13 | font-size: 11pt; 14 | } 15 | 16 | /* Header */ 17 | 18 | .dropotron { 19 | &.level-0 { 20 | font-size: 1em; 21 | } 22 | } 23 | 24 | /* Banner */ 25 | 26 | #banner { 27 | background-attachment: scroll; 28 | 29 | h2 { 30 | font-size: 3.5em; 31 | } 32 | } -------------------------------------------------------------------------------- /themes/mdweb/assets/sass/style-normal.scss: -------------------------------------------------------------------------------- 1 | @import 'vars'; 2 | @import 'mixins'; 3 | 4 | /* 5 | Alpha by HTML5 UP 6 | html5up.net | @n33co 7 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 8 | */ 9 | 10 | /* Basic */ 11 | 12 | body, input, select, textarea { 13 | font-size: 11pt; 14 | } 15 | 16 | /* Header */ 17 | 18 | .dropotron { 19 | &.level-0 { 20 | font-size: 1em; 21 | } 22 | } 23 | 24 | /* Banner */ 25 | 26 | #banner { 27 | background-attachment: scroll; 28 | 29 | h2 { 30 | font-size: 3.5em; 31 | } 32 | } -------------------------------------------------------------------------------- /themes/bootstrap/assets/css/ie10-viewport-bug-workaround.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * IE10 viewport hack for Surface/desktop Windows 8 bug 3 | * Copyright 2014-2015 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | 7 | /* 8 | * See the Getting Started docs for more information: 9 | * http://getbootstrap.com/getting-started/#support-ie10-width 10 | */ 11 | @-webkit-viewport { width: device-width; } 12 | @-moz-viewport { width: device-width; } 13 | @-ms-viewport { width: device-width; } 14 | @-o-viewport { width: device-width; } 15 | @viewport { width: device-width; } 16 | -------------------------------------------------------------------------------- /Dockerfile.test: -------------------------------------------------------------------------------- 1 | FROM python:alpine 2 | MAINTAINER Chad Rempp 3 | LABEL description="MDWeb production demo site" 4 | 5 | COPY . /opt/mdweb 6 | 7 | WORKDIR /opt/mdweb 8 | 9 | RUN apk add --no-cache --update --virtual .build-deps \ 10 | g++ \ 11 | gcc \ 12 | && pip install -r /opt/mdweb/requirements/test.txt \ 13 | && apk del .build-deps \ 14 | && rm -rf /var/cache/apk/* 15 | 16 | RUN ["mkdir", "-p", "coverage"] 17 | 18 | EXPOSE 5000 19 | 20 | CMD ["nosetests", "--with-coverage", "--cover-erase", "--cover-html", "--cover-html-dir=coverage/html", "--with-xunit", "--xunit-file=coverage/nosetests.xml", "--cover-package=mdweb"] 21 | -------------------------------------------------------------------------------- /demo-content/crossdomain.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | -------------------------------------------------------------------------------- /themes/basic/templates/layout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{ opengraph | safe }} 6 | 7 | MDWeb 8 | 9 | 10 | 11 | 16 | 17 |
18 | {% block body %}{% endblock %} 19 |
20 | 21 | 22 | {{ ga_tracking | safe }} 23 | {{ debug_helper | safe }} 24 | 25 | 26 | -------------------------------------------------------------------------------- /themes/bootstrap/assets/js/ie10-viewport-bug-workaround.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * IE10 viewport hack for Surface/desktop Windows 8 bug 3 | * Copyright 2014-2015 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | 7 | // See the Getting Started docs for more information: 8 | // http://getbootstrap.com/getting-started/#support-ie10-width 9 | 10 | (function () { 11 | 'use strict'; 12 | 13 | if (navigator.userAgent.match(/IEMobile\/10\.0/)) { 14 | var msViewportStyle = document.createElement('style') 15 | msViewportStyle.appendChild( 16 | document.createTextNode( 17 | '@-ms-viewport{width:auto!important}' 18 | ) 19 | ) 20 | document.querySelector('head').appendChild(msViewportStyle) 21 | } 22 | 23 | })(); 24 | -------------------------------------------------------------------------------- /demo-content/documentation/Development/page.md: -------------------------------------------------------------------------------- 1 | ```metainf 2 | Title: The Page Object 3 | Nav Name: Page Object 4 | Description: MDWeb Page Object 5 | Order: 4 6 | Teaser: MDWeb page object reference. Useful reference for writing 7 | themes and plugins. 8 | Sitemap Priority: 0.5 9 | Sitemap Changefreq: monthly 10 | ``` 11 | 12 | #Page Object 13 | The page object contains all the data related to a page. The rendered page 14 | is also cached in this object. 15 | 16 | * *path:* The filesystem path to the page (relative to the content directory). 17 | 18 | * *url_path:* The URL path to the page. 19 | 20 | * *meta_inf:* The page meta-information. 21 | 22 | * *markdown_str:* The raw markdown for the page. 23 | 24 | * *page_html:* The page content after rendering the markdown. 25 | 26 | * *page_cache:* Then entire rendered page including the dependant layout. 27 | -------------------------------------------------------------------------------- /mdweb/metafields.py: -------------------------------------------------------------------------------- 1 | """ Metainf block field registrations. 2 | 3 | The META_FIELDS dictionary registers allowable fields in the markdown 4 | metainf block as well as the type and default value. 5 | 6 | The dictionary structure is defined as 7 | ``` 8 | META_FIELDS = { 9 | 'camel_cased_field_name': ('python_type', default_value) 10 | } 11 | ``` 12 | 13 | """ 14 | META_FIELDS = { 15 | 'title': ('unicode', None), 16 | 'nav_name': ('unicode', None), 17 | 'description': ('unicode', None), 18 | 'author': ('unicode', None), 19 | 'date': ('date', None), 20 | 'order': ('int', 0), 21 | 'template': ('unicode', None), 22 | 'teaser': ('unicode', None), 23 | 'teaser_image': ('unicode', None), 24 | 'sitemap_priority': ('unicode', None), 25 | 'sitemap_changefreq': ('unicode', None), 26 | 'published': ('bool', True), 27 | } 28 | -------------------------------------------------------------------------------- /themes/alpha/templates/navigation.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /themes/mdweb/templates/navigation.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo-content/about/index.md: -------------------------------------------------------------------------------- 1 | ```metainf 2 | Title: About MDWeb 3 | Nav Name: About MDWeb 4 | Description: All about MDWeb 5 | Order: 1 6 | Teaser: What MDWeb is and how it came about. 7 | Sitemap Priority: 0.9 8 | Sitemap Changefreq: monthly 9 | ``` 10 | 11 | MDWeb is painstakingly designed to be as minimalistic as possible while 12 | taking less than 5 minutes to setup and less than a minute to add 13 | content. 14 | 15 | This project was borne out of my frustration with maintaining websites 16 | and adding content. I'm a firm believer in the ethos that CMS is an 17 | evil that should be rid from this world. I spent years fighting 18 | horrific battles with enemies such as Drupal, Wordpress and Joomla. 19 | The things I saw during those dark days can not be unseen. 20 | 21 | After years of battle, this weary web developer built himself a tiny 22 | oasis. This is MDWeb, I hope you find respite in it. 23 | -------------------------------------------------------------------------------- /themes/bootstrap/assets/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "App", 3 | "icons": [ 4 | { 5 | "src": "\/android-icon-36x36.png", 6 | "sizes": "36x36", 7 | "type": "image\/png", 8 | "density": "0.75" 9 | }, 10 | { 11 | "src": "\/android-icon-48x48.png", 12 | "sizes": "48x48", 13 | "type": "image\/png", 14 | "density": "1.0" 15 | }, 16 | { 17 | "src": "\/android-icon-72x72.png", 18 | "sizes": "72x72", 19 | "type": "image\/png", 20 | "density": "1.5" 21 | }, 22 | { 23 | "src": "\/android-icon-96x96.png", 24 | "sizes": "96x96", 25 | "type": "image\/png", 26 | "density": "2.0" 27 | }, 28 | { 29 | "src": "\/android-icon-144x144.png", 30 | "sizes": "144x144", 31 | "type": "image\/png", 32 | "density": "3.0" 33 | }, 34 | { 35 | "src": "\/android-icon-192x192.png", 36 | "sizes": "192x192", 37 | "type": "image\/png", 38 | "density": "4.0" 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /bin/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -u 5 | set -o pipefail 6 | 7 | # more bash-friendly output for jq 8 | JQ="jq --raw-output --exit-status" 9 | 10 | configure_aws_cli(){ 11 | aws --version 12 | aws configure set default.region $AWS_DEFAULT_REGION 13 | aws configure set default.output json 14 | } 15 | 16 | push_ecr_image(){ 17 | eval $(aws ecr get-login --region $AWS_DEFAULT_REGION) 18 | 19 | # NOTE: could also use $CIRCLE_BUILD_NUM 20 | docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/mdweb-build-registry:$CIRCLE_BRANCH-$CIRCLE_SHA1 21 | 22 | docker tag $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/mdweb-build-registry:$CIRCLE_BRANCH-$CIRCLE_SHA1 \ 23 | $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/mdweb-build-registry:latest 24 | 25 | docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/mdweb-build-registry:latest 26 | } 27 | 28 | configure_aws_cli 29 | push_ecr_image 30 | -------------------------------------------------------------------------------- /demo-content/index.md: -------------------------------------------------------------------------------- 1 | ```metainf 2 | Title: MDWeb 3 | Description: The minimalistic markdown NaCMS 4 | Order: 1 5 | Date: 2016/10/02 6 | Author: Chad Rempp 7 | Template: page_home.html 8 | Sitemap Priority: 0.9 9 | Sitemap Changefreq: daily 10 | Teaser Image: /contentassets/teaser.png 11 | ``` 12 | 13 | MDWeb is a markdown based web site framework. 14 | 15 | MDWeb is painstakingly designed to be as minimalistic as possible while taking 16 | less than 5 minutes to setup and less than one minute to add content. 17 | 18 | This project was borne out of my frustration with maintaining websites and 19 | adding content. I'm a firm believer in the ethos that CMS is an evil that 20 | should be rid from this world. I spent years fighting horrific battles with 21 | enemies such as Drupal, Wordpress and Joomla. The things I saw during those 22 | dark days can not be unseen. 23 | 24 | After years of battle, this weary web development soldier built himself a 25 | tiny oasis. This is MDWeb, I hope you find respite in it. 26 | -------------------------------------------------------------------------------- /themes/bootstrap/assets/css/bootstrap-submenu.min.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["less/bootstrap-submenu.less","less/mixins.less"],"names":[],"mappings":"AAYqB,0BACnB,QAAA,GAGyC,yBACzC,kBACE,SAAA,SAEA,iCACE,IAAA,EACA,KAAA,KACA,WAAA,KACA,uBAAA,EAJF,yCAAA,sDASI,IAAA,KACA,OAAA,EACA,WAAA,EACA,cAAA,KACA,uBAAA,IACA,0BAAA,EAdJ,sDAAA,+CAmBI,KAAA,KACA,MAAA,KAEA,uBAAA,IACA,wBAAA,EAvBJ,8DAAA,uDAAA,2EAAA,oEA2BM,cAAA,IAAA,IAAA,EAKH,0BACD,MAAA,MACA,WAAA,IACA,aAAA,MCrDJ,YAAA,IAAA,OAEA,WAAA,IAAA,MAAA,YACA,cAAA,IAAA,MAAA,YD+CK,+CAAA,wCASC,MAAA,KACA,YAAA,KACA,YAAA,MACA,aAAA,EC9DN,aAAA,IAAA,OAEA,WAAA,IAAA,MAAA,YACA,cAAA,IAAA,MAAA,aDmE6C,yBAE3C,iCACE,SAAA,OACA,WAAA,EACA,OAAA,EACA,WAAA,KAGC,0BACD,YAAA,IACA,QAAA,aACA,eAAA,OClFJ,WAAA,IAAA,OAEA,YAAA,IAAA,MAAA,YACA,aAAA,IAAA,MAAA,YAKG,8EACD,gEADC,6EACD,+DADC,2EACD,6DACE,aAAA,KAFD,gGACD,kFADC,+FACD,iFADC,6FACD,+EACE,aAAA,KAFD,kHACD,oGADC,iHACD,mGADC,+GACD,iGACE,aAAA,KAFD,oIACD,sHADC,mIACD,qHADC,iIACD,mHACE,aAAA,KAFD,yFACD,2EACE,aAAA,KAFD,2GACD,6FACE,aAAA,KAFD,6HACD,+GACE,aAAA,KAFD,+IACD,iIACE,aAAA"} -------------------------------------------------------------------------------- /sites/MySite.py: -------------------------------------------------------------------------------- 1 | """Sample site class.""" 2 | from mdweb.MDSite import MDSite 3 | 4 | 5 | class MySite(MDSite): 6 | """An example MDWeb site.""" 7 | 8 | class MDConfig: # pylint: disable=R0903 9 | """Configuration of the example site.""" 10 | 11 | #: enable/disable Flask debug mode 12 | DEBUG = True 13 | 14 | #: Flask secret key 15 | # To generate a secret key you can use the os.urandom function 16 | # 17 | # >>> import os 18 | # >>> os.urandom(24) 19 | SECRET_KEY = 'create_a_secret_key_for_use_in_production' 20 | 21 | #: Path to page content relative to application root 22 | CONTENT_PATH = 'demo-content/' 23 | 24 | #: Name of theme (should be a sub-folder in themes/ 25 | THEME = 'bootstrap' 26 | 27 | #: Google Analytics tracking ID. If False GA tracking will not be used. 28 | # Your GA tracking ID will look like 'UA-00000000-1' 29 | GA_TRACKING_ID = False 30 | 31 | DEBUG_HELPER = False 32 | -------------------------------------------------------------------------------- /mdweb/Exceptions.py: -------------------------------------------------------------------------------- 1 | """MDWeb Exceptions.""" 2 | 3 | 4 | class ThemeException(Exception): 5 | """Theme directory or content error.""" 6 | 7 | pass 8 | 9 | 10 | class ConfigException(Exception): 11 | """Configuration error.""" 12 | 13 | pass 14 | 15 | 16 | class ContentException(Exception): 17 | """Markdown content exception.""" 18 | 19 | pass 20 | 21 | 22 | class ContentStructureException(Exception): 23 | """Invalid structure of content directory.""" 24 | 25 | pass 26 | 27 | 28 | class PageMetaInfFieldException(Exception): 29 | """Invalid field in page metadata.""" 30 | 31 | pass 32 | 33 | 34 | class PageParseException(Exception): 35 | """Error parsing page markdown.""" 36 | 37 | pass 38 | 39 | 40 | class FileExistsError(Exception): # pylint: disable=W0622 41 | """Shim for FileExistsError in Python 2.x.""" 42 | 43 | pass 44 | 45 | 46 | class PermissionError(Exception): # pylint: disable=W0622 47 | """Shim for FileExistsError in Python 2.x.""" 48 | 49 | pass 50 | -------------------------------------------------------------------------------- /demo-content/examples/embedding-html.md: -------------------------------------------------------------------------------- 1 | ```metainf 2 | Title: Embedding HTML Example 3 | Nav Name: Embedding HTML 4 | Description: An example of embedding HTML into a page 5 | Order: 4 6 | Teaser: A helpful example for embedding raw HTML into a content file 7 | for advanced content rendering. 8 | Sitemap Priority: 0.5 9 | Sitemap Changefreq: monthly 10 | ``` 11 | 12 | # Embedding HTML 13 | 14 | The Markdown parser used supports embeddable HTML. For example, the following 15 | block: 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
JillSmith50
EveJackson94
29 | 30 | will be rendered as: 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 |
JillSmith50
EveJackson94
44 | -------------------------------------------------------------------------------- /demo-content/documentation/Development/navigation.md: -------------------------------------------------------------------------------- 1 | ```metainf 2 | Title: The Navigation Object 3 | Nav Name: Navigation Object 4 | Description: MDWeb Navigation Object 5 | Order: 4 6 | Teaser: MDWeb navigation object reference. Useful reference for writing 7 | themes and plugins. 8 | Sitemap Priority: 0.5 9 | Sitemap Changefreq: monthly 10 | ``` 11 | 12 | #Navigation Object 13 | The navigation object is available within page templates and provides the 14 | site navigation structure as well as access to the page objects. 15 | 16 | The navigation template object is provided by the NavigationLevel class and has 17 | the following attributes available. 18 | 19 | * *name:* Section name. This is the lower case name extracted from the 20 | directory path. 21 | 22 | * *page:* The page object for this navigation level. 23 | 24 | * *path:* A short-cut to the filesystem path to the page (relative 25 | to the content directory). 26 | 27 | * *order:* A short-cut to the page order for this navigation level. 28 | 29 | * *meta:* A short-cut to the page meta-information. 30 | 31 | * *children:* A dictionary containing the child NavigationLevel objects. 32 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Chad Rempp 4 | 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 10 | of the Software, and to permit persons to whom the Software is furnished to do 11 | so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /mdweb/partials/opengraph.html: -------------------------------------------------------------------------------- 1 | {% if page.meta_inf is defined -%} 2 | {%- if page.meta_inf.title is defined and page.meta_inf.title != None -%} 3 | 4 | {% endif %} 5 | {%- if page.meta_inf.teaser_image is defined and page.meta_inf.teaser_image != None -%} 6 | 7 | {% endif %} 8 | {%- if page.meta_inf.description is defined and page.meta_inf.description != None -%} 9 | 10 | {% endif %} 11 | {%- if page.meta_inf.date is defined and page.meta_inf.date != None -%} 12 | 13 | {% endif %} 14 | {%- if page.meta_inf.author is defined and page.meta_inf.author != None -%} 15 | 16 | {%- endif %} 17 | {%- endif %} 18 | {% if page.url_path is defined and page.url_path != None -%} 19 | 20 | {%- endif %} 21 | 22 | -------------------------------------------------------------------------------- /themes/alpha/README.txt: -------------------------------------------------------------------------------- 1 | Alpha by HTML5 UP 2 | html5up.net | @n33co 3 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 4 | 5 | 6 | A clean, super minimal responsive template geared towards startups, app devs, and other 7 | dedicated folks working tirelessly to launch their products. Includes a landing page, 8 | generic page, contact page, and a page with a whole mess of pre-styled elements (something 9 | new I'm trying out). Sass sources are also included. 10 | 11 | Demo images* courtesy of Unsplash, a radtastic collection of CC0 (public domain) images 12 | you can use for pretty much whatever. 13 | 14 | (* = Not included) 15 | 16 | Feedback, bug reports, and comments are not only welcome, but strongly encouraged :) 17 | 18 | AJ 19 | n33.co @n33co dribbble.com/n33 20 | 21 | 22 | Credits: 23 | 24 | Demo Images: 25 | Unsplash (unsplash.com) 26 | 27 | Icons: 28 | Font Awesome (fortawesome.github.com/Font-Awesome) 29 | 30 | Other: 31 | jQuery (jquery.com) 32 | html5shiv.js (@afarkas @jdalton @jon_neal @rem) 33 | CSS3 Pie (css3pie.com) 34 | background-size polyfill (github.com/louisremi) 35 | skel (n33.co) -------------------------------------------------------------------------------- /themes/mdweb/README.txt: -------------------------------------------------------------------------------- 1 | Alpha by HTML5 UP 2 | html5up.net | @n33co 3 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 4 | 5 | 6 | A clean, super minimal responsive template geared towards startups, app devs, and other 7 | dedicated folks working tirelessly to launch their products. Includes a landing page, 8 | generic page, contact page, and a page with a whole mess of pre-styled elements (something 9 | new I'm trying out). Sass sources are also included. 10 | 11 | Demo images* courtesy of Unsplash, a radtastic collection of CC0 (public domain) images 12 | you can use for pretty much whatever. 13 | 14 | (* = Not included) 15 | 16 | Feedback, bug reports, and comments are not only welcome, but strongly encouraged :) 17 | 18 | AJ 19 | n33.co @n33co dribbble.com/n33 20 | 21 | 22 | Credits: 23 | 24 | Demo Images: 25 | Unsplash (unsplash.com) 26 | 27 | Icons: 28 | Font Awesome (fortawesome.github.com/Font-Awesome) 29 | 30 | Other: 31 | jQuery (jquery.com) 32 | html5shiv.js (@afarkas @jdalton @jon_neal @rem) 33 | CSS3 Pie (css3pie.com) 34 | background-size polyfill (github.com/louisremi) 35 | skel (n33.co) -------------------------------------------------------------------------------- /mdweb/Index.py: -------------------------------------------------------------------------------- 1 | """MDWeb Index View.""" 2 | from flask.views import View 3 | from flask import render_template, abort, current_app as app 4 | 5 | 6 | class Index(View): 7 | """The one view to rule them all. 8 | 9 | MDWeb has one single entry point. The MDWeb routing system (not Flasks) 10 | determines the how to handle the request and what markdown file to load. 11 | """ 12 | 13 | methods = ['GET'] 14 | 15 | @classmethod 16 | def render(cls, page): 17 | """Render the given page using the configured theme.""" 18 | if page.meta_inf.template: 19 | page_template = page.meta_inf.template 20 | else: 21 | page_template = 'page.html' 22 | 23 | context = { 24 | 'page': page.page_html, 25 | 'meta': page.meta_inf, 26 | } 27 | 28 | return render_template(page_template, **context) 29 | 30 | def dispatch_request(self, path=None, page=None): # pylint: disable=W0221 31 | """Dispatch request.""" 32 | if page is None: 33 | page = app.get_page(path) 34 | 35 | if page is None: 36 | abort(404) 37 | 38 | return self.render(page) 39 | -------------------------------------------------------------------------------- /themes/alpha/assets/sass/_mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin vendor-property($property, $value) { 2 | @each $vendor in ('-moz-', '-webkit-', '-o-', '-ms-', '') { 3 | #{$vendor}#{$property}: #{$value}; 4 | } 5 | } 6 | 7 | @mixin vendor-value($property, $value) { 8 | @each $vendor in ('-moz-', '-webkit-', '-o-', '-ms-', '') { 9 | #{$property}: #{$vendor}#{$value}; 10 | } 11 | } 12 | 13 | @mixin vendor($property, $value) { 14 | @each $vendor in ('-moz-', '-webkit-', '-o-', '-ms-', '') { 15 | #{$vendor}#{$property}: #{$vendor}#{$value}; 16 | } 17 | } 18 | 19 | @mixin vendor-keyframes($name) { 20 | @-moz-keyframes #{$name} { @content; } 21 | @-webkit-keyframes #{$name} { @content; } 22 | @-o-keyframes #{$name} { @content; } 23 | @-ms-keyframes #{$name} { @content; } 24 | @keyframes #{$name} { @content; } 25 | } 26 | 27 | @mixin icon($content: false) { 28 | text-decoration: none; 29 | 30 | &:before { 31 | @if $content { 32 | content: $content; 33 | } 34 | -moz-osx-font-smoothing: grayscale; 35 | -webkit-font-smoothing: antialiased; 36 | font-family: FontAwesome; 37 | font-style: normal; 38 | font-weight: normal; 39 | text-transform: none !important; 40 | } 41 | } -------------------------------------------------------------------------------- /themes/mdweb/assets/sass/_mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin vendor-property($property, $value) { 2 | @each $vendor in ('-moz-', '-webkit-', '-o-', '-ms-', '') { 3 | #{$vendor}#{$property}: #{$value}; 4 | } 5 | } 6 | 7 | @mixin vendor-value($property, $value) { 8 | @each $vendor in ('-moz-', '-webkit-', '-o-', '-ms-', '') { 9 | #{$property}: #{$vendor}#{$value}; 10 | } 11 | } 12 | 13 | @mixin vendor($property, $value) { 14 | @each $vendor in ('-moz-', '-webkit-', '-o-', '-ms-', '') { 15 | #{$vendor}#{$property}: #{$vendor}#{$value}; 16 | } 17 | } 18 | 19 | @mixin vendor-keyframes($name) { 20 | @-moz-keyframes #{$name} { @content; } 21 | @-webkit-keyframes #{$name} { @content; } 22 | @-o-keyframes #{$name} { @content; } 23 | @-ms-keyframes #{$name} { @content; } 24 | @keyframes #{$name} { @content; } 25 | } 26 | 27 | @mixin icon($content: false) { 28 | text-decoration: none; 29 | 30 | &:before { 31 | @if $content { 32 | content: $content; 33 | } 34 | -moz-osx-font-smoothing: grayscale; 35 | -webkit-font-smoothing: antialiased; 36 | font-family: FontAwesome; 37 | font-style: normal; 38 | font-weight: normal; 39 | text-transform: none !important; 40 | } 41 | } -------------------------------------------------------------------------------- /themes/bootstrap/templates/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Page Not Found 6 | 7 | 52 | 53 | 54 |

Page Not Found

55 |

Sorry, but the page you were trying to view does not exist.

56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /demo-content/documentation/devserver.md: -------------------------------------------------------------------------------- 1 | ```metainf 2 | Title: MDWeb Dev Server 3 | Nav Name: Dev Server 4 | Description: How to run the MDWeb in development mode 5 | Order: 5 6 | Teaser: Learn multiple ways to run MDWeb in a development environment. 7 | Possibilities include local Flask server, Docker, and more. 8 | Sitemap Priority: 0.5 9 | Sitemap Changefreq: monthly 10 | ``` 11 | 12 | 13 | #MDWeb Development Server 14 | 15 | The `dev_server` script starts a minimal development server which is based on 16 | the Werkzeug (WSGI) server. This is not for production use and will perform 17 | abysmally under even trivial loads. 18 | 19 | usage: dev_server [-h] [-d] [-p PORT] [-n NAME] [-l] [--log-level LOG_LEVEL] 20 | site 21 | 22 | Development Server Help 23 | 24 | positional arguments: 25 | site site class 26 | 27 | optional arguments: 28 | -h, --help show this help message and exit 29 | -d, --debug run in debug mode (for use with PyCharm) 30 | -p PORT, --port PORT port of server (default:5000) 31 | -n NAME, --name NAME application name 32 | -l, --list-sites list available applications 33 | --log-level LOG_LEVEL 34 | logging level ('CRITICAL', 'ERROR, 'WARNING','INFO', 35 | 'DEBUG', 'NOTSET') 36 | 37 | -------------------------------------------------------------------------------- /tests/test_debug_helper.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """Tests for the Debug Helper.""" 3 | from flask_testing import TestCase 4 | from tests.sites import MDTestSiteDebugHelper, MDTestSite 5 | 6 | 7 | class TestDebugHelperOn(TestCase): 8 | """Debug helper tests. 9 | 10 | Can't use pyfakefs for this or partials won't load""" 11 | 12 | def create_app(self): 13 | 14 | app = MDTestSiteDebugHelper( 15 | "MDWeb", 16 | app_options={} 17 | ) 18 | app.start() 19 | 20 | return app 21 | 22 | def test_debug_helper_loads(self): 23 | # self.app.DEBUG_HELPER 24 | with self.app.test_client() as client: 25 | response = client.get('/') 26 | response_data = response.get_data(as_text=True) 27 | self.assertTrue('
' in response_data) 28 | 29 | 30 | class TestDebugHelperOff(TestCase): 31 | """Debug helper tests. 32 | 33 | Can't use pyfakefs for this or partials won't load""" 34 | 35 | def create_app(self): 36 | app = MDTestSite( 37 | "MDWeb", 38 | app_options={} 39 | ) 40 | app.start() 41 | 42 | return app 43 | 44 | def test_debug_helper_loads(self): 45 | with self.app.test_client() as client: 46 | response = client.get('/') 47 | response_data = response.get_data(as_text=True) 48 | self.assertTrue('
' not in response_data) 49 | 50 | -------------------------------------------------------------------------------- /demo-content/about/history.md: -------------------------------------------------------------------------------- 1 | ```metainf 2 | Title: MDWeb History 3 | Nav Name: MDWeb History 4 | Description: The long and storied history of MDWeb 5 | Nav Name: History 6 | Order: 3 7 | Teaser Image: /contentassets/teaser.png 8 | Teaser: The long and storied history of MDWeb. 9 | Sitemap Priority: 0.5 10 | Sitemap Changefreq: monthly 11 | ``` 12 | 13 | MDWeb began out of my need for a framework to host a site for my 14 | personal projects called lapinlabs.com. Over the past four years I went 15 | through the following iterations: 16 | 17 | ### ~July 2012 18 | Started building a site in Python, Django and Django-CMS. This 19 | iteration was never completed. 20 | 21 | ### ~March 2013 22 | Started over again, this time using PHP and Drupal. This iteration was 23 | never completed. 24 | 25 | ### May 2014 26 | Started over again, this time using PHP and the Pico framework. I 27 | completed a basic version of this iteration but there were some issues 28 | I found with the Pico framework. Despite the issues I realized that 29 | the project was onto something. I decided to try a Markdown-based 30 | framework of my own. 31 | 32 | ### Jan 2015 33 | Started over again, this time building my own Markdown framework on 34 | top of Python and Flask. So far so good... 35 | 36 | ### The Present 37 | That brings us to the present. My projects site is now hosted on MDWeb 38 | (lapinlabs.com)[http://lapinlabs.com] and I consider my journey 39 | complete. I have opensourced the framework and hope others find it 40 | useful. 41 | 42 | -------------------------------------------------------------------------------- /wsgi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """WSGI server implementation for use by Gunicorn. 3 | 4 | If the following OS environment variables are provided they will be used to 5 | generate a site class 6 | * SITE_NAME 7 | * DEBUG 8 | * SECRET_KEY 9 | * CONTENT_PATH 10 | * THEME 11 | otherwise the default MySite will be used. 12 | """ 13 | import os 14 | from mdweb.MDSite import MDSite 15 | 16 | # If all required environment variables are set use them to build a site class 17 | if ('SITE_NAME' in os.environ and 18 | 'DEBUG' in os.environ and 19 | 'SECRET_KEY' in os.environ and 20 | 'CONTENT_PATH' in os.environ and 21 | 'THEME' in os.environ 22 | ): 23 | class SiteClass(MDSite): 24 | 25 | """SiteClass is MDSite class created from OS env vars.""" 26 | 27 | class MDConfig: # pylint: disable=R0903 28 | 29 | """Set the config values based on OS env vars.""" 30 | 31 | DEBUG = os.environ['DEBUG'] 32 | SECRET_KEY = os.environ['SECRET_KEY'] 33 | CONTENT_PATH = os.environ['CONTENT_PATH'] 34 | THEME = os.environ['THEME'] 35 | 36 | app = SiteClass( 37 | os.environ['SITE_NAME'], 38 | # Flask options that will be passed through to the Flask() constructor 39 | app_options={} 40 | ) 41 | 42 | else: 43 | from sites.MySite import MySite 44 | app = MySite( 45 | "MySite", 46 | # Flask options that will be passed through to the Flask() constructor 47 | app_options={} 48 | ) 49 | 50 | if __name__ == "__main__": 51 | app.start() 52 | app.run() 53 | -------------------------------------------------------------------------------- /demo-content/documentation/Development/events.md: -------------------------------------------------------------------------------- 1 | ```metainf 2 | Title: Event Hooks 3 | Nav Name: Event Hooks 4 | Description: MDWeb Event Hooks 5 | Order: 4 6 | Teaser: MDWeb system event hook reference. Useful reference for writing 7 | plugins. 8 | Sitemap Priority: 0.5 9 | Sitemap Changefreq: monthly 10 | ``` 11 | 12 | #System Event Hooks 13 | 14 | The following is an overview of the site start-up process including the 15 | subscribable events. The following process occurs in the order it's presented 16 | in. 17 | 18 | 1. *pre-boot:* Triggered at the beginning of the Site instantiation. The only 19 | thing that has happened at this point is signal creation. 20 | 21 | 2. \[ Internal pre-boot logic occurs \] 22 | 23 | 3. *pre-app-start:* Triggered before the Flask application is created. 24 | 25 | 4. \[ Flask application is created, routes are registered, error handlers 26 | are registered and logging is started \] 27 | 28 | 5. *post-app-start:* Triggered after the application has been created. 29 | 30 | 6. *pre-config:* Triggered before the configuration is loaded. 31 | 32 | 7. \[ Config loaded and added to Flask application, theme folder is setup, 33 | meta-inf regex is compiled \] 34 | 35 | 8. *post-config:* Triggered after the configuration is loaded. 36 | 37 | 9. *pre-content-scan:* Triggered before the content directory is scanned. 38 | 39 | 10. \[ The content directory is scanned and pages are created for each content 40 | file, the navigation object is created and the navigation context processor is 41 | created \] 42 | 43 | 11. *post-content-scan:* Triggered before the content directory is scanned. 44 | 45 | 12. \[ Internal post-boot logic occurs \] 46 | 47 | 13. *post-boot:* Triggered after all site setup is complete and the application 48 | is ready to start handling requests. 49 | -------------------------------------------------------------------------------- /prospector.txt: -------------------------------------------------------------------------------- 1 | Messages 2 | ======== 3 | 4 | mdweb/MDSite.py: 5 | L395:- MDSite._inject_debug_helper: mccabe - MC0001 6 | MDSite._inject_debug_helper is too complex (13) 7 | 8 | .: 9 | L-:- None: pylint - failure 10 | Tool pylint failed to run (exception was raised) 11 | 12 | sites.MySite (sites/MySite.py): 13 | L19:- None: dodgy - secret 14 | Possible hardcoded secret key 15 | 16 | mdweb/BaseObjects.py: 17 | L39:- MetaInfParser._parse_meta_inf: mccabe - MC0001 18 | MetaInfParser._parse_meta_inf is too complex (11) 19 | 20 | tests.sites (tests/sites.py): 21 | L273:- None: dodgy - secret 22 | Possible hardcoded secret key 23 | 24 | tests.sites (tests/sites.py): 25 | L258:- None: dodgy - secret 26 | Possible hardcoded secret key 27 | 28 | tests.sites (tests/sites.py): 29 | L243:- None: dodgy - secret 30 | Possible hardcoded secret key 31 | 32 | tests.sites (tests/sites.py): 33 | L228:- None: dodgy - secret 34 | Possible hardcoded secret key 35 | 36 | tests.sites (tests/sites.py): 37 | L213:- None: dodgy - secret 38 | Possible hardcoded secret key 39 | 40 | mdweb/Navigation.py: 41 | L173:- Navigation._scan: mccabe - MC0001 42 | Navigation._scan is too complex (12) 43 | 44 | sites.LapinlabsSite (sites/LapinlabsSite.py): 45 | L19:- None: dodgy - secret 46 | Possible hardcoded secret key 47 | 48 | 49 | 50 | Check Information 51 | ================= 52 | Started: 2017-05-22 02:35:22.912415 53 | Finished: 2017-05-22 02:35:25.402799 54 | Time Taken: 2.49 seconds 55 | Formatter: text 56 | Profiles: prospector.yml, no_doc_warnings, strictness_high, strictness_veryhigh, member_warnings 57 | Strictness: from profile 58 | Libraries Used: flask 59 | Tools Run: dodgy, mccabe, pep8, profile-validator, pyflakes, pylint 60 | Messages Found: 11 61 | 62 | -------------------------------------------------------------------------------- /themes/alpha/assets/sass/_vars.scss: -------------------------------------------------------------------------------- 1 | // Duration. 2 | $duration-transition: 0.2s; 3 | 4 | // Size. 5 | $size-border-radius: 6px; 6 | $size-element-height: 3em; 7 | $size-element-margin: 2em; 8 | 9 | // Font. 10 | $font-family: 'Source Sans Pro', sans-serif; 11 | $font-family-fixed: monospace; 12 | $font-weight: 300; 13 | $font-weight-bold: 400; 14 | 15 | // Color. 16 | $color-bg: #f5f5f5; 17 | $color-fg: #777; 18 | $color-fg-bold: #646464; 19 | $color-fg-light: #999; 20 | 21 | $color-accent1-bg: #666; 22 | $color-accent1-fg: mix($color-accent1-bg, #ffffff, 25%); 23 | $color-accent1-fg-bold: #ffffff; 24 | $color-accent1-fg-light: mix($color-accent1-bg, #ffffff, 40%); 25 | 26 | $color-accent2-bg: #e89980; 27 | $color-accent2-fg: mix($color-accent2-bg, #ffffff, 25%); 28 | $color-accent2-fg-bold: #ffffff; 29 | $color-accent2-fg-light: mix($color-accent2-bg, #ffffff, 40%); 30 | 31 | $color-accent3-bg: #7fcdb8; 32 | $color-accent3-fg: mix($color-accent3-bg, #ffffff, 25%); 33 | $color-accent3-fg-bold: #ffffff; 34 | $color-accent3-fg-light: mix($color-accent3-bg, #ffffff, 40%); 35 | 36 | $color-accent4-bg: #90b0ba; 37 | $color-accent4-fg: mix($color-accent4-bg, #ffffff, 25%); 38 | $color-accent4-fg-bold: #ffffff; 39 | $color-accent4-fg-light: mix($color-accent4-bg, #ffffff, 40%); 40 | 41 | $color-accent5-bg: #e5cb95; 42 | $color-accent5-fg: mix($color-accent5-bg, #ffffff, 25%); 43 | $color-accent5-fg-bold: #ffffff; 44 | $color-accent5-fg-light: mix($color-accent5-bg, #ffffff, 40%); 45 | 46 | $color-border: #e5e5e5; 47 | $color-border-bg: #f8f8f8; 48 | 49 | $color-border2: #dddddd; 50 | $color-border2-bg: #f0f0f0; 51 | 52 | $color-header-bg: #444; 53 | $color-header-fg: #bbb; 54 | $color-header-fg-bold: #fff; 55 | $color-header-fg-light: #999; -------------------------------------------------------------------------------- /themes/mdweb/assets/sass/_vars.scss: -------------------------------------------------------------------------------- 1 | // Duration. 2 | $duration-transition: 0.2s; 3 | 4 | // Size. 5 | $size-border-radius: 6px; 6 | $size-element-height: 3em; 7 | $size-element-margin: 2em; 8 | 9 | // Font. 10 | $font-family: 'Source Sans Pro', sans-serif; 11 | $font-family-fixed: monospace; 12 | $font-weight: 300; 13 | $font-weight-bold: 400; 14 | 15 | // Color. 16 | $color-bg: #f5f5f5; 17 | $color-fg: #777; 18 | $color-fg-bold: #646464; 19 | $color-fg-light: #999; 20 | 21 | $color-accent1-bg: #666; 22 | $color-accent1-fg: mix($color-accent1-bg, #ffffff, 25%); 23 | $color-accent1-fg-bold: #ffffff; 24 | $color-accent1-fg-light: mix($color-accent1-bg, #ffffff, 40%); 25 | 26 | $color-accent2-bg: #e89980; 27 | $color-accent2-fg: mix($color-accent2-bg, #ffffff, 25%); 28 | $color-accent2-fg-bold: #ffffff; 29 | $color-accent2-fg-light: mix($color-accent2-bg, #ffffff, 40%); 30 | 31 | $color-accent3-bg: #7fcdb8; 32 | $color-accent3-fg: mix($color-accent3-bg, #ffffff, 25%); 33 | $color-accent3-fg-bold: #ffffff; 34 | $color-accent3-fg-light: mix($color-accent3-bg, #ffffff, 40%); 35 | 36 | $color-accent4-bg: #90b0ba; 37 | $color-accent4-fg: mix($color-accent4-bg, #ffffff, 25%); 38 | $color-accent4-fg-bold: #ffffff; 39 | $color-accent4-fg-light: mix($color-accent4-bg, #ffffff, 40%); 40 | 41 | $color-accent5-bg: #e5cb95; 42 | $color-accent5-fg: mix($color-accent5-bg, #ffffff, 25%); 43 | $color-accent5-fg-bold: #ffffff; 44 | $color-accent5-fg-light: mix($color-accent5-bg, #ffffff, 40%); 45 | 46 | $color-border: #e5e5e5; 47 | $color-border-bg: #f8f8f8; 48 | 49 | $color-border2: #dddddd; 50 | $color-border2-bg: #f0f0f0; 51 | 52 | $color-header-bg: #444; 53 | $color-header-fg: #bbb; 54 | $color-header-fg-bold: #fff; 55 | $color-header-fg-light: #999; -------------------------------------------------------------------------------- /tests/test_baseobjects.py: -------------------------------------------------------------------------------- 1 | """Tests for the MDWeb Base Objects.""" 2 | from pyfakefs import fake_filesystem_unittest, fake_filesystem 3 | import unittest 4 | from mdweb.BaseObjects import MetaInfParser 5 | from mdweb.Exceptions import PageMetaInfFieldException 6 | from mdweb.Navigation import Navigation 7 | from mdweb.Page import Page, load_page 8 | 9 | 10 | class TesNavigationBaseItem(fake_filesystem_unittest.TestCase): 11 | 12 | """MDSite Navigation Base tests.""" 13 | 14 | def setUp(self): 15 | """Create fake filesystem.""" 16 | self.setUpPyfakefs() 17 | self.fake_os = fake_filesystem.FakeOsModule(self.fs) 18 | 19 | def test_navigation_type(self): 20 | """A directory should have navigation type 'Navigation'.""" 21 | self.fs.create_file('/my/content/index.md') 22 | nav = Navigation('/my/content') 23 | 24 | self.assertEqual(nav.nav_type, "Navigation") 25 | 26 | def test_page_type(self): 27 | """A file in a directory should have navigation type 'Page'.""" 28 | file_string = u"" 29 | self.fs.create_file('/my/content/index.md', 30 | contents=file_string) 31 | 32 | page = Page(*load_page('/my/content', '/my/content/index.md')) 33 | 34 | self.assertEqual(page.nav_type, "Page") 35 | 36 | 37 | class TestMetaInfParser(unittest.TestCase): 38 | 39 | """Index object tests.""" 40 | 41 | class MockMetaInf(MetaInfParser): # pylint: disable=R0903 42 | 43 | """MDWeb Navigation Meta Information.""" 44 | 45 | FIELD_TYPES = { 46 | 'nav_name': ('unicode', None), 47 | 'order': ('int', 0), 48 | } 49 | 50 | def test_blank_value(self): 51 | """A blank value in a meta-inf definition should raise exception.""" 52 | self.assertRaises(PageMetaInfFieldException, 53 | self.MockMetaInf, 54 | '''Nav Name: Documentation 55 | Order: ''') 56 | -------------------------------------------------------------------------------- /themes/alpha/assets/css/style-mobilep.css: -------------------------------------------------------------------------------- 1 | /* 2 | Alpha by HTML5 UP 3 | html5up.net | @n33co 4 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | */ 6 | 7 | /* Basic */ 8 | 9 | html, body { 10 | min-width: 320px; 11 | } 12 | 13 | body, input, select, textarea { 14 | font-size: 11pt; 15 | } 16 | 17 | /* Section/Article */ 18 | 19 | header.major { 20 | padding: 0; 21 | } 22 | 23 | /* List */ 24 | 25 | ul.actions { 26 | margin: 0 0 2em 0; 27 | } 28 | 29 | ul.actions li { 30 | display: block; 31 | padding: 1em 0 0 0; 32 | text-align: center; 33 | width: 100%; 34 | } 35 | 36 | ul.actions li:first-child { 37 | padding-top: 0; 38 | } 39 | 40 | ul.actions li > * { 41 | width: 100%; 42 | margin: 0 !important; 43 | } 44 | 45 | ul.actions li > *.icon:before { 46 | margin-left: -2em; 47 | } 48 | 49 | ul.actions.small li { 50 | padding: 0.5em 0 0 0; 51 | } 52 | 53 | ul.actions.small li:first-child { 54 | padding-top: 0; 55 | } 56 | 57 | /* Box */ 58 | 59 | .box { 60 | border-radius: 0; 61 | box-shadow: none; 62 | margin: 1em 0 0 0; 63 | padding: 3em 1em !important; 64 | } 65 | 66 | .box.features .features-row section { 67 | margin: 3em 0 0 0 !important; 68 | padding: 3em 0 0 0 !important; 69 | } 70 | 71 | .box .image.featured { 72 | border-radius: 0; 73 | margin-left: -1em; 74 | width: calc(100% + 2em); 75 | } 76 | 77 | .box .image.featured img { 78 | border-radius: 0 !important; 79 | } 80 | 81 | .box .image.featured:first-child { 82 | margin-bottom: 3em; 83 | margin-top: -3em; 84 | } 85 | 86 | .box .image.featured:last-child { 87 | margin-bottom: -3em; 88 | margin-top: 3em; 89 | } 90 | 91 | /* Banner */ 92 | 93 | #banner { 94 | padding: 5em 1em 4em 1em; 95 | } 96 | 97 | /* Main */ 98 | 99 | #main > .box:first-child { 100 | margin-top: 0; 101 | } 102 | 103 | /* CTA */ 104 | 105 | #cta { 106 | padding: 2.5em 1em 3em 1em; 107 | } -------------------------------------------------------------------------------- /themes/mdweb/assets/css/style-mobilep.css: -------------------------------------------------------------------------------- 1 | /* 2 | Alpha by HTML5 UP 3 | html5up.net | @n33co 4 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | */ 6 | 7 | /* Basic */ 8 | 9 | html, body { 10 | min-width: 320px; 11 | } 12 | 13 | body, input, select, textarea { 14 | font-size: 11pt; 15 | } 16 | 17 | /* Section/Article */ 18 | 19 | header.major { 20 | padding: 0; 21 | } 22 | 23 | /* List */ 24 | 25 | ul.actions { 26 | margin: 0 0 2em 0; 27 | } 28 | 29 | ul.actions li { 30 | display: block; 31 | padding: 1em 0 0 0; 32 | text-align: center; 33 | width: 100%; 34 | } 35 | 36 | ul.actions li:first-child { 37 | padding-top: 0; 38 | } 39 | 40 | ul.actions li > * { 41 | width: 100%; 42 | margin: 0 !important; 43 | } 44 | 45 | ul.actions li > *.icon:before { 46 | margin-left: -2em; 47 | } 48 | 49 | ul.actions.small li { 50 | padding: 0.5em 0 0 0; 51 | } 52 | 53 | ul.actions.small li:first-child { 54 | padding-top: 0; 55 | } 56 | 57 | /* Box */ 58 | 59 | .box { 60 | border-radius: 0; 61 | box-shadow: none; 62 | margin: 1em 0 0 0; 63 | padding: 3em 1em !important; 64 | } 65 | 66 | .box.features .features-row section { 67 | margin: 3em 0 0 0 !important; 68 | padding: 3em 0 0 0 !important; 69 | } 70 | 71 | .box .image.featured { 72 | border-radius: 0; 73 | margin-left: -1em; 74 | width: calc(100% + 2em); 75 | } 76 | 77 | .box .image.featured img { 78 | border-radius: 0 !important; 79 | } 80 | 81 | .box .image.featured:first-child { 82 | margin-bottom: 3em; 83 | margin-top: -3em; 84 | } 85 | 86 | .box .image.featured:last-child { 87 | margin-bottom: -3em; 88 | margin-top: 3em; 89 | } 90 | 91 | /* Banner */ 92 | 93 | #banner { 94 | padding: 5em 1em 4em 1em; 95 | } 96 | 97 | /* Main */ 98 | 99 | #main > .box:first-child { 100 | margin-top: 0; 101 | } 102 | 103 | /* CTA */ 104 | 105 | #cta { 106 | padding: 2.5em 1em 3em 1em; 107 | } -------------------------------------------------------------------------------- /demo-content/about/license.md: -------------------------------------------------------------------------------- 1 | ```metainf 2 | Title: MDWeb License 3 | Nav Name: MDWeb License 4 | Description: MDWeb Opensource License 5 | Nav Name: License 6 | Order: 99 7 | Teaser: MDWeb is released under the MIT license. 8 | Sitemap Priority: 0.1 9 | Sitemap Changefreq: never 10 | ``` 11 | 12 | ## MDWeb License 13 | 14 | MDWeb is released under the MIT license. 15 | 16 | Copyright (c) 2016 Chad Rempp 17 | 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a 20 | copy of this software and associated documentation files (the "Software"), 21 | to deal in the Software without restriction, including without limitation 22 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 23 | and/or sell copies of the Software, and to permit persons to whom the 24 | Software is furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 34 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 35 | DEALINGS IN THE SOFTWARE. 36 | 37 | You are free to use MDWeb in any other project (even commercial projects) as 38 | long as the copyright header is left intact. 39 | 40 | ##Themes 41 | Alpha theme modified from the [Alpha site template](http://html5up.net/alpha) 42 | on [html5up.net](http://html5up.net). This site template was licensed under 43 | [CCA 3.0](html5up.net/license). 44 | 45 | Bootstrap theme modified from 46 | [Bootstrap examples](http://getbootstrap.com/getting-started/#examples). 47 | The Bootstrap examples are licensed under the 48 | [MIT License](https://github.com/twbs/bootstrap/blob/master/LICENSE). 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /demo-content/documentation/quickstart.md: -------------------------------------------------------------------------------- 1 | ```metainf 2 | Title: MDWeb Quick Start 3 | Nav Name: Quick Start 4 | Description: How to quickly get MDWeb running 5 | Order: 1 6 | Teaser: Learn how to setup MDWeb in 5 minutes or less. Step-by-step 7 | instructions are given. 8 | Sitemap Priority: 0.5 9 | Sitemap Changefreq: monthly 10 | ``` 11 | 12 | # Quickstart 13 | 14 | ## Requirements 15 | * Python 2.7 or 3.x 16 | * Pip 17 | * Virtualenv (optional, highly recommended) 18 | 19 | 20 | ## General usage guidlines 21 | 22 | * Fork the repository. 23 | 24 | * Clone your forked repository on your local machine. 25 | 26 | * Copy `sites/MySite.py.example` to `sites/MySite.py` or what ever name you 27 | choose for your site class. Inside the copied file rename the class to match 28 | the file name - for example if you call the file `JoesSite.py` the Class 29 | should be named `JoesSite`. 30 | 31 | * Update the config attributes in the site class, specifically `THEME` and 32 | `CONTENT_PATH` (I suggest using the provided, empty, `content` directory). 33 | The `demo-content` directory is provided with example content to get you 34 | started. 35 | 36 | * Add your content to the content directory defined. 37 | 38 | * (optional) Create a new theme for your site in the `themes` directory. If 39 | you add a new theme remember to update the THEME config value. 40 | 41 | * Run the application (assuming you have a virtual environment setup). The 42 | dev_server script has one required parameter which is the site class name, 43 | in the example about the class name was `JoesSite`. 44 | 45 | 46 | ## Quick setup 47 | * Setup a virtual environment and activate 48 | ``` 49 | $ virtualenv mymdwebenv 50 | $ source ./mymdwebenv/bin/activate 51 | ``` 52 | * Clone the project 53 | ``` 54 | $ git clone git@github.com:crempp/mdweb.git 55 | ``` 56 | * Go into the directory 57 | ``` 58 | $ cd mdweb 59 | ``` 60 | * Install requirements 61 | ``` 62 | $ pip install -r requirements.txt 63 | ``` 64 | * Setup site class 65 | ``` 66 | $ cp sites/MySite.py.example sites/JoesSite.py 67 | $ nano sites/JoesSite.py 68 | # Edit the class name and config as described above 69 | ``` 70 | * Run the server 71 | ``` 72 | $ ./bin/dev_server JoesSite 73 | ``` 74 | 75 | Now visit [http://127.0.0.1:5000](http://127.0.0.1:5000) 76 | -------------------------------------------------------------------------------- /themes/alpha/assets/css/ie/html5shiv.js: -------------------------------------------------------------------------------- 1 | /* 2 | HTML5 Shiv v3.6.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 3 | */ 4 | (function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag(); 5 | a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/\w+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x"; 6 | c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode|| 7 | "undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup main mark meter nav output progress section summary time video",version:"3.6.2",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);if(g)return a.createDocumentFragment(); 8 | for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d 4 | {# Home Section #} 5 |
6 |
7 |
8 |
9 | 10 |
11 |
12 |

{{ navigation.page.meta_inf.title }}

13 |

{{ page | safe}}

14 |
15 |
16 |
17 |
18 | 19 | {# Section for each nav entry #} 20 | {% for nav in navigation.children if nav.children|length > 0 -%} 21 |
22 |
23 | 24 | {{ nav.name }} 25 | 26 | 27 | 28 | more {{ nav.name | lower }} 29 | 30 | 31 | 32 |
33 |
34 |
35 | 36 | {% for page in nav.child_pages[0:3] %} 37 |
38 |
39 | {% if page.meta_inf.teaser_image %} 40 | 41 | {% endif %} 42 |
43 |

{{ page.meta_inf.title }}

44 |

45 |

46 | {% if page.meta_inf.author %} 47 | by {{ page.meta_inf.author }} 48 | {% endif %} 49 | {% if page.meta_inf.date %} 50 | on {{ page.meta_inf.date }} 51 | {% endif %} 52 |
53 | {{ page.meta_inf.teaser }} 54 |

55 | Read more... 56 |
57 |
58 |
59 | {% endfor %} 60 | 61 |
62 |
63 |
64 | {% endfor %} 65 | 66 | 67 | {% endblock %} 68 | -------------------------------------------------------------------------------- /themes/mdweb/assets/css/ie/html5shiv.js: -------------------------------------------------------------------------------- 1 | /* 2 | HTML5 Shiv v3.6.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 3 | */ 4 | (function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag(); 5 | a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/\w+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x"; 6 | c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode|| 7 | "undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup main mark meter nav output progress section summary time video",version:"3.6.2",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);if(g)return a.createDocumentFragment(); 8 | for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;dFoo Article 40 | |- examples/ 41 | |- index.md Examples section landing page 42 | |- help/ 43 | |- index.md Help section landing page 44 | |- how_to.md Page located in Help->HowTo 45 | 46 | 47 | ##Content Meta Fields 48 | * *Title:* The page title. In the provided templates this will be used in the 49 | `` tag and in the page header. 50 | 51 | * *Nav Name:* The name that will appear in the navigation 52 | 53 | * *Description:* The page description. In the provided templates this will be 54 | used in meta description tag. 55 | 56 | * *Author:* The page author. This is useful for blog posts and articles. 57 | 58 | * *Date:* The page creation date. This is useful for blog posts and articles. 59 | 60 | * *Order:* The order the page will appear in navigation. 61 | 62 | * *Template:* The template to use for page rendering. Defaults to page.html 63 | -------------------------------------------------------------------------------- /themes/alpha/assets/css/style-mobile.css: -------------------------------------------------------------------------------- 1 | /* 2 | Alpha by HTML5 UP 3 | html5up.net | @n33co 4 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | */ 6 | 7 | /* Basic */ 8 | 9 | body, input, select, textarea { 10 | font-size: 11pt; 11 | } 12 | 13 | h2 { 14 | font-size: 1.75em; 15 | line-height: 1.35em; 16 | letter-spacing: -0.025em; 17 | } 18 | 19 | h3 { 20 | font-size: 1.5em; 21 | } 22 | 23 | h4 { 24 | font-size: 1em; 25 | } 26 | 27 | /* Section/Article */ 28 | 29 | header.major { 30 | padding: 1em; 31 | } 32 | 33 | header.major h2, header.major p { 34 | padding-left: 0.5em; 35 | padding-right: 0.5em; 36 | } 37 | 38 | /* Box */ 39 | 40 | .box { 41 | margin: 1em; 42 | overflow-x: hidden; 43 | padding: 2em 2em !important; 44 | } 45 | 46 | .box.features .features-row { 47 | border-top: 0; 48 | padding: 0; 49 | } 50 | 51 | .box.features .features-row section { 52 | border: 0; 53 | border-top: solid 1px #e5e5e5 !important; 54 | float: none; 55 | margin: 2em 0 0 0 !important; 56 | padding: 2em 0 0 0 !important; 57 | width: 100%; 58 | } 59 | 60 | .box.features .features-row:first-child section:first-child { 61 | border-top: 0 !important; 62 | margin-top: 0 !important; 63 | padding-top: 0 !important; 64 | } 65 | 66 | .box .image.featured { 67 | margin-left: -2em; 68 | width: calc(100% + 4em); 69 | } 70 | 71 | .box .image.featured:first-child { 72 | margin-bottom: 2em; 73 | margin-top: -2em; 74 | } 75 | 76 | .box .image.featured:last-child { 77 | margin-bottom: -2em; 78 | margin-top: 2em; 79 | } 80 | 81 | /* Banner */ 82 | 83 | #banner { 84 | padding: 4em 0; 85 | } 86 | 87 | #banner h2 { 88 | font-size: 2.25em; 89 | } 90 | 91 | #banner p { 92 | font-size: 1.25em; 93 | } 94 | 95 | /* Main */ 96 | 97 | #main { 98 | padding: 4em 0 0 0; 99 | } 100 | 101 | #main > header { 102 | margin: 0 2em 1.5em 2em; 103 | } 104 | 105 | #main > header h2 { 106 | font-size: 2em; 107 | } 108 | 109 | #main > header p { 110 | font-size: 1em; 111 | padding-bottom: 1em; 112 | } 113 | 114 | body.landing #main { 115 | padding: 0; 116 | margin-top: 0; 117 | } 118 | 119 | /* Footer */ 120 | 121 | #footer { 122 | padding: 4em 0; 123 | } 124 | 125 | #footer .copyright li { 126 | border-left: 0; 127 | display: block; 128 | line-height: 2em; 129 | margin-left: 0; 130 | padding-left: 0; 131 | } -------------------------------------------------------------------------------- /themes/mdweb/assets/css/style-mobile.css: -------------------------------------------------------------------------------- 1 | /* 2 | Alpha by HTML5 UP 3 | html5up.net | @n33co 4 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | */ 6 | 7 | /* Basic */ 8 | 9 | body, input, select, textarea { 10 | font-size: 11pt; 11 | } 12 | 13 | h2 { 14 | font-size: 1.75em; 15 | line-height: 1.35em; 16 | letter-spacing: -0.025em; 17 | } 18 | 19 | h3 { 20 | font-size: 1.5em; 21 | } 22 | 23 | h4 { 24 | font-size: 1em; 25 | } 26 | 27 | /* Section/Article */ 28 | 29 | header.major { 30 | padding: 1em; 31 | } 32 | 33 | header.major h2, header.major p { 34 | padding-left: 0.5em; 35 | padding-right: 0.5em; 36 | } 37 | 38 | /* Box */ 39 | 40 | .box { 41 | margin: 1em; 42 | overflow-x: hidden; 43 | padding: 2em 2em !important; 44 | } 45 | 46 | .box.features .features-row { 47 | border-top: 0; 48 | padding: 0; 49 | } 50 | 51 | .box.features .features-row section { 52 | border: 0; 53 | border-top: solid 1px #e5e5e5 !important; 54 | float: none; 55 | margin: 2em 0 0 0 !important; 56 | padding: 2em 0 0 0 !important; 57 | width: 100%; 58 | } 59 | 60 | .box.features .features-row:first-child section:first-child { 61 | border-top: 0 !important; 62 | margin-top: 0 !important; 63 | padding-top: 0 !important; 64 | } 65 | 66 | .box .image.featured { 67 | margin-left: -2em; 68 | width: calc(100% + 4em); 69 | } 70 | 71 | .box .image.featured:first-child { 72 | margin-bottom: 2em; 73 | margin-top: -2em; 74 | } 75 | 76 | .box .image.featured:last-child { 77 | margin-bottom: -2em; 78 | margin-top: 2em; 79 | } 80 | 81 | /* Banner */ 82 | 83 | #banner { 84 | padding: 4em 0; 85 | } 86 | 87 | #banner h2 { 88 | font-size: 2.25em; 89 | } 90 | 91 | #banner p { 92 | font-size: 1.25em; 93 | } 94 | 95 | /* Main */ 96 | 97 | #main { 98 | padding: 4em 0 0 0; 99 | } 100 | 101 | #main > header { 102 | margin: 0 2em 1.5em 2em; 103 | } 104 | 105 | #main > header h2 { 106 | font-size: 2em; 107 | } 108 | 109 | #main > header p { 110 | font-size: 1em; 111 | padding-bottom: 1em; 112 | } 113 | 114 | body.landing #main { 115 | padding: 0; 116 | margin-top: 0; 117 | } 118 | 119 | /* Footer */ 120 | 121 | #footer { 122 | padding: 4em 0; 123 | } 124 | 125 | #footer .copyright li { 126 | border-left: 0; 127 | display: block; 128 | line-height: 2em; 129 | margin-left: 0; 130 | padding-left: 0; 131 | } -------------------------------------------------------------------------------- /themes/bootstrap/assets/js/bootstrap-submenu.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap-submenu v2.0.3 (https://vsn4ik.github.io/bootstrap-submenu/) 3 | * Copyright 2015 Vasily A. (https://github.com/vsn4ik) 4 | * Licensed under the MIT license 5 | */ 6 | 7 | "use strict";!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){function b(b){this.$element=a(b),this.$menu=this.$element.closest(".dropdown-menu"),this.$main=this.$menu.parent(),this.$items=this.$menu.children(".dropdown-submenu"),this.init()}function c(b){this.$element=a(b),this.$main=this.$element.parent(),this.$menu=this.$main.children(".dropdown-menu"),this.$subs=this.$main.siblings(".dropdown-submenu"),this.$items=this.$menu.children(".dropdown-submenu"),this.init()}function d(b){this.$element=a(b),this.$main=this.$element.parent(),this.$menu=this.$main.children(".dropdown-menu"),this.$items=this.$menu.children(".dropdown-submenu"),this.init()}return b.prototype={init:function(){this.$element.on("keydown",a.proxy(this,"keydown"))},close:function(){this.$main.removeClass("open"),this.$items.trigger("hide.bs.submenu")},keydown:function(a){27==a.keyCode&&(a.stopPropagation(),this.close(),this.$main.children("a, button").trigger("focus"))}},a.extend(c.prototype,b.prototype,{init:function(){this.$element.on({click:a.proxy(this,"click"),keydown:a.proxy(this,"keydown")}),this.$main.on("hide.bs.submenu",a.proxy(this,"hide"))},click:function(a){a.preventDefault(),a.stopPropagation(),this.toggle()},hide:function(a){a.stopPropagation(),this.close()},open:function(){this.$main.addClass("open"),this.$subs.trigger("hide.bs.submenu")},toggle:function(){this.$main.hasClass("open")?this.close():this.open()},keydown:function(b){32==b.keyCode&&b.preventDefault(),-1!=a.inArray(b.keyCode,[13,32])&&this.toggle()}}),d.prototype={init:function(){this.$menu.off("keydown.bs.dropdown.data-api"),this.$menu.on("keydown",a.proxy(this,"itemKeydown")),this.$menu.find("li > a").each(function(){new b(this)}),this.$menu.find(".dropdown-submenu > a").each(function(){new c(this)}),this.$main.on("hidden.bs.dropdown",a.proxy(this,"hidden"))},hidden:function(){this.$items.trigger("hide.bs.submenu")},itemKeydown:function(b){if(-1!=a.inArray(b.keyCode,[38,40])){b.preventDefault(),b.stopPropagation();var c=this.$menu.find("li:not(.disabled):visible > a"),d=c.index(b.target);if(38==b.keyCode&&0!==d)d--;else{if(40!=b.keyCode||d===c.length-1)return;d++}c.eq(d).trigger("focus")}}},a.fn.submenupicker=function(b){var c=this instanceof a?this:a(b);return c.each(function(){var b=a.data(this,"bs.submenu");b||(b=new d(this),a.data(this,"bs.submenu",b))})}}); -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Requires variables 2 | # * DO_TOKEN 3 | # * DOCKER_USER 4 | # * DOCKER_PASS 5 | # * DEPLOY_NODE 6 | 7 | defaults: &DEFAULT 8 | working_directory: ~/app 9 | docker: 10 | - image: docker:17.09.0-ce-git 11 | 12 | version: 2 13 | jobs: 14 | build: 15 | <<: *DEFAULT 16 | steps: 17 | - checkout 18 | - setup_remote_docker: 19 | docker_layer_caching: false 20 | - run: 21 | name: Install dependencies 22 | command: echo "No dependencies" 23 | - run: 24 | name: Build application Docker image 25 | command: | 26 | docker build -t lapinlabs/mdweb . 27 | # Note: we don't push here, we wait for tests to pass and push in the deploy job 28 | 29 | test: 30 | <<: *DEFAULT 31 | steps: 32 | - checkout 33 | - setup_remote_docker 34 | - run: 35 | name: Build test container 36 | command: | 37 | docker build -t mdweb-test -f Dockerfile.test . 38 | docker run --name test-app mdweb-test 39 | docker cp test-app:/opt/mdweb/coverage /tmp/coverage 40 | - store_artifacts: 41 | path: /tmp/coverage 42 | - store_test_results: 43 | path: /tmp/coverage 44 | 45 | deploy: 46 | <<: *DEFAULT 47 | steps: 48 | - checkout 49 | - setup_remote_docker 50 | - run: 51 | name: Push application Docker image 52 | command: | 53 | docker login -u $DOCKER_USER -p $DOCKER_PASS 54 | docker tag lapinlabs/mdweb lapinlabs/mdweb:${CIRCLE_BRANCH//\//-}-${CIRCLE_BUILD_NUM} 55 | docker push lapinlabs/mdweb:${CIRCLE_BRANCH//\//-}-${CIRCLE_BUILD_NUM} 56 | docker push lapinlabs/mdweb:latest 57 | - run: 58 | name: Remotely deploy to droplet 59 | command: | 60 | apk add --update curl curl-dev jq 61 | export IP=`curl -s -X GET -H "Content-Type: application/json" -H "Authorization: Bearer $DO_TOKEN" "https://api.digitalocean.com/v2/droplets/" | jq ".droplets[] | select(.name == \"$DEPLOY_NODE\") | .networks.v4[0].ip_address"` 62 | export IP=`echo $IP | sed -e 's/^"//' -e 's/"$//'` 63 | echo "Deploying to $DEPLOY_NODE [$IP]" 64 | ssh -o StrictHostKeyChecking=no root@${IP} "service container-mdweb redeploy" 65 | 66 | workflows: 67 | version: 2 68 | build-test-and-deploy: 69 | jobs: 70 | - test: 71 | context: deployment 72 | - build: 73 | context: deployment 74 | - deploy: 75 | context: deployment 76 | requires: 77 | - build 78 | - test 79 | filters: 80 | branches: 81 | only: 82 | - master 83 | -------------------------------------------------------------------------------- /themes/alpha/assets/sass/style-mobilep.scss: -------------------------------------------------------------------------------- 1 | @import 'vars'; 2 | @import 'mixins'; 3 | 4 | /* 5 | Alpha by HTML5 UP 6 | html5up.net | @n33co 7 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 8 | */ 9 | 10 | /* Basic */ 11 | 12 | html, body { 13 | min-width: 320px; 14 | } 15 | 16 | body, input, select, textarea { 17 | font-size: 11pt; 18 | } 19 | 20 | /* Section/Article */ 21 | 22 | header { 23 | &.major { 24 | padding: 0; 25 | } 26 | } 27 | 28 | /* List */ 29 | 30 | ul { 31 | &.actions { 32 | margin: 0 0 $size-element-margin 0; 33 | 34 | li { 35 | display: block; 36 | padding: ($size-element-margin * 0.5) 0 0 0; 37 | text-align: center; 38 | width: 100%; 39 | 40 | &:first-child { 41 | padding-top: 0; 42 | } 43 | 44 | > * { 45 | width: 100%; 46 | margin: 0 !important; 47 | 48 | &.icon { 49 | &:before { 50 | margin-left: -2em; 51 | } 52 | } 53 | } 54 | } 55 | 56 | &.small { 57 | li { 58 | padding: ($size-element-margin * 0.25) 0 0 0; 59 | 60 | &:first-child { 61 | padding-top: 0; 62 | } 63 | } 64 | } 65 | } 66 | } 67 | 68 | /* Box */ 69 | 70 | $box-padding-vertical: 3em; 71 | $box-padding-horizontal: 1em; 72 | 73 | .box { 74 | border-radius: 0; 75 | box-shadow: none; 76 | margin: ($size-element-margin * 0.5) 0 0 0; 77 | padding: $box-padding-vertical $box-padding-horizontal !important; 78 | 79 | &.features { 80 | .features-row { 81 | section { 82 | margin: $box-padding-vertical 0 0 0 !important; 83 | padding: $box-padding-vertical 0 0 0 !important; 84 | } 85 | } 86 | } 87 | 88 | .image { 89 | &.featured { 90 | border-radius: 0; 91 | margin-left: ($box-padding-horizontal * -1); 92 | width: calc(100% + #{$box-padding-horizontal * 2}); 93 | 94 | img { 95 | border-radius: 0 !important; 96 | } 97 | 98 | &:first-child { 99 | margin-bottom: $box-padding-vertical; 100 | margin-top: $box-padding-vertical * -1; 101 | } 102 | 103 | &:last-child { 104 | margin-bottom: $box-padding-vertical * -1; 105 | margin-top: $box-padding-vertical; 106 | } 107 | } 108 | } 109 | } 110 | 111 | /* Banner */ 112 | 113 | #banner { 114 | padding: 5em 1em 4em 1em; 115 | } 116 | 117 | /* Main */ 118 | 119 | #main { 120 | > .box { 121 | &:first-child { 122 | margin-top: 0; 123 | } 124 | } 125 | } 126 | 127 | /* CTA */ 128 | 129 | #cta { 130 | padding: 2.5em 1em 3em 1em; 131 | } -------------------------------------------------------------------------------- /themes/mdweb/assets/sass/style-mobilep.scss: -------------------------------------------------------------------------------- 1 | @import 'vars'; 2 | @import 'mixins'; 3 | 4 | /* 5 | Alpha by HTML5 UP 6 | html5up.net | @n33co 7 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 8 | */ 9 | 10 | /* Basic */ 11 | 12 | html, body { 13 | min-width: 320px; 14 | } 15 | 16 | body, input, select, textarea { 17 | font-size: 11pt; 18 | } 19 | 20 | /* Section/Article */ 21 | 22 | header { 23 | &.major { 24 | padding: 0; 25 | } 26 | } 27 | 28 | /* List */ 29 | 30 | ul { 31 | &.actions { 32 | margin: 0 0 $size-element-margin 0; 33 | 34 | li { 35 | display: block; 36 | padding: ($size-element-margin * 0.5) 0 0 0; 37 | text-align: center; 38 | width: 100%; 39 | 40 | &:first-child { 41 | padding-top: 0; 42 | } 43 | 44 | > * { 45 | width: 100%; 46 | margin: 0 !important; 47 | 48 | &.icon { 49 | &:before { 50 | margin-left: -2em; 51 | } 52 | } 53 | } 54 | } 55 | 56 | &.small { 57 | li { 58 | padding: ($size-element-margin * 0.25) 0 0 0; 59 | 60 | &:first-child { 61 | padding-top: 0; 62 | } 63 | } 64 | } 65 | } 66 | } 67 | 68 | /* Box */ 69 | 70 | $box-padding-vertical: 3em; 71 | $box-padding-horizontal: 1em; 72 | 73 | .box { 74 | border-radius: 0; 75 | box-shadow: none; 76 | margin: ($size-element-margin * 0.5) 0 0 0; 77 | padding: $box-padding-vertical $box-padding-horizontal !important; 78 | 79 | &.features { 80 | .features-row { 81 | section { 82 | margin: $box-padding-vertical 0 0 0 !important; 83 | padding: $box-padding-vertical 0 0 0 !important; 84 | } 85 | } 86 | } 87 | 88 | .image { 89 | &.featured { 90 | border-radius: 0; 91 | margin-left: ($box-padding-horizontal * -1); 92 | width: calc(100% + #{$box-padding-horizontal * 2}); 93 | 94 | img { 95 | border-radius: 0 !important; 96 | } 97 | 98 | &:first-child { 99 | margin-bottom: $box-padding-vertical; 100 | margin-top: $box-padding-vertical * -1; 101 | } 102 | 103 | &:last-child { 104 | margin-bottom: $box-padding-vertical * -1; 105 | margin-top: $box-padding-vertical; 106 | } 107 | } 108 | } 109 | } 110 | 111 | /* Banner */ 112 | 113 | #banner { 114 | padding: 5em 1em 4em 1em; 115 | } 116 | 117 | /* Main */ 118 | 119 | #main { 120 | > .box { 121 | &:first-child { 122 | margin-top: 0; 123 | } 124 | } 125 | } 126 | 127 | /* CTA */ 128 | 129 | #cta { 130 | padding: 2.5em 1em 3em 1em; 131 | } -------------------------------------------------------------------------------- /themes/alpha/templates/layout.html: -------------------------------------------------------------------------------- 1 | <!DOCTYPE HTML> 2 | <!-- 3 | Alpha by HTML5 UP 4 | html5up.net | @n33co 5 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 6 | --> 7 | <html> 8 | <head> 9 | <title>MDWeb - {{ meta.title }} 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 | 36 | {% block body %}{% endblock %} 37 | 38 | 39 | 52 | 53 | -------------------------------------------------------------------------------- /demo-content/examples/index.md: -------------------------------------------------------------------------------- 1 | ```metainf 2 | Title: Markdown Examples 3 | Nav Name: Markdown Examples 4 | Description: An example of writing markdown for MDWeb content 5 | Order: 4 6 | Teaser: A helpful example of writing markdown for MDWeb content. 7 | Sitemap Priority: 0.5 8 | Sitemap Changefreq: monthly 9 | ``` 10 | 11 | Examples taken from https://daringfireball.net/projects/markdown/basics 12 | 13 | A First Level Header 14 | ==================== 15 | 16 | A Second Level Header 17 | --------------------- 18 | 19 | Now is the time for all good men to come to 20 | the aid of their country. This is just a 21 | regular paragraph. 22 | 23 | The quick brown fox jumped over the lazy 24 | dog's back. 25 | 26 | ### Header 3 27 | 28 | > This is a blockquote. 29 | > 30 | > This is the second paragraph in the blockquote. 31 | > 32 | > ## This is an H2 in a blockquote 33 | 34 | --------------------------------------- 35 | 36 | Some of these words *are emphasized*. 37 | Some of these words _are emphasized also_. 38 | 39 | Use two asterisks for **strong emphasis**. 40 | Or, if you prefer, __use two underscores instead__. 41 | 42 | --------------------------------------- 43 | 44 | * Candy. 45 | * Gum. 46 | * Booze. 47 | 48 | 49 | --------------------------------------- 50 | 51 | 1. Red 52 | 2. Green 53 | 3. Blue 54 | 55 | --------------------------------------- 56 | 57 | * A list item. 58 | 59 | With multiple paragraphs. 60 | 61 | * Another item in the list. 62 | 63 | --------------------------------------- 64 | 65 | This is an [example link](http://example.com/). 66 | 67 | This is an [example link](http://example.com/ "With a Title"). 68 | 69 | --------------------------------------- 70 | 71 | I get 10 times more traffic from [Google][1] than from 72 | [Yahoo][2] or [MSN][3]. 73 | 74 | [1]: http://google.com/ "Google" 75 | [2]: http://search.yahoo.com/ "Yahoo Search" 76 | [3]: http://search.msn.com/ "MSN Search" 77 | 78 | I start my morning with a cup of coffee and 79 | [The New York Times][NY Times]. 80 | 81 | [ny times]: http://www.nytimes.com/ 82 | 83 | --------------------------------------- 84 | 85 | ![alt text](/path/to/img.jpg "Title") 86 | 87 | ![alt text][id] 88 | 89 | [id]: /path/to/img.jpg "Title" 90 | 91 | --------------------------------------- 92 | 93 | I strongly recommend against using any `` tags. 94 | 95 | I wish SmartyPants used named entities like `—` 96 | instead of decimal-encoded entites like `—`. 97 | 98 | 99 | If you want your page to validate under XHTML 1.0 Strict, 100 | you've got to put paragraph tags in your blockquotes: 101 | 102 |
103 |

For example.

104 |
105 | 106 | 107 | --------------------------------------- 108 | 109 | -------------------------------------------------------------------------------- /themes/alpha/assets/js/jquery.scrollgress.min.js: -------------------------------------------------------------------------------- 1 | /* jquery.scrollgress vx.x | (c) n33 | n33.co @n33co | MIT */ 2 | (function(){var e="scrollwatchResume",t="length",n="removeData",r="data",i="scrollwatch-state",s="scrollwatch-suspended",o="scrollgress-suspended",u="setTimeout",a="trigger",f="scroll",l="scrollwatchSuspend",c=!0,h="scrollwatch",p=null,d="top",v="rangeMin",m="rangeMax",g="scrollgress",y=!1,b="anchor",w="unscrollwatch",E="unscrollgress",S="element",x="-id",T="scroll.",N="height",C="scrollTop",k="center",L="bottom",A=$(window),O=$(document),M=1e3;jQuery.fn[e]=function(){var l,c;if(this[t]==0)return $(this);if(this[t]>1){for(l=0;l1){for(e=0;e1){for(n=0;n=a[v],n=a[m]===y||e<=a[m];if(t&&n){f[r](i,1),a.on&&a.on(f),w&&(w(f,c),w=p);return}}if(s==1||s==-1){t=a[v]!==y&&ea[m];if(t||n){f[r](i,0),a.off&&a.off(f),w&&(w(f,y),w=p);return}}},w?0:a.delay)},{anchor:a[b]},h),f},jQuery.fn[w]=function(){var e,r;if(this[t]==0)return $(this);if(this[t]>1){for(e=0;e1){for(s=0;s0?s=Math.max(0,s-u.easing/100):s<0&&(s=Math.min(0,s+u.easing/100)),e(s,l)})[a](f),l},jQuery.fn[E]=function(e){var i,s,o,u;if(this[t]==0)return $(this);if(this[t]>1){for(i=0;i1){for(l=0;l1){for(e=0;e1){for(n=0;n=a[v],n=a[m]===y||e<=a[m];if(t&&n){f[r](i,1),a.on&&a.on(f),w&&(w(f,c),w=p);return}}if(s==1||s==-1){t=a[v]!==y&&ea[m];if(t||n){f[r](i,0),a.off&&a.off(f),w&&(w(f,y),w=p);return}}},w?0:a.delay)},{anchor:a[b]},h),f},jQuery.fn[w]=function(){var e,r;if(this[t]==0)return $(this);if(this[t]>1){for(e=0;e1){for(s=0;s0?s=Math.max(0,s-u.easing/100):s<0&&(s=Math.min(0,s+u.easing/100)),e(s,l)})[a](f),l},jQuery.fn[E]=function(e){var i,s,o,u;if(this[t]==0)return $(this);if(this[t]>1){for(i=0;i 2 | 7 | 8 | 9 | MDWeb - {{ meta.title }} 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 | 36 | {% block body %}{% endblock %} 37 | 38 | 39 | 53 | {{ ga_tracking | safe }} 54 | 55 | 56 | -------------------------------------------------------------------------------- /bin/dev_server: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import argparse 3 | import os 4 | import sys 5 | 6 | MDWEB_BASE_DIR = os.path.abspath(os.path.join(__file__, os.pardir, os.pardir)) 7 | 8 | # We're starting in a subdirectory of the project, we need to add the 9 | # project base directory to the python path 10 | sys.path.insert(1, MDWEB_BASE_DIR) 11 | 12 | if __name__ == '__main__': 13 | parser = argparse.ArgumentParser(description='Development Server Help') 14 | parser.add_argument("-d", "--debug", action="store_true", dest="debug_mode", 15 | help="run in debug mode (for use with PyCharm)", 16 | default=False) 17 | parser.add_argument("-p", "--port", dest="port", 18 | help="port of server (default:%(default)s)", type=int, 19 | default=5000) 20 | parser.add_argument("-n", "--name", dest="name", 21 | help="application name", type=str, 22 | default="MDWeb") 23 | parser.add_argument("-l", "--list-sites", dest="list", action="store_true", 24 | help="list available applications") 25 | parser.add_argument("--log-level", dest="log_level", type=str, 26 | help="logging level ('CRITICAL', 'ERROR, 'WARNING'," 27 | "'INFO', 'DEBUG', 'NOTSET')", default="ERROR") 28 | parser.add_argument('site', help='site class') 29 | 30 | cmd_args = parser.parse_args() 31 | 32 | # Print the available sites 33 | if cmd_args.list: 34 | import pkgutil 35 | sites_path = os.path.abspath(os.path.join(MDWEB_BASE_DIR, 'sites')) 36 | for _, name, __ in pkgutil.iter_modules([sites_path]): 37 | print(" - %s" % name) 38 | else: 39 | site_module = __import__("sites.%s" % cmd_args.site) 40 | site_module = getattr(site_module, cmd_args.site) 41 | site_class = getattr(site_module, cmd_args.site) 42 | 43 | # Options that can be passed to the Flask application. 44 | # These are currently set to defaults but are defined here for 45 | # potential future use with argument options. 46 | app_options = { 47 | 'static_url_path': None, 48 | 'static_folder': 'static', 49 | 'template_folder': 'templates', 50 | 'instance_path': None, 51 | 'instance_relative_config': False, 52 | } 53 | 54 | # Options specific to MDWeb sites (not Flask app options) 55 | site_options = { 56 | 'logging_level': cmd_args.log_level, 57 | } 58 | 59 | site = site_class( 60 | # Site name, this gets passed in as the Flask name 61 | cmd_args.name, 62 | # Flask options that will be passed through to the Flask() 63 | # constructor 64 | app_options=app_options, 65 | # MDWeb site options 66 | site_options=site_options 67 | ) 68 | 69 | site.start() 70 | 71 | site.run() 72 | -------------------------------------------------------------------------------- /mdweb/SiteMapView.py: -------------------------------------------------------------------------------- 1 | """MDWeb SiteMap View Object.""" 2 | import datetime 3 | import logging 4 | import numbers 5 | import os 6 | import pytz 7 | import time 8 | 9 | from flask import ( 10 | current_app as app, 11 | make_response, 12 | render_template_string, 13 | url_for, 14 | ) 15 | from flask.views import View 16 | 17 | #: Template string to use for the sitemap generation 18 | # (is there a better place to put this?, not in the theme) 19 | # pylint: disable=C0301 20 | SITEMAP_TEMPLATE = """ 21 | 24 | {% for page in pages -%} 25 | 26 | {{page.loc|safe}} 27 | {{page.lastmod|safe}} 28 | {%- if page.changefreq %} 29 | {{page.changefreq|safe}} 30 | {%- endif %} 31 | {%- if page.priority %} 32 | {{page.priority|safe}} 33 | {%- endif %} 34 | 35 | {%- endfor %} 36 | 37 | """ 38 | 39 | 40 | class SiteMapView(View): 41 | """Sitemap View Object.""" 42 | 43 | sitemap_cache = None 44 | 45 | def dispatch_request(self): 46 | """Flask dispatch method.""" 47 | if self.sitemap_cache is None: 48 | self.sitemap_cache = self.generate_sitemap() 49 | 50 | response = make_response(self.sitemap_cache) 51 | response.headers["Content-Type"] = "application/xml" 52 | return response 53 | 54 | @classmethod 55 | def generate_sitemap(cls): 56 | """Generate sitemap.xml. Makes a list of urls and date modified.""" 57 | logging.info("Generating sitemap...") 58 | start = time.time() 59 | 60 | pages = [] 61 | 62 | index_url = url_for('index', _external=True) 63 | 64 | for url, page in app.navigation.get_page_dict().items(): 65 | if page.meta_inf.published: 66 | mtime = os.path.getmtime(page.page_path) 67 | if isinstance(mtime, numbers.Real): 68 | mtime = datetime.datetime.fromtimestamp(mtime) 69 | mtime.replace(tzinfo=pytz.UTC) 70 | # lastmod = mtime.strftime('%Y-%m-%dT%H:%M:%S%z') 71 | lastmod = mtime.strftime('%Y-%m-%d') 72 | pages.append({ 73 | 'loc': "%s%s" % (index_url, url), 74 | 'lastmod': lastmod, 75 | 'changefreq': page.meta_inf.sitemap_changefreq, 76 | 'priority': page.meta_inf.sitemap_priority, 77 | }) 78 | 79 | sitemap_xml = render_template_string(SITEMAP_TEMPLATE, pages=pages) 80 | 81 | end = time.time() 82 | logging.info("completed sitemap generation in %s seconds", 83 | (end - start)) 84 | 85 | return sitemap_xml 86 | -------------------------------------------------------------------------------- /themes/alpha/assets/css/style-narrower.css: -------------------------------------------------------------------------------- 1 | /* 2 | Alpha by HTML5 UP 3 | html5up.net | @n33co 4 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | */ 6 | 7 | /* Basic */ 8 | 9 | body, input, select, textarea { 10 | font-size: 11pt; 11 | } 12 | 13 | h2 br, h3 br, h4 br, h5 br, h6 br { 14 | display: none; 15 | } 16 | 17 | /* Section/Article */ 18 | 19 | header br { 20 | display: none; 21 | } 22 | 23 | header.major { 24 | padding: 0 4em; 25 | } 26 | 27 | /* Box */ 28 | 29 | .box { 30 | padding: 3em 2em; 31 | } 32 | 33 | .box.features > section { 34 | padding: 3em 2em; 35 | } 36 | 37 | .box .image.featured { 38 | margin-left: -2em; 39 | width: calc(100% + 4em); 40 | } 41 | 42 | .box .image.featured:first-child { 43 | margin-bottom: 3em; 44 | margin-top: -3em; 45 | } 46 | 47 | .box .image.featured:last-child { 48 | margin-bottom: -3em; 49 | margin-top: 3em; 50 | } 51 | 52 | /* Header */ 53 | 54 | #skel-layers-wrapper { 55 | padding-top: 0; 56 | } 57 | 58 | #header { 59 | display: none; 60 | } 61 | 62 | /* Banner */ 63 | 64 | /* Layers */ 65 | 66 | #navButton .toggle { 67 | text-decoration: none; 68 | height: 100%; 69 | left: 0; 70 | position: absolute; 71 | top: 0; 72 | width: 100%; 73 | } 74 | 75 | #navButton .toggle:before { 76 | -moz-osx-font-smoothing: grayscale; 77 | -webkit-font-smoothing: antialiased; 78 | font-family: FontAwesome; 79 | font-style: normal; 80 | font-weight: normal; 81 | text-transform: none !important; 82 | } 83 | 84 | #navButton .toggle:before { 85 | background: rgba(192, 192, 192, 0.75); 86 | border-radius: 6px; 87 | color: #fff; 88 | content: '\f0c9'; 89 | display: block; 90 | font-size: 16px; 91 | height: 2.25em; 92 | left: 0.5em; 93 | line-height: 2.25em; 94 | position: absolute; 95 | text-align: center; 96 | top: 0.5em; 97 | width: 3.5em; 98 | } 99 | 100 | #navPanel { 101 | background: #2b2b2b; 102 | color: #bbb; 103 | } 104 | 105 | #navPanel .link { 106 | border-bottom: 0; 107 | border-top: solid 1px rgba(255, 255, 255, 0.05); 108 | color: #bbb; 109 | display: block; 110 | height: 44px; 111 | line-height: 44px; 112 | padding: 0 1em 0 1em; 113 | text-decoration: none; 114 | } 115 | 116 | #navPanel .link:first-child { 117 | border-top: 0; 118 | } 119 | 120 | #navPanel .link.depth-0 { 121 | color: #fff; 122 | } 123 | 124 | #navPanel .link .indent-1 { 125 | display: inline-block; 126 | width: 1em; 127 | } 128 | 129 | #navPanel .link .indent-2 { 130 | display: inline-block; 131 | width: 2em; 132 | } 133 | 134 | #navPanel .link .indent-3 { 135 | display: inline-block; 136 | width: 3em; 137 | } 138 | 139 | #navPanel .link .indent-4 { 140 | display: inline-block; 141 | width: 4em; 142 | } 143 | 144 | #navPanel .link .indent-5 { 145 | display: inline-block; 146 | width: 5em; 147 | } -------------------------------------------------------------------------------- /themes/mdweb/assets/css/style-narrower.css: -------------------------------------------------------------------------------- 1 | /* 2 | Alpha by HTML5 UP 3 | html5up.net | @n33co 4 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | */ 6 | 7 | /* Basic */ 8 | 9 | body, input, select, textarea { 10 | font-size: 11pt; 11 | } 12 | 13 | h2 br, h3 br, h4 br, h5 br, h6 br { 14 | display: none; 15 | } 16 | 17 | /* Section/Article */ 18 | 19 | header br { 20 | display: none; 21 | } 22 | 23 | header.major { 24 | padding: 0 4em; 25 | } 26 | 27 | /* Box */ 28 | 29 | .box { 30 | padding: 3em 2em; 31 | } 32 | 33 | .box.features > section { 34 | padding: 3em 2em; 35 | } 36 | 37 | .box .image.featured { 38 | margin-left: -2em; 39 | width: calc(100% + 4em); 40 | } 41 | 42 | .box .image.featured:first-child { 43 | margin-bottom: 3em; 44 | margin-top: -3em; 45 | } 46 | 47 | .box .image.featured:last-child { 48 | margin-bottom: -3em; 49 | margin-top: 3em; 50 | } 51 | 52 | /* Header */ 53 | 54 | #skel-layers-wrapper { 55 | padding-top: 0; 56 | } 57 | 58 | #header { 59 | display: none; 60 | } 61 | 62 | /* Banner */ 63 | 64 | /* Layers */ 65 | 66 | #navButton .toggle { 67 | text-decoration: none; 68 | height: 100%; 69 | left: 0; 70 | position: absolute; 71 | top: 0; 72 | width: 100%; 73 | } 74 | 75 | #navButton .toggle:before { 76 | -moz-osx-font-smoothing: grayscale; 77 | -webkit-font-smoothing: antialiased; 78 | font-family: FontAwesome; 79 | font-style: normal; 80 | font-weight: normal; 81 | text-transform: none !important; 82 | } 83 | 84 | #navButton .toggle:before { 85 | background: rgba(192, 192, 192, 0.75); 86 | border-radius: 6px; 87 | color: #fff; 88 | content: '\f0c9'; 89 | display: block; 90 | font-size: 16px; 91 | height: 2.25em; 92 | left: 0.5em; 93 | line-height: 2.25em; 94 | position: absolute; 95 | text-align: center; 96 | top: 0.5em; 97 | width: 3.5em; 98 | } 99 | 100 | #navPanel { 101 | background: #2b2b2b; 102 | color: #bbb; 103 | } 104 | 105 | #navPanel .link { 106 | border-bottom: 0; 107 | border-top: solid 1px rgba(255, 255, 255, 0.05); 108 | color: #bbb; 109 | display: block; 110 | height: 44px; 111 | line-height: 44px; 112 | padding: 0 1em 0 1em; 113 | text-decoration: none; 114 | } 115 | 116 | #navPanel .link:first-child { 117 | border-top: 0; 118 | } 119 | 120 | #navPanel .link.depth-0 { 121 | color: #fff; 122 | } 123 | 124 | #navPanel .link .indent-1 { 125 | display: inline-block; 126 | width: 1em; 127 | } 128 | 129 | #navPanel .link .indent-2 { 130 | display: inline-block; 131 | width: 2em; 132 | } 133 | 134 | #navPanel .link .indent-3 { 135 | display: inline-block; 136 | width: 3em; 137 | } 138 | 139 | #navPanel .link .indent-4 { 140 | display: inline-block; 141 | width: 4em; 142 | } 143 | 144 | #navPanel .link .indent-5 { 145 | display: inline-block; 146 | width: 5em; 147 | } -------------------------------------------------------------------------------- /themes/alpha/assets/sass/style-mobile.scss: -------------------------------------------------------------------------------- 1 | @import 'vars'; 2 | @import 'mixins'; 3 | 4 | /* 5 | Alpha by HTML5 UP 6 | html5up.net | @n33co 7 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 8 | */ 9 | 10 | /* Basic */ 11 | 12 | body, input, select, textarea { 13 | font-size: 11pt; 14 | } 15 | 16 | h2 { 17 | font-size: 1.75em; 18 | line-height: 1.35em; 19 | letter-spacing: -0.025em; 20 | } 21 | 22 | h3 { 23 | font-size: 1.5em; 24 | } 25 | 26 | h4 { 27 | font-size: 1em; 28 | } 29 | 30 | /* Section/Article */ 31 | 32 | header { 33 | &.major { 34 | padding: 1em; 35 | 36 | h2, p { 37 | padding-left: 0.5em; 38 | padding-right: 0.5em; 39 | } 40 | } 41 | } 42 | 43 | /* Box */ 44 | 45 | $box-padding-vertical: 2em; 46 | $box-padding-horizontal: 2em; 47 | 48 | .box { 49 | margin: ($size-element-margin * 0.5); 50 | overflow-x: hidden; 51 | padding: $box-padding-vertical $box-padding-horizontal !important; 52 | 53 | &.features { 54 | .features-row { 55 | border-top: 0; 56 | padding: 0; 57 | 58 | section { 59 | border: 0; 60 | border-top: solid 1px $color-border !important; 61 | float: none; 62 | margin: $box-padding-vertical 0 0 0 !important; 63 | padding: $box-padding-vertical 0 0 0 !important; 64 | width: 100%; 65 | } 66 | 67 | &:first-child { 68 | section { 69 | &:first-child { 70 | border-top: 0 !important; 71 | margin-top: 0 !important; 72 | padding-top: 0 !important; 73 | } 74 | } 75 | } 76 | } 77 | } 78 | 79 | .image { 80 | &.featured { 81 | margin-left: ($box-padding-horizontal * -1); 82 | width: calc(100% + #{$box-padding-horizontal * 2}); 83 | 84 | &:first-child { 85 | margin-bottom: $box-padding-vertical; 86 | margin-top: $box-padding-vertical * -1; 87 | } 88 | 89 | &:last-child { 90 | margin-bottom: $box-padding-vertical * -1; 91 | margin-top: $box-padding-vertical; 92 | } 93 | } 94 | } 95 | } 96 | 97 | /* Banner */ 98 | 99 | #banner { 100 | padding: 4em 0; 101 | 102 | h2 { 103 | font-size: 2.25em; 104 | } 105 | 106 | p { 107 | font-size: 1.25em; 108 | } 109 | } 110 | 111 | /* Main */ 112 | 113 | #main { 114 | padding: 4em 0 0 0; 115 | 116 | > header { 117 | margin: 0 2em 1.5em 2em; 118 | 119 | h2 { 120 | font-size: 2em; 121 | } 122 | 123 | p { 124 | font-size: 1em; 125 | padding-bottom: 1em; 126 | } 127 | } 128 | } 129 | 130 | body.landing { 131 | #main { 132 | padding: 0; 133 | margin-top: 0; 134 | } 135 | } 136 | 137 | /* Footer */ 138 | 139 | #footer { 140 | padding: 4em 0; 141 | 142 | .copyright { 143 | li { 144 | border-left: 0; 145 | display: block; 146 | line-height: 2em; 147 | margin-left: 0; 148 | padding-left: 0; 149 | } 150 | } 151 | } -------------------------------------------------------------------------------- /themes/mdweb/assets/sass/style-mobile.scss: -------------------------------------------------------------------------------- 1 | @import 'vars'; 2 | @import 'mixins'; 3 | 4 | /* 5 | Alpha by HTML5 UP 6 | html5up.net | @n33co 7 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 8 | */ 9 | 10 | /* Basic */ 11 | 12 | body, input, select, textarea { 13 | font-size: 11pt; 14 | } 15 | 16 | h2 { 17 | font-size: 1.75em; 18 | line-height: 1.35em; 19 | letter-spacing: -0.025em; 20 | } 21 | 22 | h3 { 23 | font-size: 1.5em; 24 | } 25 | 26 | h4 { 27 | font-size: 1em; 28 | } 29 | 30 | /* Section/Article */ 31 | 32 | header { 33 | &.major { 34 | padding: 1em; 35 | 36 | h2, p { 37 | padding-left: 0.5em; 38 | padding-right: 0.5em; 39 | } 40 | } 41 | } 42 | 43 | /* Box */ 44 | 45 | $box-padding-vertical: 2em; 46 | $box-padding-horizontal: 2em; 47 | 48 | .box { 49 | margin: ($size-element-margin * 0.5); 50 | overflow-x: hidden; 51 | padding: $box-padding-vertical $box-padding-horizontal !important; 52 | 53 | &.features { 54 | .features-row { 55 | border-top: 0; 56 | padding: 0; 57 | 58 | section { 59 | border: 0; 60 | border-top: solid 1px $color-border !important; 61 | float: none; 62 | margin: $box-padding-vertical 0 0 0 !important; 63 | padding: $box-padding-vertical 0 0 0 !important; 64 | width: 100%; 65 | } 66 | 67 | &:first-child { 68 | section { 69 | &:first-child { 70 | border-top: 0 !important; 71 | margin-top: 0 !important; 72 | padding-top: 0 !important; 73 | } 74 | } 75 | } 76 | } 77 | } 78 | 79 | .image { 80 | &.featured { 81 | margin-left: ($box-padding-horizontal * -1); 82 | width: calc(100% + #{$box-padding-horizontal * 2}); 83 | 84 | &:first-child { 85 | margin-bottom: $box-padding-vertical; 86 | margin-top: $box-padding-vertical * -1; 87 | } 88 | 89 | &:last-child { 90 | margin-bottom: $box-padding-vertical * -1; 91 | margin-top: $box-padding-vertical; 92 | } 93 | } 94 | } 95 | } 96 | 97 | /* Banner */ 98 | 99 | #banner { 100 | padding: 4em 0; 101 | 102 | h2 { 103 | font-size: 2.25em; 104 | } 105 | 106 | p { 107 | font-size: 1.25em; 108 | } 109 | } 110 | 111 | /* Main */ 112 | 113 | #main { 114 | padding: 4em 0 0 0; 115 | 116 | > header { 117 | margin: 0 2em 1.5em 2em; 118 | 119 | h2 { 120 | font-size: 2em; 121 | } 122 | 123 | p { 124 | font-size: 1em; 125 | padding-bottom: 1em; 126 | } 127 | } 128 | } 129 | 130 | body.landing { 131 | #main { 132 | padding: 0; 133 | margin-top: 0; 134 | } 135 | } 136 | 137 | /* Footer */ 138 | 139 | #footer { 140 | padding: 4em 0; 141 | 142 | .copyright { 143 | li { 144 | border-left: 0; 145 | display: block; 146 | line-height: 2em; 147 | margin-left: 0; 148 | padding-left: 0; 149 | } 150 | } 151 | } -------------------------------------------------------------------------------- /themes/alpha/assets/sass/style-narrower.scss: -------------------------------------------------------------------------------- 1 | @import 'vars'; 2 | @import 'mixins'; 3 | 4 | /* 5 | Alpha by HTML5 UP 6 | html5up.net | @n33co 7 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 8 | */ 9 | 10 | /* Basic */ 11 | 12 | body, input, select, textarea { 13 | font-size: 11pt; 14 | } 15 | 16 | h2, h3, h4, h5, h6 { 17 | br { 18 | display: none; 19 | } 20 | } 21 | 22 | /* Section/Article */ 23 | 24 | header { 25 | br { 26 | display: none; 27 | } 28 | 29 | &.major { 30 | padding: 0 4em; 31 | } 32 | } 33 | 34 | /* Box */ 35 | 36 | $box-padding-vertical: 3em; 37 | $box-padding-horizontal: 2em; 38 | 39 | .box { 40 | padding: $box-padding-vertical $box-padding-horizontal; 41 | 42 | &.features { 43 | > section { 44 | padding: $box-padding-vertical $box-padding-horizontal; 45 | } 46 | } 47 | 48 | .image { 49 | &.featured { 50 | margin-left: ($box-padding-horizontal * -1); 51 | width: calc(100% + #{$box-padding-horizontal * 2}); 52 | 53 | &:first-child { 54 | margin-bottom: $box-padding-vertical; 55 | margin-top: $box-padding-vertical * -1; 56 | } 57 | 58 | &:last-child { 59 | margin-bottom: $box-padding-vertical * -1; 60 | margin-top: $box-padding-vertical; 61 | } 62 | } 63 | } 64 | } 65 | 66 | /* Header */ 67 | 68 | //body { 69 | #skel-layers-wrapper { 70 | padding-top: 0; 71 | } 72 | 73 | #header { 74 | display: none; 75 | } 76 | 77 | /* Banner */ 78 | 79 | #banner { 80 | //padding: 6em 2em; 81 | } 82 | 83 | /* Layers */ 84 | 85 | #navButton { 86 | .toggle { 87 | @include icon; 88 | height: 100%; 89 | left: 0; 90 | position: absolute; 91 | top: 0; 92 | width: 100%; 93 | 94 | &:before { 95 | background: rgba(192,192,192,0.75); 96 | border-radius: $size-border-radius; 97 | color: #fff; 98 | content: '\f0c9'; 99 | display: block; 100 | font-size: 16px; 101 | height: 2.25em; 102 | left: 0.5em; 103 | line-height: 2.25em; 104 | position: absolute; 105 | text-align: center; 106 | top: 0.5em; 107 | width: 3.5em; 108 | } 109 | } 110 | } 111 | 112 | #navPanel { 113 | background: darken($color-header-bg, 10); 114 | color: $color-header-fg; 115 | 116 | .link { 117 | border-bottom: 0; 118 | border-top: solid 1px rgba(255,255,255,0.05); 119 | color: $color-header-fg; 120 | display: block; 121 | height: 44px; 122 | line-height: 44px; 123 | padding: 0 1em 0 1em; 124 | text-decoration: none; 125 | 126 | &:first-child { 127 | border-top: 0; 128 | } 129 | 130 | &.depth-0 { 131 | color: $color-header-fg-bold; 132 | } 133 | 134 | .indent-1 { display: inline-block; width: 1em; } 135 | .indent-2 { display: inline-block; width: 2em; } 136 | .indent-3 { display: inline-block; width: 3em; } 137 | .indent-4 { display: inline-block; width: 4em; } 138 | .indent-5 { display: inline-block; width: 5em; } 139 | } 140 | } -------------------------------------------------------------------------------- /themes/alpha/templates/page_home.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 | 4 | 8 | 9 | 10 |
11 | 12 |
13 |
14 | {{ page | safe}} 15 |
16 | 17 |
18 | 19 |
20 |
21 |
22 | 23 |

Simplicity of Markdown

24 |

Focus on the content not managing your site.

25 |
26 |
27 | 28 |

No Database

29 |

Your entire site is saved in files, no database to maintain.

30 |
31 |
32 |
33 |
34 | 35 |

Fast Setup

36 |

Get your site setup in less than 5 minutes.

37 |
38 |
39 | 40 |

MDWeb on Github

41 |

42 | Fork us on Github. Setup takes less than 5 minutes. 43 |

44 |
45 |
46 |
47 | 48 |
49 |
50 | 51 |
52 | 53 |

Sed lorem adipiscing

54 |

Integer volutpat ante et accumsan commophasellus sed aliquam feugiat lorem aliquet ut enim rutrum phasellus iaculis accumsan dolore magna aliquam veroeros.

55 | 58 |
59 | 60 |
61 |
62 | 63 |
64 | 65 |

Accumsan integer

66 |

Integer volutpat ante et accumsan commophasellus sed aliquam feugiat lorem aliquet ut enim rutrum phasellus iaculis accumsan dolore magna aliquam veroeros.

67 | 70 |
71 | 72 |
73 |
74 |
75 | 76 | 77 |
78 |
79 | 80 | {% endblock %} -------------------------------------------------------------------------------- /themes/mdweb/assets/sass/style-narrower.scss: -------------------------------------------------------------------------------- 1 | @import 'vars'; 2 | @import 'mixins'; 3 | 4 | /* 5 | Alpha by HTML5 UP 6 | html5up.net | @n33co 7 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 8 | */ 9 | 10 | /* Basic */ 11 | 12 | body, input, select, textarea { 13 | font-size: 11pt; 14 | } 15 | 16 | h2, h3, h4, h5, h6 { 17 | br { 18 | display: none; 19 | } 20 | } 21 | 22 | /* Section/Article */ 23 | 24 | header { 25 | br { 26 | display: none; 27 | } 28 | 29 | &.major { 30 | padding: 0 4em; 31 | } 32 | } 33 | 34 | /* Box */ 35 | 36 | $box-padding-vertical: 3em; 37 | $box-padding-horizontal: 2em; 38 | 39 | .box { 40 | padding: $box-padding-vertical $box-padding-horizontal; 41 | 42 | &.features { 43 | > section { 44 | padding: $box-padding-vertical $box-padding-horizontal; 45 | } 46 | } 47 | 48 | .image { 49 | &.featured { 50 | margin-left: ($box-padding-horizontal * -1); 51 | width: calc(100% + #{$box-padding-horizontal * 2}); 52 | 53 | &:first-child { 54 | margin-bottom: $box-padding-vertical; 55 | margin-top: $box-padding-vertical * -1; 56 | } 57 | 58 | &:last-child { 59 | margin-bottom: $box-padding-vertical * -1; 60 | margin-top: $box-padding-vertical; 61 | } 62 | } 63 | } 64 | } 65 | 66 | /* Header */ 67 | 68 | //body { 69 | #skel-layers-wrapper { 70 | padding-top: 0; 71 | } 72 | 73 | #header { 74 | display: none; 75 | } 76 | 77 | /* Banner */ 78 | 79 | #banner { 80 | //padding: 6em 2em; 81 | } 82 | 83 | /* Layers */ 84 | 85 | #navButton { 86 | .toggle { 87 | @include icon; 88 | height: 100%; 89 | left: 0; 90 | position: absolute; 91 | top: 0; 92 | width: 100%; 93 | 94 | &:before { 95 | background: rgba(192,192,192,0.75); 96 | border-radius: $size-border-radius; 97 | color: #fff; 98 | content: '\f0c9'; 99 | display: block; 100 | font-size: 16px; 101 | height: 2.25em; 102 | left: 0.5em; 103 | line-height: 2.25em; 104 | position: absolute; 105 | text-align: center; 106 | top: 0.5em; 107 | width: 3.5em; 108 | } 109 | } 110 | } 111 | 112 | #navPanel { 113 | background: darken($color-header-bg, 10); 114 | color: $color-header-fg; 115 | 116 | .link { 117 | border-bottom: 0; 118 | border-top: solid 1px rgba(255,255,255,0.05); 119 | color: $color-header-fg; 120 | display: block; 121 | height: 44px; 122 | line-height: 44px; 123 | padding: 0 1em 0 1em; 124 | text-decoration: none; 125 | 126 | &:first-child { 127 | border-top: 0; 128 | } 129 | 130 | &.depth-0 { 131 | color: $color-header-fg-bold; 132 | } 133 | 134 | .indent-1 { display: inline-block; width: 1em; } 135 | .indent-2 { display: inline-block; width: 2em; } 136 | .indent-3 { display: inline-block; width: 3em; } 137 | .indent-4 { display: inline-block; width: 4em; } 138 | .indent-5 { display: inline-block; width: 5em; } 139 | } 140 | } -------------------------------------------------------------------------------- /themes/mdweb/templates/page_home.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 | 4 | 8 | 9 | 10 |
11 | 12 |
13 |
14 | {{ page | safe}} 15 |
16 | 17 |
18 | 19 |
20 |
21 |
22 | 23 |

Simplicity of Markdown

24 |

Focus on the content not managing your site.

25 |
26 |
27 | 28 |

No Database

29 |

Your entire site is saved in files, no database to maintain.

30 |
31 |
32 |
33 |
34 | 35 |

Fast Setup

36 |

Get your site setup in less than 5 minutes.

37 |
38 |
39 | 40 |

MDWeb on Github

41 |

42 | Fork us on Github. Setup takes less than 5 minutes. 43 |

44 |
45 |
46 |
47 | 48 |
49 |
50 | 51 |
52 | 53 |

Sed lorem adipiscing

54 |

Integer volutpat ante et accumsan commophasellus sed aliquam feugiat lorem aliquet ut enim rutrum phasellus iaculis accumsan dolore magna aliquam veroeros.

55 | 58 |
59 | 60 |
61 |
62 | 63 |
64 | 65 |

Accumsan integer

66 |

Integer volutpat ante et accumsan commophasellus sed aliquam feugiat lorem aliquet ut enim rutrum phasellus iaculis accumsan dolore magna aliquam veroeros.

67 | 70 |
71 | 72 |
73 |
74 |
75 | 76 | 77 |
78 |
79 | 80 | {% endblock %} -------------------------------------------------------------------------------- /tests/test_partials.py: -------------------------------------------------------------------------------- 1 | from flask import render_template 2 | from flask_testing import TestCase 3 | import os 4 | from pyfakefs import fake_filesystem_unittest, fake_filesystem 5 | from tests.sites import MDTestSite 6 | from mdweb.MDSite import BASE_PATH 7 | from mdweb.Page import Page, load_page 8 | 9 | 10 | class TestPartials(TestCase): 11 | """Can't use pyfakefs for this or partials won't load""" 12 | 13 | def create_app(self): 14 | app = MDTestSite( 15 | "MDWeb", 16 | app_options={} 17 | ) 18 | app.start() 19 | 20 | return app 21 | 22 | def test_ga_tracking_context(self): 23 | """GA Tracking should be added to context.""" 24 | with self.app.test_client() as client: 25 | client.get('/') 26 | self.assertContext('ga_tracking', ''' 27 | ''') 34 | 35 | def test_og_full_data(self): 36 | with self.app.test_client() as client: 37 | response = client.get('/') 38 | self.assertEqual(response.data[:607], og_full_data_response) 39 | 40 | def test_og_partial_data(self): 41 | with self.app.test_client() as client: 42 | response = client.get('/download') 43 | self.assertEqual(response.data[:414], og_partial_data_response) 44 | 45 | def test_og_no_data(self): 46 | with self.app.test_client() as client: 47 | response = client.get('/about/empty') 48 | self.assertEqual(response.data[:303], og_no_data_response) 49 | 50 | 51 | og_full_data_response = b''' 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | MDWeb 64 | 65 | 66 | ''' 67 | 68 | og_partial_data_response = b''' 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | MDWeb 79 | 80 | 81 | ''' 82 | 83 | og_no_data_response = b''' 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | MDWeb 92 | 93 | 94 | ''' 95 | -------------------------------------------------------------------------------- /themes/alpha/assets/css/ie/v8.css: -------------------------------------------------------------------------------- 1 | /* 2 | Alpha by HTML5 UP 3 | html5up.net | @n33co 4 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | */ 6 | 7 | /* Basic */ 8 | 9 | pre, code { 10 | position: relative; 11 | -ms-behavior: url("css/ie/PIE.htc"); 12 | } 13 | 14 | /* Form */ 15 | 16 | input[type="text"], 17 | input[type="password"], 18 | input[type="email"], 19 | select, 20 | textarea { 21 | position: relative; 22 | -ms-behavior: url("css/ie/PIE.htc"); 23 | line-height: 3em; 24 | } 25 | 26 | input[type="checkbox"], 27 | input[type="radio"] { 28 | opacity: 1; 29 | z-index: auto; 30 | } 31 | 32 | input[type="checkbox"] + label:before, 33 | input[type="radio"] + label:before { 34 | display: none; 35 | } 36 | 37 | /* Button */ 38 | 39 | input[type="submit"], 40 | input[type="reset"], 41 | input[type="button"], 42 | .button { 43 | position: relative; 44 | -ms-behavior: url("css/ie/PIE.htc"); 45 | } 46 | 47 | input[type="submit"].alt, 48 | input[type="reset"].alt, 49 | input[type="button"].alt, 50 | .button.alt { 51 | border: solid 2px #e5e5e5; 52 | } 53 | 54 | /* Box */ 55 | 56 | .box { 57 | position: relative; 58 | -ms-behavior: url("css/ie/PIE.htc"); 59 | } 60 | 61 | .box .image.featured { 62 | margin: 2em 0; 63 | width: 100%; 64 | } 65 | 66 | /* Icon */ 67 | 68 | .icon.major { 69 | position: relative; 70 | -ms-behavior: url("css/ie/PIE.htc"); 71 | } 72 | 73 | /* Image */ 74 | 75 | .image { 76 | position: relative; 77 | -ms-behavior: url("css/ie/PIE.htc"); 78 | } 79 | 80 | .image img { 81 | position: relative; 82 | -ms-behavior: url("css/ie/PIE.htc"); 83 | } 84 | 85 | /* Header */ 86 | 87 | #header nav > ul > li a { 88 | color: #fff; 89 | display: inline-block; 90 | text-decoration: none; 91 | border: 0; 92 | } 93 | 94 | #header nav > ul > li a.icon:before { 95 | color: #fff; 96 | margin-right: 0.5em; 97 | } 98 | 99 | #header.alt { 100 | color: #fff; 101 | } 102 | 103 | #header.alt nav > ul > li a:not(.button).icon:before { 104 | color: rgba(255, 255, 255, 0.75); 105 | } 106 | 107 | #header.alt nav > ul > li.active a:not(.button) { 108 | background-color: rgba(255, 255, 255, 0.2); 109 | } 110 | 111 | .dropotron { 112 | border: solid 1px #e5e5e5; 113 | } 114 | 115 | .dropotron.level-0 { 116 | margin-top: 0; 117 | } 118 | 119 | .dropotron.level-0:before { 120 | display: none; 121 | } 122 | 123 | /* Banner */ 124 | 125 | #banner { 126 | background-attachment: scroll; 127 | background-image: url("../../images/banner.jpg"); 128 | background-position: auto; 129 | background-repeat: no-repeat; 130 | background-size: cover; 131 | -ms-behavior: url("css/ie/backgroundsize.min.htc"); 132 | } 133 | 134 | #banner input[type="submit"], 135 | #banner input[type="reset"], 136 | #banner input[type="button"], 137 | #banner .button { 138 | border: solid 2px #fff; 139 | } 140 | 141 | /* Main */ 142 | 143 | #main { 144 | position: relative; 145 | z-index: 1; 146 | } 147 | 148 | /* CTA */ 149 | 150 | #cta input[type="text"], 151 | #cta input[type="password"], 152 | #cta input[type="email"], 153 | #cta select, 154 | #cta textarea { 155 | background: #e89980; 156 | border: solid 2px #fff; 157 | } 158 | 159 | #cta .formerize-placeholder { 160 | color: #fff !important; 161 | } -------------------------------------------------------------------------------- /themes/mdweb/assets/css/ie/v8.css: -------------------------------------------------------------------------------- 1 | /* 2 | Alpha by HTML5 UP 3 | html5up.net | @n33co 4 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | */ 6 | 7 | /* Basic */ 8 | 9 | pre, code { 10 | position: relative; 11 | -ms-behavior: url("css/ie/PIE.htc"); 12 | } 13 | 14 | /* Form */ 15 | 16 | input[type="text"], 17 | input[type="password"], 18 | input[type="email"], 19 | select, 20 | textarea { 21 | position: relative; 22 | -ms-behavior: url("css/ie/PIE.htc"); 23 | line-height: 3em; 24 | } 25 | 26 | input[type="checkbox"], 27 | input[type="radio"] { 28 | opacity: 1; 29 | z-index: auto; 30 | } 31 | 32 | input[type="checkbox"] + label:before, 33 | input[type="radio"] + label:before { 34 | display: none; 35 | } 36 | 37 | /* Button */ 38 | 39 | input[type="submit"], 40 | input[type="reset"], 41 | input[type="button"], 42 | .button { 43 | position: relative; 44 | -ms-behavior: url("css/ie/PIE.htc"); 45 | } 46 | 47 | input[type="submit"].alt, 48 | input[type="reset"].alt, 49 | input[type="button"].alt, 50 | .button.alt { 51 | border: solid 2px #e5e5e5; 52 | } 53 | 54 | /* Box */ 55 | 56 | .box { 57 | position: relative; 58 | -ms-behavior: url("css/ie/PIE.htc"); 59 | } 60 | 61 | .box .image.featured { 62 | margin: 2em 0; 63 | width: 100%; 64 | } 65 | 66 | /* Icon */ 67 | 68 | .icon.major { 69 | position: relative; 70 | -ms-behavior: url("css/ie/PIE.htc"); 71 | } 72 | 73 | /* Image */ 74 | 75 | .image { 76 | position: relative; 77 | -ms-behavior: url("css/ie/PIE.htc"); 78 | } 79 | 80 | .image img { 81 | position: relative; 82 | -ms-behavior: url("css/ie/PIE.htc"); 83 | } 84 | 85 | /* Header */ 86 | 87 | #header nav > ul > li a { 88 | color: #fff; 89 | display: inline-block; 90 | text-decoration: none; 91 | border: 0; 92 | } 93 | 94 | #header nav > ul > li a.icon:before { 95 | color: #fff; 96 | margin-right: 0.5em; 97 | } 98 | 99 | #header.alt { 100 | color: #fff; 101 | } 102 | 103 | #header.alt nav > ul > li a:not(.button).icon:before { 104 | color: rgba(255, 255, 255, 0.75); 105 | } 106 | 107 | #header.alt nav > ul > li.active a:not(.button) { 108 | background-color: rgba(255, 255, 255, 0.2); 109 | } 110 | 111 | .dropotron { 112 | border: solid 1px #e5e5e5; 113 | } 114 | 115 | .dropotron.level-0 { 116 | margin-top: 0; 117 | } 118 | 119 | .dropotron.level-0:before { 120 | display: none; 121 | } 122 | 123 | /* Banner */ 124 | 125 | #banner { 126 | background-attachment: scroll; 127 | background-image: url("../../images/banner.jpg"); 128 | background-position: auto; 129 | background-repeat: no-repeat; 130 | background-size: cover; 131 | -ms-behavior: url("css/ie/backgroundsize.min.htc"); 132 | } 133 | 134 | #banner input[type="submit"], 135 | #banner input[type="reset"], 136 | #banner input[type="button"], 137 | #banner .button { 138 | border: solid 2px #fff; 139 | } 140 | 141 | /* Main */ 142 | 143 | #main { 144 | position: relative; 145 | z-index: 1; 146 | } 147 | 148 | /* CTA */ 149 | 150 | #cta input[type="text"], 151 | #cta input[type="password"], 152 | #cta input[type="email"], 153 | #cta select, 154 | #cta textarea { 155 | background: #e89980; 156 | border: solid 2px #fff; 157 | } 158 | 159 | #cta .formerize-placeholder { 160 | color: #fff !important; 161 | } -------------------------------------------------------------------------------- /mdweb/Page.py: -------------------------------------------------------------------------------- 1 | """MDWeb Page Objects.""" 2 | import codecs 3 | import os 4 | import re 5 | 6 | import markdown 7 | 8 | from mdweb.BaseObjects import NavigationBaseItem, MetaInfParser 9 | from mdweb.Exceptions import ( 10 | ContentException, 11 | PageParseException, 12 | ) 13 | 14 | #: A regex to extract the url path from the file path 15 | URL_PATH_REGEX = r'^%s(?P[^\0]*?)(index)?(\.md)' 16 | 17 | #: A regex for extracting meta information (and comments). 18 | META_INF_REGEX = r'(^```metainf(?P.*?)```)?(?P.*)' 19 | 20 | 21 | class PageMetaInf(MetaInfParser): # pylint: disable=R0903 22 | """MDWeb Page Meta Information.""" 23 | 24 | def __init__(self, meta_string): 25 | """Content page meta-information. 26 | 27 | If a page defines a non-standard meta value it is blindly included. 28 | 29 | :param meta_string: Raw meta-inf content as a string 30 | """ 31 | super(PageMetaInf, self).__init__(meta_string) 32 | self.nav_name = self.title if self.nav_name is None else self.nav_name 33 | 34 | 35 | def load_page(content_path, page_path): 36 | """Load the page file and return the path, URL and contents""" 37 | 38 | # Extract the part of the page_path that will be used as the URL path 39 | pattern = URL_PATH_REGEX % content_path 40 | matches = re.match(pattern, page_path) 41 | if matches: 42 | url_path = matches.group('path').rstrip('/').lstrip('/') 43 | else: 44 | raise PageParseException("Unable to parse page path [%s]" % 45 | content_path) 46 | 47 | if not os.path.exists(page_path): 48 | raise ContentException('Could not find file for content page "%s"' % 49 | page_path) 50 | 51 | # Read the page file 52 | with codecs.open(page_path, 'r', encoding='utf8') as f: 53 | file_string = f.read() 54 | 55 | return page_path, url_path, file_string 56 | 57 | 58 | class Page(NavigationBaseItem): 59 | """MDWeb Page View.""" 60 | 61 | def __init__(self, page_path, url_path, file_string): 62 | """Initialize Page object.""" 63 | 64 | self.page_path = page_path 65 | self.url_path = url_path 66 | 67 | # Separate the meta information and the page content 68 | meta_inf_regex = re.compile(META_INF_REGEX, flags=re.DOTALL) 69 | match = meta_inf_regex.search(file_string) 70 | meta_inf_string = match.group('metainf') if match.group('metainf') \ 71 | else '' 72 | content_string = match.group('content') 73 | 74 | self.meta_inf = PageMetaInf(meta_inf_string) 75 | 76 | # Strip the meta information and comments 77 | self.markdown_str = content_string 78 | 79 | # The page will be rendered on first view 80 | self.page_html = self.parse_markdown(self.markdown_str) 81 | 82 | self.abstract = self.page_html[0:100] 83 | 84 | @property 85 | def is_published(self): 86 | return self.meta_inf.published 87 | 88 | @staticmethod 89 | def parse_markdown(page_markdown): 90 | """Parse given markdown string into rendered html. 91 | 92 | :param page_markdown: Markdown to be parsed 93 | :return: Rendered page HTML 94 | """ 95 | page_html = markdown.markdown(page_markdown) 96 | 97 | return page_html 98 | 99 | def __repr__(self): 100 | return '{0}'.format(self.page_path) 101 | -------------------------------------------------------------------------------- /themes/basic/templates/navigation.html: -------------------------------------------------------------------------------- 1 | 11 | 93 | -------------------------------------------------------------------------------- /themes/bootstrap/templates/navigation.html: -------------------------------------------------------------------------------- 1 | 11 | 93 | -------------------------------------------------------------------------------- /docs/development.md: -------------------------------------------------------------------------------- 1 | # Development 2 | 3 | This section is intended primarily for those who wish to build themes 4 | or plugins. This section is still a work in progress but will stabalize 5 | after the plugin architecture is completed and as we approach the 1.0 6 | release. 7 | 8 | 9 | ## Building a Theme 10 | 11 | Themes are composed of the HTML templates and assets required for a 12 | site's display. Themes can be as simple or as complicated as you'd like. 13 | 14 | Theme HTML is rendered using the [Jinja](http://jinja.pocoo.org/docs/dev/) 15 | templating engine. All functionality available in Jinja is available to 16 | you in MDWeb theme files. 17 | 18 | To build a basic them you will need to 19 | 1. Create a directory whose name is the name of your theme 20 | 2. Create a subdirectory named 'templates' 21 | 2. Create a subdirectory named 'assets' 22 | 3. Create a template named layout.html in the templates directory 23 | 4. Create a template named page.html in the templates directory 24 | 5. Create a template named navigation.html in the templates directory 25 | 6. Add any CSS, Javascript or images into the assets directory. 26 | 27 | 28 | #### Example: 29 | 30 | ``` 31 | themes/ 32 | |- mytheme/ 33 | |- templates/ 34 | |- layout.html 35 | |- page.html 36 | |- navigation.html 37 | |- assets/ 38 | |- site.js 39 | |- site.css 40 | |- logo.png 41 | ``` 42 | 43 | 44 | #### Assets 45 | 46 | Assets can be placed in the `<>/assets` directory using any 47 | structure. The asset path is referenced in the templates by using the 48 | `url_for` helper. 49 | 50 | For example, this line in the layout.html file will load the minified 51 | bootstrap CSS from the css directory in assets. 52 | ``` 53 | 54 | ``` 55 | 56 | 57 | #### Using your theme 58 | To use your theme make sure the theme directory is located within 59 | `themes` inside the MDWeb project and then set the `THEME` configuration 60 | value to the the name of your theme directory. 61 | 62 | 63 | ## Building a Plugin 64 | 65 | The plugin architecture is not yet completed this section will be added 66 | once plugins are supported. 67 | 68 | 69 | ## Adding Meta Fields 70 | 71 | Currently new meta fields must be registered or they will throw a 72 | `PageMetaInfFieldException` exception. Unfortunately meta fields must 73 | be registered in the core of MDWeb. I hope to change this once the 74 | plugin architecture is completed. 75 | 76 | Meta field names are capital-cased and space separated in the markdown 77 | metainf block, for example `Nav Name`. These capital-cased, space 78 | separated meta field names are converted to camel-cased, underscore 79 | separated dictionary keys within the code. 80 | 81 | To register a meta field in MDWeb core: 82 | 1. Decide on a capital-cased and space separated name to be used in the 83 | metainf block, for example `Co Author`. This is the field name that 84 | will be used in markdown files metainf block. For example 85 | ~~~ 86 | ```metainf 87 | Title: Breaking News 88 | Author: Jean Luc Picard 89 | Co Author: Will Riker 90 | ``` 91 | ~~~ 92 | 2 Add an entry to the META_FIELDS dictionary in mdweb/metafields.py. 93 | This dictionary has the following structure 94 | ``` 95 | META_FIELDS = { 96 | 'camel_cased_field_name': ('python_type', default_value) 97 | } 98 | ``` 99 | 100 | the camel-cased version of the name to 101 | 102 | 103 | ## Testing 104 | 105 | MDWeb uses nose as the test runner. Running tests are as simple as 106 | ``` 107 | $ nosetests 108 | ``` 109 | -------------------------------------------------------------------------------- /themes/alpha/assets/css/ie/backgroundsize.min.htc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /themes/mdweb/assets/css/ie/backgroundsize.min.htc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /themes/alpha/assets/sass/ie/v8.scss: -------------------------------------------------------------------------------- 1 | @import 'vars'; 2 | @import 'mixins'; 3 | 4 | /* 5 | Alpha by HTML5 UP 6 | html5up.net | @n33co 7 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 8 | */ 9 | 10 | /* Basic */ 11 | 12 | pre, code { 13 | position: relative; 14 | -ms-behavior: url('css/ie/PIE.htc'); 15 | } 16 | 17 | /* Form */ 18 | 19 | input[type="text"], 20 | input[type="password"], 21 | input[type="email"], 22 | select, 23 | textarea { 24 | position: relative; 25 | -ms-behavior: url('css/ie/PIE.htc'); 26 | line-height: 3em; 27 | } 28 | 29 | input[type="checkbox"], 30 | input[type="radio"], { 31 | opacity: 1; 32 | z-index: auto; 33 | 34 | & + label { 35 | &:before { 36 | display: none; 37 | } 38 | } 39 | } 40 | 41 | /* Button */ 42 | 43 | input[type="submit"], 44 | input[type="reset"], 45 | input[type="button"], 46 | .button { 47 | position: relative; 48 | -ms-behavior: url('css/ie/PIE.htc'); 49 | 50 | &.alt { 51 | border: solid 2px $color-border; 52 | } 53 | } 54 | 55 | /* Box */ 56 | 57 | .box { 58 | position: relative; 59 | -ms-behavior: url('css/ie/PIE.htc'); 60 | 61 | .image { 62 | &.featured { 63 | margin: 2em 0; 64 | width: 100%; 65 | } 66 | } 67 | } 68 | 69 | /* Icon */ 70 | 71 | .icon { 72 | &.major { 73 | position: relative; 74 | -ms-behavior: url('css/ie/PIE.htc'); 75 | } 76 | } 77 | 78 | /* Image */ 79 | 80 | .image { 81 | position: relative; 82 | -ms-behavior: url('css/ie/PIE.htc'); 83 | 84 | img { 85 | position: relative; 86 | -ms-behavior: url('css/ie/PIE.htc'); 87 | } 88 | } 89 | 90 | /* Header */ 91 | 92 | #header { 93 | nav { 94 | > ul { 95 | > li { 96 | a { 97 | color: #fff; 98 | display: inline-block; 99 | text-decoration: none; 100 | border: 0; 101 | 102 | &.icon { 103 | &:before { 104 | color: #fff; 105 | margin-right: 0.5em; 106 | } 107 | } 108 | } 109 | } 110 | } 111 | } 112 | 113 | &.alt { 114 | color: #fff; 115 | 116 | nav { 117 | > ul { 118 | > li { 119 | a:not(.button) { 120 | &.icon { 121 | &:before { 122 | color: rgba(255,255,255,0.75); 123 | } 124 | } 125 | } 126 | 127 | &.active { 128 | a:not(.button) { 129 | background-color: rgba(255,255,255,0.2); 130 | } 131 | } 132 | } 133 | } 134 | } 135 | } 136 | } 137 | 138 | .dropotron { 139 | border: solid 1px $color-border; 140 | 141 | &.level-0 { 142 | margin-top: 0; 143 | 144 | &:before { 145 | display: none; 146 | } 147 | } 148 | } 149 | 150 | /* Banner */ 151 | 152 | #banner { 153 | background-attachment: scroll; 154 | background-image: url('../../images/banner.jpg'); 155 | background-position: auto; 156 | background-repeat: no-repeat; 157 | background-size: cover; 158 | -ms-behavior: url('css/ie/backgroundsize.min.htc'); 159 | 160 | input[type="submit"], 161 | input[type="reset"], 162 | input[type="button"], 163 | .button { 164 | border: solid 2px #fff; 165 | } 166 | } 167 | 168 | /* Main */ 169 | 170 | #main { 171 | position: relative; 172 | z-index: 1; 173 | } 174 | 175 | /* CTA */ 176 | 177 | #cta { 178 | input[type="text"], 179 | input[type="password"], 180 | input[type="email"], 181 | select, 182 | textarea { 183 | background: $color-accent2-bg; 184 | border: solid 2px #fff; 185 | } 186 | 187 | .formerize-placeholder { 188 | color: #fff !important; 189 | } 190 | } -------------------------------------------------------------------------------- /themes/mdweb/assets/sass/ie/v8.scss: -------------------------------------------------------------------------------- 1 | @import 'vars'; 2 | @import 'mixins'; 3 | 4 | /* 5 | Alpha by HTML5 UP 6 | html5up.net | @n33co 7 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 8 | */ 9 | 10 | /* Basic */ 11 | 12 | pre, code { 13 | position: relative; 14 | -ms-behavior: url('css/ie/PIE.htc'); 15 | } 16 | 17 | /* Form */ 18 | 19 | input[type="text"], 20 | input[type="password"], 21 | input[type="email"], 22 | select, 23 | textarea { 24 | position: relative; 25 | -ms-behavior: url('css/ie/PIE.htc'); 26 | line-height: 3em; 27 | } 28 | 29 | input[type="checkbox"], 30 | input[type="radio"], { 31 | opacity: 1; 32 | z-index: auto; 33 | 34 | & + label { 35 | &:before { 36 | display: none; 37 | } 38 | } 39 | } 40 | 41 | /* Button */ 42 | 43 | input[type="submit"], 44 | input[type="reset"], 45 | input[type="button"], 46 | .button { 47 | position: relative; 48 | -ms-behavior: url('css/ie/PIE.htc'); 49 | 50 | &.alt { 51 | border: solid 2px $color-border; 52 | } 53 | } 54 | 55 | /* Box */ 56 | 57 | .box { 58 | position: relative; 59 | -ms-behavior: url('css/ie/PIE.htc'); 60 | 61 | .image { 62 | &.featured { 63 | margin: 2em 0; 64 | width: 100%; 65 | } 66 | } 67 | } 68 | 69 | /* Icon */ 70 | 71 | .icon { 72 | &.major { 73 | position: relative; 74 | -ms-behavior: url('css/ie/PIE.htc'); 75 | } 76 | } 77 | 78 | /* Image */ 79 | 80 | .image { 81 | position: relative; 82 | -ms-behavior: url('css/ie/PIE.htc'); 83 | 84 | img { 85 | position: relative; 86 | -ms-behavior: url('css/ie/PIE.htc'); 87 | } 88 | } 89 | 90 | /* Header */ 91 | 92 | #header { 93 | nav { 94 | > ul { 95 | > li { 96 | a { 97 | color: #fff; 98 | display: inline-block; 99 | text-decoration: none; 100 | border: 0; 101 | 102 | &.icon { 103 | &:before { 104 | color: #fff; 105 | margin-right: 0.5em; 106 | } 107 | } 108 | } 109 | } 110 | } 111 | } 112 | 113 | &.alt { 114 | color: #fff; 115 | 116 | nav { 117 | > ul { 118 | > li { 119 | a:not(.button) { 120 | &.icon { 121 | &:before { 122 | color: rgba(255,255,255,0.75); 123 | } 124 | } 125 | } 126 | 127 | &.active { 128 | a:not(.button) { 129 | background-color: rgba(255,255,255,0.2); 130 | } 131 | } 132 | } 133 | } 134 | } 135 | } 136 | } 137 | 138 | .dropotron { 139 | border: solid 1px $color-border; 140 | 141 | &.level-0 { 142 | margin-top: 0; 143 | 144 | &:before { 145 | display: none; 146 | } 147 | } 148 | } 149 | 150 | /* Banner */ 151 | 152 | #banner { 153 | background-attachment: scroll; 154 | background-image: url('../../images/banner.jpg'); 155 | background-position: auto; 156 | background-repeat: no-repeat; 157 | background-size: cover; 158 | -ms-behavior: url('css/ie/backgroundsize.min.htc'); 159 | 160 | input[type="submit"], 161 | input[type="reset"], 162 | input[type="button"], 163 | .button { 164 | border: solid 2px #fff; 165 | } 166 | } 167 | 168 | /* Main */ 169 | 170 | #main { 171 | position: relative; 172 | z-index: 1; 173 | } 174 | 175 | /* CTA */ 176 | 177 | #cta { 178 | input[type="text"], 179 | input[type="password"], 180 | input[type="email"], 181 | select, 182 | textarea { 183 | background: $color-accent2-bg; 184 | border: solid 2px #fff; 185 | } 186 | 187 | .formerize-placeholder { 188 | color: #fff !important; 189 | } 190 | } -------------------------------------------------------------------------------- /docs/reference.md: -------------------------------------------------------------------------------- 1 | # Reference 2 | 3 | ## Context Variables 4 | 5 | 6 | There are MDWeb context variables available in theme templates. 7 | 8 | * *navigation* The [navigation object](#navigation-object). Useful for 9 | building navigation and menus. 10 | 11 | ```{navigation}``` 12 | 13 | 14 | * *current_page* The [page object](#page-object) for the current page you're on. A useful 15 | shortcut to get current page properties and settings. 16 | 17 | ```{current_page}``` 18 | 19 | * *ga_tracking* A rendered partial with the tracking code for Google 20 | Analytics. You must enable this by setting the `GA_TRACKING_ID` value in your 21 | site config. 22 | 23 | ```{ga_tracking | safe}``` 24 | 25 | * *debug_helper* An HTML debug interface. Useful for showing current config 26 | and page-level properties. You must enable this by setting the `DEBUG_HELPER` 27 | option to `True` in your site config. 28 | 29 | 30 | ## Navigation Object 31 | 32 | 33 | The navigation object is available within page templates and provides the 34 | site navigation structure as well as access to the page objects. 35 | 36 | The navigation template object is provided by the NavigationLevel class and has 37 | the following attributes available. 38 | 39 | * *id:* A unique identifier for the navigation object. This is generated by 40 | MD5'ing the content path after the _root_content_path. 41 | 42 | * *slug:* A slug for the navigation object. This is the filename with the ' 43 | .md' extension removed. 44 | 45 | * *name:* Section name. This is the lower case name extracted from the 46 | directory path. 47 | 48 | * *page:* The page object for this navigation level. 49 | 50 | * *path:* A short-cut to the filesystem path to the page (relative 51 | to the content directory). 52 | 53 | * *order:* A short-cut to the page order for this navigation level. 54 | 55 | * *meta:* A short-cut to the page meta-information. 56 | 57 | * *children:* A dictionary containing the child NavigationLevel objects. 58 | 59 | ## Page Object 60 | 61 | 62 | The page object contains all the data related to a page. The rendered page 63 | is also cached in this object. 64 | 65 | * *path:* The filesystem path to the page (relative to the content directory). 66 | 67 | * *url_path:* The URL path to the page. 68 | 69 | * *meta_inf:* The page meta-information. 70 | 71 | * *markdown_str:* The raw markdown for the page. 72 | 73 | * *page_html:* The page content after rendering the markdown. 74 | 75 | * *page_cache:* Then entire rendered page including the dependant layout. 76 | 77 | ## System Events 78 | 79 | 80 | The following is an overview of the site start-up process including the 81 | subscribable events. The following process occurs in the order it's presented 82 | in. 83 | 84 | 1. *pre-boot:* Triggered at the beginning of the Site instantiation. The only 85 | thing that has happened at this point is signal creation. 86 | 87 | 2. **\[ Internal pre-boot logic occurs \]** 88 | 89 | 3. *pre-app-start:* Triggered before the Flask application is created. 90 | 91 | 4. **\[ Flask application is created, routes are registered, error handlers 92 | are registered and logging is started \]** 93 | 94 | 5. *post-app-start:* Triggered after the application has been created. 95 | 96 | 6. *pre-config:* Triggered before the configuration is loaded. 97 | 98 | 7. **\[ Config loaded and added to Flask application, theme folder is setup, 99 | meta-inf regex is compiled \]** 100 | 101 | 8. *post-config:* Triggered after the configuration is loaded. 102 | 103 | 9. *pre-content-scan:* Triggered before the content directory is scanned. 104 | 105 | 10. **\[ The content directory is scanned and pages are created for each content 106 | file, the navigation object is created and the navigation context processor is 107 | created \]** 108 | 109 | 11. *post-content-scan:* Triggered before the content directory is scanned. 110 | 111 | 12. **\[ Internal post-boot logic occurs \]** 112 | 113 | 13. *post-boot:* Triggered after all site setup is complete and the application 114 | is ready to start handling requests. 115 | -------------------------------------------------------------------------------- /themes/alpha/assets/js/jquery.dropotron.min.js: -------------------------------------------------------------------------------- 1 | /* jquery.dropotron.js v1.4.3 | (c) n33 | n33.co | MIT licensed */ 2 | (function(e){var t="openerActiveClass",n="click touchend",r="left",i="doCollapseAll",s="position",o="trigger",u="disableSelection_dropotron",a="addClass",f="doCollapse",l=!1,c="outerWidth",h="removeClass",p="preventDefault",d="length",v="dropotron",m="clearTimeout",g="right",y="parent",b=!0,w="speed",E="none",S="stopPropagation",x="doExpand",T=":visible",N="absolute",C="css",k="center",L="toggle",A="baseZIndex",O="offsetX",M="alignment",_="submenuClassPrefix",D="children",P="hover",H="relative",B="doToggle",j="ul",F="z-index",I="opacity",q="find",R="opener",U="px",z=null,W="hide",X="offset",V="detach",$="fast";e.fn[u]=function(){return e(this)[C]("user-select",E)[C]("-khtml-user-select",E)[C]("-moz-user-select",E)[C]("-o-user-select",E)[C]("-webkit-user-select",E)},e.fn[v]=function(t){var n;if(this[d]==0)return e(this);if(this[d]>1)for(n=0;n0&&i.add(d).on("mouseleave",function(){window[m](at),at=window.setTimeout(function(){i[o](f)},et.hideDelay)}),i[u]()[W]()[a](et.menuClass)[C](s,N).on("mouseenter",function(){window[m](at)}).on(x,function(){var n,u,p,v,E,S,x,_,D,P,B;if(i.is(T))return l;window[m](at),nt.each(function(){var t=e(this);e.contains(t.get(0),d.get(0))||t[o](f)}),n=d[X](),u=d[s](),p=d[y]()[s](),v=d[c](),E=i[c](),S=i[C](F)==et[A];if(S){et[V]?x=n:x=u,P=x.top+d.outerHeight()+et.globalOffsetY,_=et[M],i[h](r)[h](g)[h](k);switch(et[M]){case g:D=x[r]-E+v,D<0&&(D=x[r],_=r);break;case k:D=x[r]-Math.floor((E-v)/2),D<0?(D=x[r],_=r):D+E>st.width()&&(D=x[r]-E+v,_=g);break;case r:default:D=x[r],D+E>st.width()&&(D=x[r]-E+v,_=g)}i[a](_)}else{d[C](s)==H||d[C](s)==N?(P=et.offsetY,D=-1*u[r]):(P=u.top+et.offsetY,D=0);switch(et[M]){case g:D+=-1*d[y]()[c]()+et[O];break;case k:case r:default:D+=d[y]()[c]()+et[O]}}navigator.userAgent.match(/MSIE ([0-9]+)\./)&&RegExp.$1<8&&(D+=et.IEOffsetX,P+=et.IEOffsetY),i[C](r,D+U)[C]("top",P+U)[C](I,"0.01").show(),B=l,d[C](s)==H||d[C](s)==N?D=-1*u[r]:D=0,i[X]()[r]<0?(D+=d[y]()[c]()-et[O],B=b):i[X]()[r]+E>st.width()&&(D+=-1*d[y]()[c]()-et[O],B=b),B&&i[C](r,D+U),i[W]()[C](I,"1");switch(et.mode){case"zoom":ot=b,d[a](et[t]),i.animate({width:L,height:L},et[w],et.easing,function(){ot=l});break;case"slide":ot=b,d[a](et[t]),i.animate({height:L},et[w],et.easing,function(){ot=l});break;case"fade":ot=b,S&&!et.noOpenerFade?(et[w]=="slow"?B=80:et[w]==$?B=40:B=Math.floor(et[w]/2),d.fadeTo(B,.01,function(){d[a](et[t]),d.fadeTo(et[w],1),i.fadeIn(et[w],function(){ot=l})})):(d[a](et[t]),d.fadeTo(et[w],1),i.fadeIn(et[w],function(){ot=l}));break;case"instant":default:d[a](et[t]),i.show()}return l}).on(f,function(){return i.is(T)?(i[W](),d[h](et[t]),i[q]("."+et[t])[h](et[t]),i[q](j)[W](),l):l}).on(B,function(){return i.is(T)?i[o](f):i[o](x),l}),d[u]()[a](R)[C]("cursor","pointer").on(n,function(e){if(ot)return;e[p](),e[S](),i[o](B)}),et.expandMode==P&&d[P](function(){if(ot)return;ut=window.setTimeout(function(){i[o](x)},et.hoverDelay)},function(){window[m](ut)})}),nt[q]("a")[C]("display","block").on(n,function(t){if(ot)return;e(this).attr("href")[d]<1&&t[p]()}),tt[q]("li")[C]("white-space","nowrap").each(function(){var t=e(this),r=t[D]("a"),s=t[D](j),u=r.attr("href");r.on(n,function(e){u[d]==0||u=="#"?e[p]():e[S]()}),r[d]>0&&s[d]==0&&t.on(n,function(e){if(ot)return;tt[o](i),e[S]()})}),tt[D]("li").each(function(){var t,n,r,i,s=e(this),o=s[D](j);if(o[d]>0){et[V]&&(et.cloneOnDetach&&(t=o.clone(),t.attr("class","")[W]().appendTo(o[y]())),o[V]().appendTo(rt));for(n=et[A],r=1,i=o;i[d]>0;r++)i[C](F,n++),et[_]&&i[a](et[_]+(n-1-et[A])),i=i[q]("> li > ul")}}),st.on("scroll",function(){tt[o](i)}).on("keypress",function(e){!ot&&e.keyCode==27&&(e[p](),tt[o](i))}),it.on(n,function(){ot||tt[o](i)})}})(jQuery); -------------------------------------------------------------------------------- /themes/mdweb/assets/js/jquery.dropotron.min.js: -------------------------------------------------------------------------------- 1 | /* jquery.dropotron.js v1.4.3 | (c) n33 | n33.co | MIT licensed */ 2 | (function(e){var t="openerActiveClass",n="click touchend",r="left",i="doCollapseAll",s="position",o="trigger",u="disableSelection_dropotron",a="addClass",f="doCollapse",l=!1,c="outerWidth",h="removeClass",p="preventDefault",d="length",v="dropotron",m="clearTimeout",g="right",y="parent",b=!0,w="speed",E="none",S="stopPropagation",x="doExpand",T=":visible",N="absolute",C="css",k="center",L="toggle",A="baseZIndex",O="offsetX",M="alignment",_="submenuClassPrefix",D="children",P="hover",H="relative",B="doToggle",j="ul",F="z-index",I="opacity",q="find",R="opener",U="px",z=null,W="hide",X="offset",V="detach",$="fast";e.fn[u]=function(){return e(this)[C]("user-select",E)[C]("-khtml-user-select",E)[C]("-moz-user-select",E)[C]("-o-user-select",E)[C]("-webkit-user-select",E)},e.fn[v]=function(t){var n;if(this[d]==0)return e(this);if(this[d]>1)for(n=0;n0&&i.add(d).on("mouseleave",function(){window[m](at),at=window.setTimeout(function(){i[o](f)},et.hideDelay)}),i[u]()[W]()[a](et.menuClass)[C](s,N).on("mouseenter",function(){window[m](at)}).on(x,function(){var n,u,p,v,E,S,x,_,D,P,B;if(i.is(T))return l;window[m](at),nt.each(function(){var t=e(this);e.contains(t.get(0),d.get(0))||t[o](f)}),n=d[X](),u=d[s](),p=d[y]()[s](),v=d[c](),E=i[c](),S=i[C](F)==et[A];if(S){et[V]?x=n:x=u,P=x.top+d.outerHeight()+et.globalOffsetY,_=et[M],i[h](r)[h](g)[h](k);switch(et[M]){case g:D=x[r]-E+v,D<0&&(D=x[r],_=r);break;case k:D=x[r]-Math.floor((E-v)/2),D<0?(D=x[r],_=r):D+E>st.width()&&(D=x[r]-E+v,_=g);break;case r:default:D=x[r],D+E>st.width()&&(D=x[r]-E+v,_=g)}i[a](_)}else{d[C](s)==H||d[C](s)==N?(P=et.offsetY,D=-1*u[r]):(P=u.top+et.offsetY,D=0);switch(et[M]){case g:D+=-1*d[y]()[c]()+et[O];break;case k:case r:default:D+=d[y]()[c]()+et[O]}}navigator.userAgent.match(/MSIE ([0-9]+)\./)&&RegExp.$1<8&&(D+=et.IEOffsetX,P+=et.IEOffsetY),i[C](r,D+U)[C]("top",P+U)[C](I,"0.01").show(),B=l,d[C](s)==H||d[C](s)==N?D=-1*u[r]:D=0,i[X]()[r]<0?(D+=d[y]()[c]()-et[O],B=b):i[X]()[r]+E>st.width()&&(D+=-1*d[y]()[c]()-et[O],B=b),B&&i[C](r,D+U),i[W]()[C](I,"1");switch(et.mode){case"zoom":ot=b,d[a](et[t]),i.animate({width:L,height:L},et[w],et.easing,function(){ot=l});break;case"slide":ot=b,d[a](et[t]),i.animate({height:L},et[w],et.easing,function(){ot=l});break;case"fade":ot=b,S&&!et.noOpenerFade?(et[w]=="slow"?B=80:et[w]==$?B=40:B=Math.floor(et[w]/2),d.fadeTo(B,.01,function(){d[a](et[t]),d.fadeTo(et[w],1),i.fadeIn(et[w],function(){ot=l})})):(d[a](et[t]),d.fadeTo(et[w],1),i.fadeIn(et[w],function(){ot=l}));break;case"instant":default:d[a](et[t]),i.show()}return l}).on(f,function(){return i.is(T)?(i[W](),d[h](et[t]),i[q]("."+et[t])[h](et[t]),i[q](j)[W](),l):l}).on(B,function(){return i.is(T)?i[o](f):i[o](x),l}),d[u]()[a](R)[C]("cursor","pointer").on(n,function(e){if(ot)return;e[p](),e[S](),i[o](B)}),et.expandMode==P&&d[P](function(){if(ot)return;ut=window.setTimeout(function(){i[o](x)},et.hoverDelay)},function(){window[m](ut)})}),nt[q]("a")[C]("display","block").on(n,function(t){if(ot)return;e(this).attr("href")[d]<1&&t[p]()}),tt[q]("li")[C]("white-space","nowrap").each(function(){var t=e(this),r=t[D]("a"),s=t[D](j),u=r.attr("href");r.on(n,function(e){u[d]==0||u=="#"?e[p]():e[S]()}),r[d]>0&&s[d]==0&&t.on(n,function(e){if(ot)return;tt[o](i),e[S]()})}),tt[D]("li").each(function(){var t,n,r,i,s=e(this),o=s[D](j);if(o[d]>0){et[V]&&(et.cloneOnDetach&&(t=o.clone(),t.attr("class","")[W]().appendTo(o[y]())),o[V]().appendTo(rt));for(n=et[A],r=1,i=o;i[d]>0;r++)i[C](F,n++),et[_]&&i[a](et[_]+(n-1-et[A])),i=i[q]("> li > ul")}}),st.on("scroll",function(){tt[o](i)}).on("keypress",function(e){!ot&&e.keyCode==27&&(e[p](),tt[o](i))}),it.on(n,function(){ot||tt[o](i)})}})(jQuery); -------------------------------------------------------------------------------- /themes/alpha/templates/_old_files/contact.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | Contact - Alpha by HTML5 UP 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 25 | 26 | 27 | 28 | 29 | 30 | 56 | 57 | 58 |
59 |
60 |

Contact Us

61 |

Tell us what you think about our little operation.

62 |
63 |
64 |
65 |
66 |
67 | 68 |
69 |
70 | 71 |
72 |
73 |
74 |
75 | 76 |
77 |
78 |
79 |
80 | 81 |
82 |
83 |
84 |
85 |
    86 |
  • 87 |
88 |
89 |
90 |
91 |
92 |
93 | 94 | 95 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /themes/mdweb/templates/_old_files/contact.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | Contact - Alpha by HTML5 UP 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 25 | 26 | 27 | 28 | 29 | 30 | 56 | 57 | 58 |
59 |
60 |

Contact Us

61 |

Tell us what you think about our little operation.

62 |
63 |
64 |
65 |
66 |
67 | 68 |
69 |
70 | 71 |
72 |
73 |
74 |
75 | 76 |
77 |
78 |
79 |
80 | 81 |
82 |
83 |
84 |
85 |
    86 |
  • 87 |
88 |
89 |
90 |
91 |
92 |
93 | 94 | 95 | 108 | 109 | 110 | --------------------------------------------------------------------------------