|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- title: Introducing Lektor — A Static File Content Management System For Python
- url: http://lucumr.pocoo.org/2015/12/21/introducing-lektor/
- hash_url: b83377f25e572457d7ab9ed5411034c9
-
- <p>The longer I'm programming and creating software, the more I notice that I
- build a lot of stuff that requires maintenance even though it should not.
- In particular a topic that just keeps annoying me is how quickly
- technology moves forward and how much effort it is to maintain older code
- that still exist but now stands on ancient foundations.</p>
- <p>This is not a new discovery mind you. This blog you're reading started
- out as a Django application many, many years ago, made a transition to
- WordPress because I could not be bothered with updating Django and then
- turned into two different static site generators because I did not want to
- bother with making database updates and rather wanted to track my content
- in a git repository.</p>
- <p>I like static website generators quite a bit. As everything needs a
- website these days â it's impossible to escape the work to create one.
- For programmers it's possible to get away with building something with
- static website generators like Jekyll, Hexo, Hugo, Pelican, Hyde, Brunch,
- Middleman, Harp, Expose, â¦</p>
- <p>As you can see the list of tools available is endless. Unfortunately
- though these tools are all aimed at programmers and it's very hard to use
- them as a someone without programming experience. Worse though: many of
- those are clones of each other just written in different programming
- languages with very similar designs. There is very little innovation in
- that space and that's a bit unfortunate because I like the flexibility I
- get from frameworks like Flask at times.</p>
- <div class="section" id="so-i-built-my-own">
- <h2>So I Built My Own</h2>
- <p>This is by far not the first time I built a static website generator but I
- hope it will be the last time. This one however is different from any
- project I built before. The reason it exists is quite frankly that it's
- impossible to escape family duties. For me that means helping out with
- the website of my parents. I knew that I did not want that to be
- WordPress or something that needs security updates so about two years ago
- I started to investigate that options there are.</p>
- <p>After a ton of toying around I ended up using <a class="reference external" href="http://pythonhosted.org/Frozen-Flask/">Frozen-Flask</a> for that project. It was neat
- because it allowed me to structure the website exactly like I wanted.
- However it also meant that whenever text started to change I needed to
- spend time on it. Thus I had to investigate CMS solutions again.
- Countless weekends were wasted trying to make WordPress work again and
- looking at Statamic. However I found them quite a bit more complex to
- customize than what I was used to with Frozen-Flask and they did not
- really fit the format at all. Especially WordPress feels much more like a
- blog engine than a CMS.</p>
- <p>Finally I decided to sit down and build something completely different: a
- content management system that uses flat files as source files like most
- other systems, but it has a locally hosted admin panel that a non
- programmer can use. You install the application, double click on the
- project, a browser opens and you can edit the pages. It builds in the
- background into static HTML files and there is a publish button to ship it
- up to a server. For collaboration one can use Dropbox.</p>
- </div>
- <div class="section" id="enter-lektor">
- <h2>Enter Lektor</h2>
- <p>I called this system Lektor and Open Sourced it initially a few months ago
- after not having cared about it in a year or so. However I had another
- run-in with a project which was the Sentry documentation. Sentry uses
- Sphinx for the documentation and customizing the docs for what we had in
- mind there turned out to be a complete waste of time and sanity. While
- Lektor is currently not in a position where it could replace Sphinx for
- Sentry it gave me enough motivation to hack on it again on weekends.</p>
- <p>So I figured I might retry Open Sourcing it and made a website for it with
- documentation and cleaned up some bad stuff in it.</p>
- <p>Here is what it looks like when you open up the admin panel:</p>
- <img alt="https://raw.githubusercontent.com/lektor/lektor-archive/master/screenshots/admin.png" src="https://raw.githubusercontent.com/lektor/lektor-archive/master/screenshots/admin.png"/>
- </div>
- <div class="section" id="lektor-is-a-framework">
- <h2>Lektor is a Framework</h2>
- <p>But what makes Lektor so much fun to work with is that Lektor is (while
- very opinionated) very, very flexible. It takes a lot of inspiration from
- ORMs like Django's. Instead there being a "blog component" you can model
- your own blog posts and render them with the templates you want to use.
- There is not a single built-in template that you have to use. The only
- thing it gives you is a quickstart that sets up the folders and copies
- default minimalistic templates over.</p>
- <p>As an example, here is how a blog index template looks like:</p>
- <div class="highlight"><pre><span class="cp">{%</span> <span class="k">extends</span> <span class="s2">"blog_layout.html"</span> <span class="cp">%}</span>
- <span class="cp">{%</span> <span class="k">from</span> <span class="s2">"macros/pagination.html"</span> <span class="k">import</span> <span class="nv">render_pagination</span> <span class="cp">%}</span>
- <span class="cp">{%</span> <span class="k">block</span> <span class="nv">title</span> <span class="cp">%}</span>My Blog<span class="cp">{%</span> <span class="k">endblock</span> <span class="cp">%}</span>
- <span class="nt"><h1></span>My Blog<span class="nt"></h1></span>
-
- <span class="nt"><ul</span> <span class="na">class=</span><span class="s">"blog-index"</span><span class="nt">></span>
- <span class="cp">{%</span> <span class="k">for</span> <span class="nv">post</span> <span class="k">in</span> <span class="nv">this.pagination.items</span> <span class="cp">%}</span>
- <span class="nt"><li></span>
- <span class="nt"><a</span> <span class="na">href=</span><span class="s">"</span><span class="cp">{{</span> <span class="nv">post</span><span class="o">|</span><span class="nf">url</span> <span class="cp">}}</span><span class="s">"</span><span class="nt">></span><span class="cp">{{</span> <span class="nv">post.title</span> <span class="cp">}}</span><span class="nt"></a></span> â
- by <span class="cp">{{</span> <span class="nv">post.author</span> <span class="cp">}}</span>
- on <span class="cp">{{</span> <span class="nv">post.pub_date</span><span class="o">|</span><span class="nf">dateformat</span> <span class="cp">}}</span>
- <span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span>
- <span class="nt"></ul></span>
-
- <span class="cp">{%</span> <span class="k">if</span> <span class="nv">this.pagination.pages</span> <span class="o">></span> <span class="m">1</span> <span class="cp">%}</span>
- <span class="cp">{{</span> <span class="nv">render_pagination</span><span class="o">(</span><span class="nv">this.pagination</span><span class="o">)</span> <span class="cp">}}</span>
- <span class="cp">{%</span> <span class="k">endif</span> <span class="cp">%}</span>
- <span class="cp">{%</span> <span class="k">endblock</span> <span class="cp">%}</span>
- </pre></div>
- <p>The system understands what the blog is, that it has child record, that
- those records are paginated, it can provide pagination etc. However there
- is nothing in there that makes it a blog in itself. It just has a very
- flexible ORM inspired component that gives access to the structured files
- on the file system. Programming for Lektor feels very much like
- programming something with Flask or Django.</p>
- </div>
- <div class="section" id="learn-more">
- <h2>Learn More</h2>
- <p>If you want to learn more about it, there are quite a few resources at
- this point:</p>
-
- </div>
- <div class="section" id="final-words">
- <h2>Final Words</h2>
- <p>I hope people find it useful. I know that I enjoy using it a ton and I
- hope it makes others enjoy it similarly. Because I run so many Open
- Source projects and maintenance of all of them turns out to be tricky I
- figured I do this better this time around. Lektor belongs to a separate
- org and the project does not use any resources only I have access to
- (other than the domain name and the server travis-CI deploys to). So in
- case people want to help out, there is no single point of failure!</p>
- <p>I hope I can spend some time over Christmas to do the same to my other
- projects to alter the bus factor of those.</p>
- <p>There is far too much in Lektor to be able to cover it in a single blog
- post so I will probably write a bit more about some of the really cool
- things about in in the next few weeks. Enjoy!</p>
|