Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Simple, lightweight, and magic-free static site/blog generator for Python coders

License

NotificationsYou must be signed in to change notification settings

sunainapai/makesite

Repository files navigation

Take full control of your static website/blog generation by writing yourown simple, lightweight, and magic-free static site generator inPython. That's right! Reinvent the wheel!

View SourceView DemoMIT License

Contents

Introduction

This repository contains the source code of an example websitecontaining two static blogs and a few static pages. The website can begenerated by runningmakesite.py. The output looks likethis. That's it!

So go ahead, fork this repository, replace thecontent withyour own, and generate your static website. It's that simple!

You arefree to copy, use, and modify this project foryour blog or website, so go ahead and fork this repository and make ityour own project. Change thelayout if you wish to, improvethestylesheet to suit your taste, enhancemakesite.py if you need to, and develop your website/blogjust the way you want it.

But Why?

For fun and profit! Okay, maybe not for profit, but hopefully for fun.

Have you used a popular static site generator like Jekyll to generateyour blog? I have too. It is simple and great. But then did you yearnto use something even simpler to generate your blog? Do you like Python?Perhaps the thought of writing your own static site generator crossedyour mind but you thought it would be too much work? If you answered"yes" to these questions, then this project is for you.

Withmakesite.py, you are in full control. There is nohidden magic! There is no need to read any documentation to understandhow it works. There is no need to learn how to write configuration filesto produce some desired effect.

Withmakesite.py:

  • The code is the documentation.
  • The code is the configuration.

Everything is laid out as plain and simple Python code for you to readand enhance. It is less than 130 lines of code (excluding comments,docstrings, and blank lines). It gets you off the ground pretty quickly.You only need to executemakesite.py.

You can develop a decent website/blog within a few minutes and then youcan begin tinkering with thesource code, thelayout, and thestylesheet tocustomize the look and feel of your website to your satisfaction.

Get Started

This section provides some quick steps to get you off the ground asquickly as possible.

  1. For a quick demo on your local system, just enter this command:

    make serve

    If you don't havemake but have Python 3.x, enter this command:

    python3 makesite.pycd _sitepython3 -m http.server

    Note: In some environments, you may need to usepython instead ofpython3 to invoke Python 3.x.

    If you only have Python 2.7, enter this command:

    python makesite.pycd _sitepython -m SimpleHTTPServer

    Then visithttp://localhost:8000/. It should look likethis.

    Note: You can runmakesite.py with Python 2.7 orPython 3.x.

  2. You may see a fewCannot render Markdown warning messages in theoutput of the previous command. This is due to the fact that anexampleblog in this project has a few posts writtenin Markdown. To render them correctly, install thecommonmarkpackage with this command:

    pip install commonmark

    Then try the previous step again.

  3. For an Internet-facing website, you would be hosting the staticwebsite/blog on a hosting service and/or with a web server such asApache HTTP Server, Nginx, etc. You probably only need to generatethe static files and know where the static files are and move themto your hosting location.

    If you have themake command, enter this command to generate yourwebsite:

    make site

    If you don't havemake but havepython3, enter this command:

    python3 makesite.py

    Note: In some environments, you may need to usepython instead ofpython3 to invoke Python 3.x.

    If you only havepython, enter this command:

    python makesite.py

    The_site directory contains the entire generated website. Thecontent of this directory may be copied to your website hostinglocation.

The Code

Now that you know how to generate the static website that comes withthis project, it is time to see whatmakesite.py does.You probably don't really need to read the entire section. The sourcecode is pretty self-explanatory but just in case, you need a detailedoverview of what it does, here are the details:

  1. Themain() function is the starting point of website generation.It calls the other functions necessary to get the website generationdone.

  2. First it creates a fresh new_site directory from scratch. Allfiles in thestatic directory are copied to thisdirectory. Later the static website is generated and written to thisdirectory.

  3. Then it creates aparams dictionary with some default parameters.This dictionary is passed around to other functions. These otherfunctions would pick values from this dictionary to populateplaceholders in the layout template files.

    Let us take thesubtitle parameter for example. It is setto our example website's fictitious brand name: "Lorem Ipsum". Wewant each page to include this brand name as a suffix in the title.For example, theabout pagehas "About - Lorem Ipsum" in its title. Now take a look at thepage layout template that is used as the layoutfor all pages in the static website. This layout file uses the{{ subtitle }} syntax to denote that it is a placeholder thatshould be populated while rendering the template.

    Another interesting thing to note is that a content file canoverride these parameters by defining its own parameters in thecontent header. For example, take a look at the content file forthehome page. In its content header, i.e.,the HTML comments at the top with key-value pairs, it defines a newparameter namedtitle and overrides thesubtitle parameter.

    We will discuss the syntax for placeholders and content headerslater. It is quite simple.

  4. It then loads all the layout templates. There are 6 of them in thisproject.

    • layout/page.html: It contains the basetemplate that applies to all pages. It begins with<!DOCTYPE html> and<html>, and ends with</html>. The{{ content }} placeholder in this template is replaced withthe actual content of the page. For example, for the about page,the{{ content }} placeholder is replaced with the the entirecontent fromcontent/about.html. This isdone with themake_pages() calls further down in the code.

    • layout/post.html: It contains the templatefor the blog posts. Note that it does not begin with<!DOCTYPE html> and does not contain the<html> and</html> tags.This is not a complete standalone template. This templatedefines only a small portion of the blog post pages that arespecific to blog posts. It contains the HTML code and theplaceholders to display the title, publication date, and authorof blog posts.

      This template must be combined with thepage layout template to create the finalstandalone template. To do so, we replace the{{ content }}placeholder in thepage layout template withthe HTML code in thepost layout template toget a final standalone template. This is done with therender() calls further down in the code.

      The resulting standalone template still has a{{ content }}placeholder from thepost layout templatetemplate. This{{ content }} placeholder is then replacedwith the actual content from theblog posts.

    • layout/list.html: It contains the templatefor the blog listing page, the page that lists all the posts ina blog in reverse chronological order. This template does not domuch except provide a title at the top and an RSS link at thebottom. The{{ content }} placeholder is populated with thelist of blog posts in reverse chronological order.

      Just like thepost layout template , thistemplate must be combined with thepage layout template to arrive at the finalstandalone template.

    • layout/item.html: It contains the templatefor each blog post item in the blog listing page. Themake_list() function renders each blog post item with thistemplate and inserts them into thelist layout template to create the bloglisting page.

    • layout/feed.xml: It contains the XML templatefor RSS feeds. The{{ content }} placeholder is populated withthe list of feed items.

    • layout/item.xml: It contains the XML template foreach blog post item to be included in the RSS feed. Themake_list() function renders each blog post item with thistemplate and inserts them into thelayout/feed.xml template to create thecomplete RSS feed.

  5. After loading all the layout templates, it makes arender() callto combine thepost layout template with thepage layout template to form the finalstandalone post template.

    Similarly, it combines thelist layout templatetemplate with thepage layout template to formthe final list template.

  6. Then it makes twomake_pages() calls to render the home page and acouple of other site pages: thecontact pageand theabout page.

  7. Then it makes two moremake_pages() calls to render two blogs: onethat is named simplyblog and another that is namednews.

    Note that themake_pages() call accepts three positionalarguments:

    • Path to content source files provided as a glob pattern.
    • Output path template as a string.
    • Layout template code as a string.

    These three positional arguments are then followed by keywordarguments. These keyword arguments are used as template parametersin the output path template and the layout template to replace theplaceholders with their corresponding values.

    As described in point 2 above, a content file can override theseparameters in its content header.

  8. Then it makes twomake_list() calls to render the blog listingpages for the two blogs. These calls are very similar to themake_pages() calls. There are only two things that are differentabout themake_list() calls:

    • There is no point in reading the same blog posts again that wereread bymake_pages(), so instead of passing the path tocontent source files, we feed a chronologically reverse-sortedindex of blog posts returned bymake_pages() tomake_list().
    • There is an additional argument to pass theitem layout template as a string.
  9. Finally it makes two moremake_list() calls to generate the RSSfeeds for the two blogs. There is nothing different about thesecalls than the previous ones except that we use the feed XMLtemplates here to generate RSS feeds.

To recap quickly, we create a_site directory to write the static sitegenerated, define some default parameters, load all the layouttemplates, and then callmake_pages() to render pages and blog postswith these templates, callmake_list() to render blog listing pagesand RSS feeds. That's all!

Take a look at how themake_pages() andmake_list() functions areimplemented. They are very simple with less than 20 lines of code each.Once you are comfortable with this code, you can begin modifying it toadd more blogs or reduce them. For example, you probably don't need anews blog, so you may delete themake_pages() andmake_list() callsfor'news' along with its content atcontent/news.

Layout

In this project, the layout template files are located in thelayoutdirectory. But they don't necessarily have to be there. You canplace the layout files wherever you want and updatemakesite.py accordingly.

The source code ofmakesite.py that comes with thisproject understands the notion of placeholders in the layout templates.The template placeholders have the following syntax:

{{ <key> }}

Any whitespace before{{, around<key>, and after}} is ignored.The<key> should be a valid Python identifier. Here is an example oftemplate placeholder:

{{ title }}

This is a very simple template mechanism that is implemented already inthemakesite.py. For a simple website or blog, thisshould be sufficient. If you need a more sophisticated template enginesuch asJinja2 orCheetah, you need to modifymakesite.py to add support for it.

Content

In this project, the content files are located in thecontentdirectory. Most of the content files are written in HTML.However, the content files for the blog namedblog arewritten in Markdown.

The notion of headers in the content files is supported bymakesite.py. Each content file may begin with one or moreconsecutive HTML comments that contain headers. Each header has thefollowing syntax:

<!-- <key>: <value> -->

Any whitespace before, after, and around the<!--,<key>,:,<value>, and--> tokens are ignored. Here are some example headers:

<!-- title: About --><!-- subtitle: Lorem Ipsum --><!-- author: Admin -->

It looks for the headers at the top of every content file. As soon assome non-header text is encountered, the rest of the content from thatpoint is not checked for headers.

By default, placeholders in content files are not populated duringrendering. This behaviour is chosen so that you can write content freelywithout having to worry about makesite interfering with the content,i.e., you can write something like{{ title }} in the content andmakesite would leave it intact by default.

However if you do want to populate the placeholders in a content file,you need to specify a parameter namedrender with value ofyes. Thiscan be done in two ways:

  • Specify the parameter in a header in the content file in thefollowing manner:

    <!-- render: yes -->
  • Specify the parameter as a keyword argument inmake_pages call.For example:

    blog_posts = make_pages('content/blog/*.md',                        '_site/blog/{{ slug }}/index.html',                        post_layout, blog='blog', render='yes',                        **params)

FAQ

Here are some frequently asked questions along with answers to them:

  1. Can you add feature X to this project?

    I do not have any plans to add new features to this project. It isintended to be as minimal and as simple as reasonably possible. Thisproject is meant to be a quick-starter-kit for developers who wantto develop their own static site generators. Someone who needs morefeatures is free to fork this project repository and customize theproject as per their needs in their own fork.

  2. Can you add support for Jinja templates, YAML front matter, etc.?

    I will not add or accept support for Jinja templates, YAML frontmatter, etc. in this project. However, you can do so in your fork.The reasons are explained in the first point.

  3. Do you accept any new features from the contributors?

    I do not accept any new features in this project. The reasons areexplained in the first point.

  4. Do you accept bug fixes and improvements?

    Yes, I accept bug fixes and minor improvements that do not increasethe scope and complexity of this project.

  5. Are there any contribution guidelines?

    Yes, please seeCONTRIBUTING.md.

  6. How do I add my own copyright notice to the source code withoutviolating the terms of license while customizing this project in myown fork?

    This project is released under the terms of the MIT license. One ofthe terms of the license is that the original copyright notice andthe license text must be preserved. However, at the same time, whenyou edit and customize this project in your own fork, you hold thecopyright to your changes. To fulfill both conditions, please addyour own copyright notice above the original copyright notice andclarify that your software is a derivative of the original.

    Here is an example of such a notice where a person named J. Doewants to reserve all rights to their changes:

    # Copyright (c) 2018-2019 J. Doe# All rights reserved# This software is a derivative of the original makesite.py.# The license text of the original makesite.py is included below.

    Anything similar to the above notice or something to this effect issufficient.

Credits

Thanks to:

  • Susam Pal for the initial documentationand the initial unit tests.
  • Keith Gaughan for an improvedsingle-pass rendering of templates.

License

This is free and open source software. You can use, copy, modify,merge, publish, distribute, sublicense, and/or sell copies of it,under the terms of theMIT License.

This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,express or implied. See theMIT License for details.

Support

To report bugs, suggest improvements, or ask questions, please visithttps://github.com/sunainapai/makesite/issues.

About

Simple, lightweight, and magic-free static site/blog generator for Python coders

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp