commit c89085297a47d258cd866938abba187d7da44b47 Author: Lektor Bot Date: Sun Feb 20 15:15:38 2022 +0100 Synchronized build diff --git a/404.html b/404.html new file mode 100644 index 00000000..757ca673 --- /dev/null +++ b/404.html @@ -0,0 +1,142 @@ + + + + + + + + + + Page Not Found | Lektor Static Content Management System + + + + +
+ + + + + + +
+ +
+
+
+ +

Page Not Found

+ +
+
+
+ + + + + +
+
+
+
+

The page you requested does not exist. Maybe it has been removed or +deleted or you made a typo when copy/pasting or typing it. If you think this +is a mistake you can report it here.

+ +
+
+
+
+ + + + + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/_404.html/header.jpg b/_404.html/header.jpg new file mode 100644 index 00000000..02f708f6 Binary files /dev/null and b/_404.html/header.jpg differ diff --git a/blog/2015/12/hello-lektor/admin.png b/blog/2015/12/hello-lektor/admin.png new file mode 100644 index 00000000..1c74ca14 Binary files /dev/null and b/blog/2015/12/hello-lektor/admin.png differ diff --git a/blog/2015/12/hello-lektor/banner.jpg b/blog/2015/12/hello-lektor/banner.jpg new file mode 100644 index 00000000..85d32756 Binary files /dev/null and b/blog/2015/12/hello-lektor/banner.jpg differ diff --git a/blog/2015/12/hello-lektor/index.html b/blog/2015/12/hello-lektor/index.html new file mode 100644 index 00000000..375aadc8 --- /dev/null +++ b/blog/2015/12/hello-lektor/index.html @@ -0,0 +1,248 @@ + + + + + + + + + + Hello Lektor! | The Transcript | Lektor Static Content Management System + + + + +
+ +
+ + + + + +
+ +
+
+
+ +
+

Hello Lektor!

+

+ by + + Armin Ronacher + + on Monday, December 21, 2015 +

+
+ +
+
+
+ + + + + +
+
+
+
+

About 25% of the Internet uses +Wordpress and +it's estimated that about 50% of Wordpress installations out there are +vulnerable to security problems because they have not been updated. This is a +very high number.

+

Because I know how much work it can be to keep software updated and my own +terrible track record of spending time of updating everything I'm running +I kept getting increasingly frustrated with the lack of software that would +allow me to run a simple website in a secure manner without having to resort +to all kinds of user-unfriendly hackery.

+

While there are many static site generators none of them really matched what I +actually wanted: a content management system that just happens to run +on the client. Most static website generators are too “hacker focused” in the +sense that they could not be used by people without programming experiences or +they are full fledged content management systems that need a server to run on +or require regular maintenance for security updates.

+

There the hacker's favorite projects like +Pelican or +Jekyll which support generating websites out of static +files that are tracked through version control and there are CMS systems like +Statamic which store all of its data in flat files +— but as mentioned — needs PHP.

+

None of those were what I was looking for. Static file generators like Jekyll +are nice in a way but not just end user unfriendly, but also very limited in +what you can do with them. They are more suited for building blogs than +more complex sites. I tried a bunch of them and built different things +with them, but ultimately always felt like something was missing.

+

After about two years of frustration with that situation I finally sat down +and spend some time working on a system to solve this problem. May I +introduce: Lektor.

+

What is Lektor?

Lektor combines the experience of using a content management system like +Wordpress with a static website generator like Jekyll and has some of the +flexibility of a web development framework like Django. It can run locally +on your computer and deploy to remote servers. All source assets are stored +either in version control or Dropbox and when you are satisfied with the end +results, you can push them online from the UI to a remote server.

+

And this is what it roughly looks like when you look at the admin panel:

+

How do I use it?

That depends on who you are. Lektor is based on the idea that there are +two parties to a website: the web developers and the editors. The former +create the design, layout, data layout and configures Lektor in general. The +latter change the contents of the website according to the general setup.

+

If you are a web developer you can install two versions of Lektor: you can +use the command line client or if you are on a Mac, you can install the +desktop version. Either version comes with a handy web interface that +can be used to preview and edit all pages.

+

Once you have configured Lektor to your liking you can put the project into +version control (or just Dropbox) and let your users modify the contents. All +they have to do is to install the Desktop version of Lektor, double click the +project in their Dropbox and start changing it.

+

If you just want to edit the contents of a project you can install the +Desktop version or maybe in the future use a cloud hosted version.

+

Project Layout

To get an idea how it works, you can have a look at the github repository of +this website which contains the +project for this website and blog and have a look at the introduction +documentation: Getting Started. You can +also find a screencast there.

+

On a very basic level Lektor takes .lr files which are basic text files +with a super simple format and generates out HTML files. The .lr files +correspond to a previously set up data model. They are pure text format for +key/value pairs. Each pair is separated by three dashes (---):

+
field_1: value
+---
+field_2:
+
+a longer value
+
+

You can set up data models for simple things like blog posts but also more +elaborate ones if you want to build portfolio sites. For instance you could +set up models for your projects and then access that data in the templates.

+

The content files are stored in folders in a tree like structure and at any +level you can add other files as attachments:

+

An Open Source Project

Lektor is available under a BSD license and run as a +community Open Source project on github. +The build system is written in Python, the UI in JavaScript with React and +the GUI components use Electron.

+

Feedback Appreciated

Lektor took two attempts to get into a usable application and I'm sure that +there is more that needs to be done to scratch the needs of most users. +However I also know that there is no point in delaying an initial release +unnecessarily. What's being released today is the application as it exists +today and I think it's in a good shape to build really cool websites with +it. I welcome you to give it a try and give feedback on what you think +about it.

+ +
+
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/blog/2015/12/hello-lektor/structure.png b/blog/2015/12/hello-lektor/structure.png new file mode 100644 index 00000000..4459ae1b Binary files /dev/null and b/blog/2015/12/hello-lektor/structure.png differ diff --git a/blog/2015/12/index.html b/blog/2015/12/index.html new file mode 100644 index 00000000..b6104449 --- /dev/null +++ b/blog/2015/12/index.html @@ -0,0 +1,147 @@ + + + + + + + + + + December 2015 Archive | The Transcript | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +
+
+ +

The Transcript, December 2015

+

+ « Back to 2015 +

+ +
+
+

About This Blog

+

+ “The Transcript” is the blog about Lektor, a new solution in static content management. +

+ Subscribe for the latest news about Lektor as well as content + management and web development. +

+

Missed a Post?

+ +
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/blog/2015/12/travis-and-ghpages/header.jpg b/blog/2015/12/travis-and-ghpages/header.jpg new file mode 100644 index 00000000..a5b9637f Binary files /dev/null and b/blog/2015/12/travis-and-ghpages/header.jpg differ diff --git a/blog/2015/12/travis-and-ghpages/index.html b/blog/2015/12/travis-and-ghpages/index.html new file mode 100644 index 00000000..edb75867 --- /dev/null +++ b/blog/2015/12/travis-and-ghpages/index.html @@ -0,0 +1,182 @@ + + + + + + + + + + Lektor Loves Travis-CI and GitHub Pages | The Transcript | Lektor Static Content Management System + + + + +
+ +
+ + + + + +
+ +
+
+
+ +
+

Lektor Loves Travis-CI and GitHub Pages

+

+ by + + Armin Ronacher + + on Wednesday, December 23, 2015 +

+
+ +
+
+
+ + + + + +
+
+
+
+

Open Source projects need websites, that's a given, and one of the most popular +ways to host them these days is GitHub Pages. +It's a free service provided by GitHub which allows +hosts a git repository as a website on a subdomain of github.io.

+

Wouldn't it be nice if you could easily host Lektor projects on there? Turns +out you can with the help of Travis-CI. Because +Lektor has built-in support for deploying to GitHub Pages pairing up the three +is a breeze.

+

We created a guide and also recorded +a screencast that goes with it:

+ +
+
+
+
+ + + + + + + + +
+ +
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/blog/2015/index.html b/blog/2015/index.html new file mode 100644 index 00000000..e04b7ec7 --- /dev/null +++ b/blog/2015/index.html @@ -0,0 +1,155 @@ + + + + + + + + + + 2015 Archive | The Transcript | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +
+
+ +

The Transcript in 2015

+

+ « Back to the archive +

+ +
+
+

About This Blog

+

+ “The Transcript” is the blog about Lektor, a new solution in static content management. +

+ Subscribe for the latest news about Lektor as well as content + management and web development. +

+

Missed a Post?

+ +
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/blog/2016/3/index.html b/blog/2016/3/index.html new file mode 100644 index 00000000..3df9c4cc --- /dev/null +++ b/blog/2016/3/index.html @@ -0,0 +1,147 @@ + + + + + + + + + + March 2016 Archive | The Transcript | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +
+
+ +

The Transcript, March 2016

+

+ « Back to 2016 +

+ +
+
+

About This Blog

+

+ “The Transcript” is the blog about Lektor, a new solution in static content management. +

+ Subscribe for the latest news about Lektor as well as content + management and web development. +

+

Missed a Post?

+ +
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/blog/2016/3/lektor-at-rails-girls-summer-of-code/banner.jpg b/blog/2016/3/lektor-at-rails-girls-summer-of-code/banner.jpg new file mode 100644 index 00000000..91f8d790 Binary files /dev/null and b/blog/2016/3/lektor-at-rails-girls-summer-of-code/banner.jpg differ diff --git a/blog/2016/3/lektor-at-rails-girls-summer-of-code/index.html b/blog/2016/3/lektor-at-rails-girls-summer-of-code/index.html new file mode 100644 index 00000000..9ade383b --- /dev/null +++ b/blog/2016/3/lektor-at-rails-girls-summer-of-code/index.html @@ -0,0 +1,191 @@ + + + + + + + + + + Lektor at Rails Girls Summer of Code 2016 | The Transcript | Lektor Static Content Management System + + + + +
+ +
+ + + + + +
+ +
+
+
+ +
+

Lektor at Rails Girls Summer of Code 2016

+

+ by + + Armin Ronacher + + on Thursday, March 17, 2016 +

+
+ +
+
+
+ + + + + +
+
+
+
+

I'm happy to announce that Lektor is participating as a project in this year's +Rails Girls Summer of Code (RGSOC). +Unlike what the name would suggest, RGSOC is open for all Open Source projects +and not just Ruby.

+

The goal of RGSOC is to bring more women into programming. To quote the +website:

+

Rails Girls Summer of Code is a global fellowship program aimed at bringing +more diversity into Open Source. Successful applicants are paid a monthly +stipend, from July-September, to work on Open Source projects of their +choice.

+
+

Lektor was accepted as a particpating project. For more information about +the project there refer to the project overview on +RGSOC.

+

We want to make it as easy as possible to work on Lektor during the event which +is why we will be very flexible with regards to which area interested +developers want to work on.

+

If you are interested in working on Lektor you can reach out to us via +Twitter at @getlektor or +Gitter.

+ +
+
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/blog/2016/3/road-to-lektor-2/header.jpg b/blog/2016/3/road-to-lektor-2/header.jpg new file mode 100644 index 00000000..7f424622 Binary files /dev/null and b/blog/2016/3/road-to-lektor-2/header.jpg differ diff --git a/blog/2016/3/road-to-lektor-2/index.html b/blog/2016/3/road-to-lektor-2/index.html new file mode 100644 index 00000000..af7df1e9 --- /dev/null +++ b/blog/2016/3/road-to-lektor-2/index.html @@ -0,0 +1,210 @@ + + + + + + + + + + Road to Lektor 2.0 | The Transcript | Lektor Static Content Management System + + + + +
+ +
+ + + + + +
+ +
+
+
+ +
+

Road to Lektor 2.0

+

+ by + + Armin Ronacher + + on Thursday, March 10, 2016 +

+
+ +
+
+
+ + + + + +
+
+
+
+

It's great to see what people have been building with Lektor so far. It also +shows us what still needs to be built. For a lot of things we improved for +Lektor 2.0 which is going to release very soon indeed. To give you some ideas +what's going to change here is a current brief look into the changelog and +what has been changed so far.

+

Page Discovery

One of the biggest frustrations users have voiced is the inability to control +discoverability of pages. In Lektor 1.0 you can only hide pages entirely in +which case the build process skips over them but there was no way to hide them +by default from queries. While you could always hide pages by changing the +query, this did not work for pagination and it also required you to be quite +careful with the queries you are writing in templates.

+

In Lektor 2.0 we introduced the system _discoverable attribute which allows +you to easily hide pages from any query. Queries can explicitly include +undiscoverable pages but you do not need to take care of this yourself. This +makes it possible to automatically hide drafts from blogs for instance. Lektor +will still build it but without knowing the URL you cannot see it on the +overview.

+

Virtual Paths

The biggest change in Lektor 2.0 is the introduction of virtual paths and +sources. This is somewhat of an under the hood change but it has big +implications on what is possible with Lektor plugins. Each page can have +virtual resources below it that can be provided by plugins. These virtual +resources are separated from the page through what is called a virtual path +which is indicated by the at-sign (@). For instance this blog here uses +a plugin which provides a blog archive available at /blog@blog-archive and +the year 2015 is available at /blog@blog-archive/2015 etc.

+

Next / Previous Page

Lektor 2.0 implements sibling support through it's virtual path system which +allows you to refer to the next or previous record easily. This is for +instance used by this blog here to link between blog posts.

+

Improved Alternative Support

Alternatives were heavily improved. Individual fields that are absent in +content files now fall back to the primary content file. In addition it is +now possible to ask Lektor about which alternatives exist for a given source +or in total. This simplifies handling of internationalized pages greatly +but more work will be done in that field.

+

Improved Plugin Support

Plugins now have the ability to do a few more things they could not do before:

+
    +
  • custom field types (want to render reStructuredText? You can now build a plugin)
  • +
  • custom build programs: because of the virtual source and path support you can +now build custom build programs that build things that do not exist in the +source tree. For instance you can build feeds, blog archives etc.
  • +
+ +
+
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/blog/2016/4/index.html b/blog/2016/4/index.html new file mode 100644 index 00000000..472b1a26 --- /dev/null +++ b/blog/2016/4/index.html @@ -0,0 +1,145 @@ + + + + + + + + + + April 2016 Archive | The Transcript | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +
+
+ +

The Transcript, April 2016

+

+ « Back to 2016 +

+ +
+
+

About This Blog

+

+ “The Transcript” is the blog about Lektor, a new solution in static content management. +

+ Subscribe for the latest news about Lektor as well as content + management and web development. +

+

Missed a Post?

+ +
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/blog/2016/4/lektor-2-released/banner.jpg b/blog/2016/4/lektor-2-released/banner.jpg new file mode 100644 index 00000000..51771358 Binary files /dev/null and b/blog/2016/4/lektor-2-released/banner.jpg differ diff --git a/blog/2016/4/lektor-2-released/index.html b/blog/2016/4/lektor-2-released/index.html new file mode 100644 index 00000000..134d0ded --- /dev/null +++ b/blog/2016/4/lektor-2-released/index.html @@ -0,0 +1,231 @@ + + + + + + + + + + Lektor 2.0 Released | The Transcript | Lektor Static Content Management System + + + + +
+ +
+ + + + + +
+ +
+
+
+ +
+

Lektor 2.0 Released

+

+ by + + Armin Ronacher + + on Monday, April 11, 2016 +

+
+ +
+
+
+ + + + + +
+
+
+
+

After quite a bit of wait, I'm happy to announce the 2.0 release of Lektor. +Some things that previously were supposed to go into this release were pushed +out a bit more because the wait just was too long and quite a few features +were already in this release.

+

Here is the changelog of what's in this release:

+
    +
  • Added _discoverable system field which controls if a page should show +up in children. The default is that a page is discoverable. Setting it +to False means in practical terms that someone needs to know the URL as +all collection operations will not return it.
  • +
  • Added for_page function to pagination that returns the pagiantion for a +specific page.
  • +
  • Make pagination next_page and prev_page be None on the edges.
  • +
  • Allow plugins to provide publishers.
  • +
  • Added |markdown filter.
  • +
  • Added French translations.
  • +
  • Unicode filenames as final build artifacts are now explicitly disallowed.
  • +
  • Serve up a 404.html as an error page in the dev server.
  • +
  • Improvements to the path normalization and alt handling. This should support +URL generation in more complex cases between alts now.
  • +
  • Show a clearer error message when URL generation fails because a source +object is virtual (does not have a path).
  • +
  • Empty text is now still valid markdown.
  • +
  • Lektor clean now loads the plugins as well.
  • +
  • Basic support for type customization.
  • +
  • Fields that are absent in a content file from an alternative are now pulled +from the primary content file.
  • +
  • Development server now resolves index.html for assets as well.
  • +
  • Markdown processing now correctly adjusts links relative to where the +rendered output is rendered.
  • +
  • Added Dutch translations.
  • +
  • Added Record.get_siblings()
  • +
  • Added various utilties: build_url, join_path, parse_path
  • +
  • Added support for virtual paths and made pagination work with it.
  • +
  • Added support for Query.distinct
  • +
  • Add support for pagination url resolving on root URL.
  • +
  • Server information can now also contain extra key/value pairs that +can be used by publishers to affect the processing.
  • +
  • The thumbnails will now always have the correct width and height set +as an attribute.
  • +
  • added datetime type
  • +
  • added support for the process_image utility functions so that plugins +can use it directly.
  • +
  • added support for included_assets and excluded_assets in the project file.
  • +
  • added Spanish translations.
  • +
  • added Japanese translations.
  • +
  • added support for discovering existing alts of sources.
  • +
  • added support for image cropping.
  • +
  • added preliminary support for publishing on windows.
  • +
  • children and attachments can now have a hidden flag configured explicitly. +Attachments will also no longer inherit the hidden flag of the parent +record as that is not a sensible default.
  • +
  • changed internal sqlite consistency mode to improve performance on HDDs.
  • +
  • allow SVG files to be treated as images. This is something that does not +work in all situations yet (in particular thumbnailing does not actually +do anything for those)
  • +
+

As always you can install the release as mentioned in the release notes. +If you had a previous version of Lektor the install process should auto +upgrade. If you use the OS X desktop build, just drag the new application over +the already existing one.

+ +
+
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/blog/2016/index.html b/blog/2016/index.html new file mode 100644 index 00000000..5889ae3f --- /dev/null +++ b/blog/2016/index.html @@ -0,0 +1,164 @@ + + + + + + + + + + 2016 Archive | The Transcript | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +
+
+ +

The Transcript in 2016

+

+ « Back to the archive +

+ +
+
+

About This Blog

+

+ “The Transcript” is the blog about Lektor, a new solution in static content management. +

+ Subscribe for the latest news about Lektor as well as content + management and web development. +

+

Missed a Post?

+ +
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/blog/2018/1/index.html b/blog/2018/1/index.html new file mode 100644 index 00000000..c76997dc --- /dev/null +++ b/blog/2018/1/index.html @@ -0,0 +1,145 @@ + + + + + + + + + + January 2018 Archive | The Transcript | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +
+
+ +

The Transcript, January 2018

+

+ « Back to 2018 +

+ +
+
+

About This Blog

+

+ “The Transcript” is the blog about Lektor, a new solution in static content management. +

+ Subscribe for the latest news about Lektor as well as content + management and web development. +

+

Missed a Post?

+ +
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/blog/2018/1/lektor-31-released/index.html b/blog/2018/1/lektor-31-released/index.html new file mode 100644 index 00000000..fcbbc539 --- /dev/null +++ b/blog/2018/1/lektor-31-released/index.html @@ -0,0 +1,187 @@ + + + + + + + + + + Lektor 3.1 Released | The Transcript | Lektor Static Content Management System + + + + +
+ +
+ + + + + +
+ +
+
+
+ +
+

Lektor 3.1 Released

+

+ by + + Joseph Nix + + on Monday, January 29, 2018 +

+
+ +
+
+
+ + + + + +
+
+
+
+

Lektor continues to be discovered and used by more people, and many of these fine people have given back. Lektor is now a little easier to use, and more robust with plenty of bugfixes and added support for Python 3. Let's take a brief look at what's been done, and what we want next.

+

Lektor Themes

Perhaps the most eye-catching change is the introduction of the ability for Lektor to use themes. This can become a very powerful tool, allowing people to make beautiful sites even more quickly by standing on the shoulders of those who have gone before them. Why spend more time fiddling with your CSS, or template queries than you need to? If there's a theme that's similar to yours in either design or function, you can start from there. Assets, templates, models, and flowblocks are all able to be themed, offering a lot of flexibility in what they could provide.

+

This is a very new and experimental feature. We'd love to add more support for themes so that making them and using them is easy, but it may be a bit rough around the edges at the moment. The contributor who gave Lektor its initial theming ability also created the first theme, which is a simple theme based on the Nix Hugo theme.

+

I think this feature has a lot of potential. It's pretty exciting.

+

Improved Support and Testing

If you take a look at the changelog since version 2.0, you'll notice many references to bugfixes and dependency updates. We now support Python 3, and have a more extensive automated testing environment. We have upgraded the versions of Mistune (our current Markdown parser), and several JavaScript dependencies that drive the admin interface. Windows users have a few bugfixes to help them out, and added automated testing to catch more bugs before they reach a release.

+

Other Features

    +
  • Templates now have greater control of image quality and rotation.
  • +
  • Fixed and expanded handling of image EXIF data.
  • +
  • Improved date handling in the admin interface.
  • +
  • Added ability to publish from different file systems.
  • +
  • Fields can now be disabled for alternatives in the admin interface.
  • +
  • Another Plugin hook added between instantiating the Renderer and creating the Markdown Processor.
  • +
  • lektor dev shell now uses IPython if it's installed.
  • +
+

Support for Mac Installer Paused

The code that was used to create the Mac installer for the Desktop App has some problems. We're (hopefully temporarily) pulling support for the desktop app because of this. If you have modern experience making executables (especially cross-platform) and would like to contribute, we'd love to have your support. We generally want to make Lektor as easy to use as possible, and a new desktop app could really help with that.

+

Want to Contribute?

Open Source Software lives and dies by the communities that use them, love them, and support them. If you're a developer looking to get your feet wet in OSS, we'd love to review your pull request. <3

+

A larger task, if you're someone with React (and Python) knowledge, is our admin interface. It has served us pretty well so far, but it also has some issues. It could use some TLC.

+ +
+
+
+
+ + + + + + + + +
+ +
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/blog/2018/1/lektor-31-released/pancakes-2020863.jpg b/blog/2018/1/lektor-31-released/pancakes-2020863.jpg new file mode 100644 index 00000000..81b53883 Binary files /dev/null and b/blog/2018/1/lektor-31-released/pancakes-2020863.jpg differ diff --git a/blog/2018/5/index.html b/blog/2018/5/index.html new file mode 100644 index 00000000..2bbc09da --- /dev/null +++ b/blog/2018/5/index.html @@ -0,0 +1,145 @@ + + + + + + + + + + May 2018 Archive | The Transcript | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +
+
+ +

The Transcript, May 2018

+

+ « Back to 2018 +

+ +
+
+

About This Blog

+

+ “The Transcript” is the blog about Lektor, a new solution in static content management. +

+ Subscribe for the latest news about Lektor as well as content + management and web development. +

+

Missed a Post?

+ +
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/blog/2018/5/plugin-play/index.html b/blog/2018/5/plugin-play/index.html new file mode 100644 index 00000000..e437e948 --- /dev/null +++ b/blog/2018/5/plugin-play/index.html @@ -0,0 +1,176 @@ + + + + + + + + + + Plugin Play | The Transcript | Lektor Static Content Management System + + + + +
+ +
+ + + + + +
+ +
+
+
+ +
+

Plugin Play

+

+ by + + Joseph Nix + + on Tuesday, May 15, 2018 +

+
+ +
+
+
+ + + + + +
+
+
+
+

Get Lektor Updates

This site just updated the way it lists available plugins! Now https://www.getlektor.com/plugins/ gives you a list of all known Lektor plugins in a much more interactive and informative way. This will hopefully make it much easier for you to discover plugins that are relevant to your project and your needs. If you are a plugin developer, this should also help you find examples from existing plugins to help you learn how to interact better with Lektor's plugin system.

+

Categories

Each plugin now falls within one of a few broad categories to help quickly narrow your search for what you're looking for.

+

Details

Each plugin also now has its own dedicated page. On this page you can see the entire README for a plugin, in beautiful rendered Markdown or reStructuredText, GitHub statistics, authorship information, and tags. This page should give you all the information you need to be able to use the plugin, or to decide if it's what you're looking for as a guide to building your own.

+

Tags

Plugins are tagged with specific key words or phrases that describe what they are used for and how they work. All of a plugin's tags are listed on its page as a link. Each tag has its own page where you can see other plugins that share that tag. This offers a powerful way to navigate between related content, and another way to discover more plugins.

+

I think this is especially useful for plugin development when the tag is an event that the plugin hooks. This allows you to quickly find the source code of plugins that depend on the same Lektor plugin events, so that you can see many quick examples to help you write your own plugin. For instance, you can find all of the plugins that hook the before-build-all event by looking at it's tag page here. Tag pages for events also have links back to the plugin documentation pages, including the page for that specific event.

+

Now go check out some plugins!

+ +
+
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/blog/2018/5/plugin-play/spices.jpg b/blog/2018/5/plugin-play/spices.jpg new file mode 100644 index 00000000..11504c7c Binary files /dev/null and b/blog/2018/5/plugin-play/spices.jpg differ diff --git a/blog/2018/index.html b/blog/2018/index.html new file mode 100644 index 00000000..84901bfc --- /dev/null +++ b/blog/2018/index.html @@ -0,0 +1,161 @@ + + + + + + + + + + 2018 Archive | The Transcript | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +
+
+ +

The Transcript in 2018

+

+ « Back to the archive +

+ +
+
+

About This Blog

+

+ “The Transcript” is the blog about Lektor, a new solution in static content management. +

+ Subscribe for the latest news about Lektor as well as content + management and web development. +

+

Missed a Post?

+ +
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/blog/2020/8/index.html b/blog/2020/8/index.html new file mode 100644 index 00000000..4a0fb225 --- /dev/null +++ b/blog/2020/8/index.html @@ -0,0 +1,145 @@ + + + + + + + + + + August 2020 Archive | The Transcript | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +
+
+ +

The Transcript, August 2020

+

+ « Back to 2020 +

+ +
+
+

About This Blog

+

+ “The Transcript” is the blog about Lektor, a new solution in static content management. +

+ Subscribe for the latest news about Lektor as well as content + management and web development. +

+

Missed a Post?

+ +
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/blog/2020/8/lektor-32-released/coffee-ground-1171092-1599x1066.jpg b/blog/2020/8/lektor-32-released/coffee-ground-1171092-1599x1066.jpg new file mode 100644 index 00000000..0d775751 Binary files /dev/null and b/blog/2020/8/lektor-32-released/coffee-ground-1171092-1599x1066.jpg differ diff --git a/blog/2020/8/lektor-32-released/index.html b/blog/2020/8/lektor-32-released/index.html new file mode 100644 index 00000000..ddc16d33 --- /dev/null +++ b/blog/2020/8/lektor-32-released/index.html @@ -0,0 +1,205 @@ + + + + + + + + + + Lektor 3.2 Released | The Transcript | Lektor Static Content Management System + + + + +
+ +
+ + + + + +
+ +
+
+
+ +
+

Lektor 3.2 Released

+

+ by + + Andreas Runfalk + + on Thursday, August 20, 2020 +

+
+ +
+
+
+ + + + + +
+
+
+
+

It's been a long time in the making, and on behalf of the Lektor Team I'm happy to introduce the 3.2 release of Lektor. As some of you may have noticed the development pace of Lektor has slowed down over the past two years. Those of you who have had open PRs for a long time, sorry for the delay and we'll try to do better going forward!

+

Recently we've made a big push to bring the project back on its feet. Our focus besides merging PRs and fixing various issues has been to streamline the CI and release process. The biggest change was the switch from Travis and Appveyor to GitHub actions which should make the release process a lot easier going forward.

+

We have also promoted lektor-tags and lektor-atom to official plugins. This represents our commitment to keep them up to date. We have also deployed a new CI workflow that can publish new versions using tags. This will be something all plugin authors can use in their own projects. Thank you Gonzalo Peña-Castellanos for spearheading the CI improvements.

+

A big shoutout to all the contributors who help make Lektor awesome!

+

Since Python 2 is EOL and its final release ever happened on April 20th, 2020, this will be the last Lektor release with Python 2 support. This is also the last release supporting Python 3.5 since it is very near EOL and we want to have opportunity to work with several benefits of Python 3.6 going forward.

The slugify change may mean that your URLs will change when you update to Lektor 3.2. This could lead to broken links from external sites such as search engines. This can be fixed by providing a custom slug for the necessary pages.

Changelog

Bugfixes

    +
  • Fix to correctly calculate relative urls from slugs that contain dots. (thank you f-seven)
  • +
  • Fix to allow negative integers in integer fields in the admin UI. (thank you David Ferguson)
  • +
  • Fix lektor plugins reinstall triggered on_setup_env instead of just reinstalling plugins. (thank you Mikhail Gerasimov)
  • +
  • Fix failing dimensions detection for some JPEG thumbnails. (thank you Ionuț Ciocîrlan)
  • +
  • Fix mismatch between reported thumbnail size and on-disk image when both width & height are provided. (thank you Ionuț Ciocîrlan)
  • +
  • Return JPEG dimensions swapped when EXIF rotation is in effect. (thank you Ionuț Ciocîrlan)
  • +
  • Fix off-by-1px rounding discrepancy between reported thumbnail dimensions and actual dimensions. (thank you Ionuț Ciocîrlan)
  • +
  • Fix off-by-one error in pagination's iter_pages in the interpretation of the right_current argument, and adding an appropriate trailing None for some uses. (thank you Jeff Dairiki)
  • +
+

New features

+

Improvements

    +
  • Added support for setting the output_path in the project file. (thank you George Kussumoto)
  • +
  • Added support for deleting and excluding files for the rsync deployment publisher. (thank you m-lib)
  • +
  • Several modernization and performance improvements to the admin UI (thank you Jakob Schnitzer)
  • +
  • Improved speed of source info updates. (thank you Jeff Dairiki)
  • +
  • Set colorspace to sRGB for thumbnails. This should result in significantly reduced thumbnail file size when the source image uses a more exotic colorspace. (thank you Stavros Korokithakis)
  • +
  • Now stripping profiles and comments from thumbnails, for even smaller file size. (thank you Stavros Korokithakis)
  • +
  • Improved speed of flow rendering in the admin UI. (thank you David Ferguson)
  • +
  • Improved image-heavy build speeds by reducing the amount of data extracted from EXIFs. (thank you Tobias Pfeiffer)
  • +
  • Added the ability to collapse flow elements in the admin UI. (thank you Jason Traub)
  • +
  • Now extra_flags is passed to all plugin events. (thank you Joseph Nix)
  • +
  • Extra flags can now be passed to the clean and dev shell CLI commands. (thank you Joseph Nix)
  • +
  • Deprecate the crop thumbnail argument in favor of the new mode argument, which can be one of fit (the default), crop, or stretch. (thank you Ionuț Ciocîrlan)
  • +
  • upscale=False for thumbnails can now prevent up scaling. (thank you Ionuț Ciocîrlan)
  • +
  • Added a new CLI command lektor dev new-theme. (thank you Joseph Nix)
  • +
  • Made admin use full UTF-8 version of RobotoSlab. Fixes missing glyphs for some languages (thank you Jakob Schnitzer)
  • +
  • Bumped minimum Jinja2 version to 2.11 (thank you Joseph Nix)
  • +
  • Bumped filetype dependency to 1.0.7 because of API changes (thank you Ionuț Ciocîrlan)
  • +
  • Relative urls are now as short as possible. (thank you Oleg Geier and Ionuț Ciocîrlan)
  • +
  • Automatically include setup.cfg configured for universal wheels when creating plugins (thank you George Kussumoto)
  • +
  • Changed default slug creation to use python-slugify. This should mean greater language support, but this may produce slightly different results than before for some users (thank you Joseph Nix and Ionuț Ciocîrlan)
  • +
+ +
+
+
+
+ + + + + + + + +
+
+
+ + + + +
+
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/blog/2020/index.html b/blog/2020/index.html new file mode 100644 index 00000000..541533ee --- /dev/null +++ b/blog/2020/index.html @@ -0,0 +1,152 @@ + + + + + + + + + + 2020 Archive | The Transcript | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +
+
+ +

The Transcript in 2020

+

+ « Back to the archive +

+ +
+
+

About This Blog

+

+ “The Transcript” is the blog about Lektor, a new solution in static content management. +

+ Subscribe for the latest news about Lektor as well as content + management and web development. +

+

Missed a Post?

+ +
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/blog/archives/index.html b/blog/archives/index.html new file mode 100644 index 00000000..b677cf12 --- /dev/null +++ b/blog/archives/index.html @@ -0,0 +1,153 @@ + + + + + + + + + + Archive | The Transcript | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +
+
+ +

The Transcript Archive

+

+ « back to the blog +

+ There have been posts in the following years: +

+ +
+
+

About This Blog

+

+ “The Transcript” is the blog about Lektor, a new solution in static content management. +

+ Subscribe for the latest news about Lektor as well as content + management and web development. +

+

Missed a Post?

+ +
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/blog/feed.xml b/blog/feed.xml new file mode 100644 index 00000000..e23edacb --- /dev/null +++ b/blog/feed.xml @@ -0,0 +1,320 @@ + +The Transcripturn:uuid:ba2c0c5f-e742-36a4-a184-2b9e5f2282bb2020-08-20T00:00:00ZLektor's blogLektor 3.2 Released2020-08-20T00:00:00ZAndreas Runfalkurn:uuid:c70ce082-4b32-3a99-9052-691daaf6033a +<div class="page-banner page-banner-500" style="background-image: url(coffee-ground-1171092-1599x1066.jpg)"></div> + +<div class="text-block text-block-default"> + <p>It's been a long time in the making, and on behalf of the Lektor Team I'm happy to introduce the 3.2 release of Lektor. As some of you may have noticed the development pace of Lektor has slowed down over the past two years. Those of you who have had open PRs for a long time, sorry for the delay and we'll try to do better going forward!</p> +<p>Recently we've made a big push to bring the project back on its feet. Our focus besides merging PRs and fixing various issues has been to streamline the CI and release process. The biggest change was the <a href="https://github.com/lektor/lektor/pull/734">switch from Travis and Appveyor to GitHub actions</a> which should make the release process a lot easier going forward.</p> +<p>We have also promoted <a href="https://github.com/lektor/lektor-tags">lektor-tags</a> and <a href="https://github.com/lektor/lektor-atom">lektor-atom</a> to official plugins. This represents our commitment to keep them up to date. We have also deployed a <a href="https://github.com/lektor/lektor-atom/pull/28">new CI workflow</a> that can publish new versions using tags. This will be something all plugin authors can use in their own projects. Thank you <a href="https://github.com/goanpeca">Gonzalo Peña-Castellanos</a> for spearheading the CI improvements.</p> +<p>A big shoutout to all the contributors who help make Lektor awesome!</p> +<div class="admonition admonition-info"><p>Since Python 2 is EOL and its <a href="https://blog.python.org/2020/04/python-2718-last-release-of-python-2.html">final release ever</a> happened on April 20th, 2020, this will be the last Lektor release with Python 2 support. This is also the last release supporting Python 3.5 since it is <a href="https://devguide.python.org/#status-of-python-branches">very near EOL</a> and we want to have opportunity to work with several benefits of Python 3.6 going forward.</p></div><div class="admonition admonition-warning"><p>The slugify change may mean that your URLs will change when you update to Lektor 3.2. This could lead to broken links from external sites such as search engines. This can be fixed by providing a custom slug for the necessary pages.</p></div><h1 id="changelog">Changelog</h1><h2 id="bugfixes">Bugfixes</h2><ul> +<li>Fix to correctly calculate relative urls from slugs that contain dots. (thank you <a href="https://github.com/f-seven">f-seven</a>)</li> +<li>Fix to allow negative integers in integer fields in the admin UI. (thank you <a href="https://github.com/davidferguson">David Ferguson</a>)</li> +<li>Fix <code>lektor plugins reinstall</code> triggered <code>on_setup_env</code> instead of just reinstalling plugins. (thank you <a href="https://github.com/germn">Mikhail Gerasimov</a>)</li> +<li>Fix failing dimensions detection for some JPEG thumbnails. (thank you <a href="https://github.com/xlotlu">Ionuț Ciocîrlan</a>)</li> +<li>Fix mismatch between reported thumbnail size and on-disk image when both width &amp; height are provided. (thank you <a href="https://github.com/xlotlu">Ionuț Ciocîrlan</a>)</li> +<li>Return JPEG dimensions swapped when EXIF rotation is in effect. (thank you <a href="https://github.com/xlotlu">Ionuț Ciocîrlan</a>)</li> +<li>Fix off-by-1px rounding discrepancy between reported thumbnail dimensions and actual dimensions. (thank you <a href="https://github.com/xlotlu">Ionuț Ciocîrlan</a>)</li> +<li>Fix off-by-one error in pagination's iter_pages in the interpretation of the right_current argument, and adding an appropriate trailing <code>None</code> for some uses. (thank you <a href="https://github.com/dairiki">Jeff Dairiki</a>)</li> +</ul> +<h2 id="new-features">New features</h2><ul> +<li>Added the ability to <a href="/docs/templates/videoops/">generate video thumbnails</a> with ffmpeg. (thank you <a href="https://github.com/runfalk">Andreas Runfalk</a>)</li> +</ul> +<h2 id="improvements">Improvements</h2><ul> +<li>Added support for setting the output_path in the project file. (thank you <a href="https://github.com/georgeyk">George Kussumoto</a>)</li> +<li>Added support for deleting and excluding files for the rsync deployment publisher. (thank you <a href="https://github.com/m-lib">m-lib</a>)</li> +<li>Several modernization and performance improvements to the admin UI (thank you <a href="https://github.com/yagebu">Jakob Schnitzer</a>)</li> +<li>Improved speed of source info updates. (thank you <a href="https://github.com/dairiki">Jeff Dairiki</a>)</li> +<li>Set colorspace to sRGB for thumbnails. This should result in significantly reduced thumbnail file size when the source image uses a more exotic colorspace. (thank you <a href="https://github.com/skorokithakis">Stavros Korokithakis</a>)</li> +<li>Now stripping profiles and comments from thumbnails, for even smaller file size. (thank you <a href="https://github.com/skorokithakis">Stavros Korokithakis</a>)</li> +<li>Improved speed of flow rendering in the admin UI. (thank you <a href="https://github.com/davidferguson">David Ferguson</a>)</li> +<li>Improved image-heavy build speeds by reducing the amount of data extracted from EXIFs. (thank you <a href="https://github.com/tgpfeiffer">Tobias Pfeiffer</a>)</li> +<li>Added the ability to collapse flow elements in the admin UI. (thank you <a href="https://github.com/jtraub91">Jason Traub</a>)</li> +<li>Now <code>extra_flags</code> is passed to all plugin events. (thank you <a href="https://github.com/nixjdm">Joseph Nix</a>)</li> +<li>Extra flags can now be passed to the <code>clean</code> and <code>dev shell</code> CLI commands. (thank you <a href="https://github.com/nixjdm">Joseph Nix</a>)</li> +<li>Deprecate the <code>crop</code> thumbnail argument in favor of the new <code>mode</code> argument, which can be one of <code>fit</code> (the default), <code>crop</code>, or <code>stretch</code>. (thank you <a href="https://github.com/xlotlu">Ionuț Ciocîrlan</a>)</li> +<li><code>upscale=False</code> for thumbnails can now prevent up scaling. (thank you <a href="https://github.com/xlotlu">Ionuț Ciocîrlan</a>)</li> +<li>Added a new CLI command <code>lektor dev new-theme</code>. (thank you <a href="https://github.com/nixjdm">Joseph Nix</a>)</li> +<li>Made admin use full UTF-8 version of RobotoSlab. Fixes missing glyphs for some languages (thank you <a href="https://github.com/yagebu">Jakob Schnitzer</a>)</li> +<li>Bumped minimum Jinja2 version to 2.11 (thank you <a href="https://github.com/nixjdm">Joseph Nix</a>)</li> +<li>Bumped filetype dependency to 1.0.7 because of API changes (thank you <a href="https://github.com/xlotlu">Ionuț Ciocîrlan</a>)</li> +<li>Relative urls are now as short as possible. (thank you <a href="https://github.com/relikd">Oleg Geier</a> and <a href="https://github.com/xlotlu">Ionuț Ciocîrlan</a>)</li> +<li>Automatically include setup.cfg configured for universal wheels when creating plugins (thank you <a href="https://github.com/georgeyk">George Kussumoto</a>)</li> +<li>Changed default slug creation to use <a href="https://github.com/un33k/python-slugify">python-slugify</a>. This should mean greater language support, but this may produce slightly different results than before for some users (thank you <a href="https://github.com/nixjdm">Joseph Nix</a> and <a href="https://github.com/xlotlu">Ionuț Ciocîrlan</a>)</li> +</ul> + +</div>Plugin Play2018-05-15T00:00:00ZJoseph Nixurn:uuid:a10aa9d1-b8c4-381e-ae4f-17e101f15466 +<div class="page-banner page-banner-300" style="background-image: url(spices.jpg)"></div> + +<div class="text-block text-block-default"> + <h2 id="get-lektor-updates">Get Lektor Updates</h2><p>This site just updated the way it lists available plugins! Now <a href="https://www.getlektor.com/plugins/">https://www.getlektor.com/plugins/</a> gives you a list of all known Lektor plugins in a much more interactive and informative way. This will hopefully make it much easier for you to discover plugins that are relevant to your project and your needs. If you are a plugin developer, this should also help you find examples from existing plugins to help you learn how to interact better with Lektor's plugin system.</p> +<h3 id="categories">Categories</h3><p>Each plugin now falls within one of a few broad categories to help quickly narrow your search for what you're looking for.</p> +<h3 id="details">Details</h3><p>Each plugin also now has its own dedicated page. On this page you can see the entire README for a plugin, in beautiful rendered Markdown or reStructuredText, GitHub statistics, authorship information, and tags. This page should give you all the information you need to be able to use the plugin, or to decide if it's what you're looking for as a guide to building your own.</p> +<h3 id="tags">Tags</h3><p>Plugins are tagged with specific key words or phrases that describe what they are used for and how they work. All of a plugin's tags are listed on its page as a link. Each tag has its own page where you can see other plugins that share that tag. This offers a powerful way to navigate between related content, and another way to discover more plugins.</p> +<p>I think this is especially useful for plugin development when the tag is an event that the plugin hooks. This allows you to quickly find the source code of plugins that depend on the same Lektor plugin events, so that you can see many quick examples to help you write your own plugin. For instance, you can find all of the plugins that hook the <code>before-build-all</code> event by looking at it's tag page <a href="/plugins/tag/before-build-all/">here</a>. Tag pages for events also have links back to the plugin documentation pages, including the page for that specific event.</p> +<p>Now go check out some <a href="/plugins">plugins</a>!</p> + +</div>Lektor 3.1 Released2018-01-29T00:00:00ZJoseph Nixurn:uuid:eff20a81-ee57-3c93-ad4b-13ef7b6369cf +<div class="page-banner page-banner-500-tall" style="background-image: url(pancakes-2020863.jpg)"></div> + +<div class="text-block text-block-default"> + <p>Lektor continues to be discovered and used by more people, and many of these fine people have given back. Lektor is now a little easier to use, and more robust with plenty of bugfixes and added support for Python 3. Let's take a brief look at what's been done, and what we want next.</p> +<h2 id="lektor-themes">Lektor Themes</h2><p>Perhaps the most eye-catching change is the introduction of the ability for Lektor to use <a href="/docs/themes/">themes</a>. This can become a very powerful tool, allowing people to make beautiful sites even more quickly by standing on the shoulders of those who have gone before them. Why spend more time fiddling with your CSS, or template queries than you need to? If there's a theme that's similar to yours in either design or function, you can start from there. Assets, templates, models, and flowblocks are all able to be themed, offering a lot of flexibility in what they could provide.</p> +<p>This is a very new and experimental feature. We'd love to add more support for themes so that making them and using them is easy, but it may be a bit rough around the edges at the moment. The <a href="https://github.com/rlaverde">contributor</a> who gave Lektor its initial theming ability also created the <a href="https://github.com/rlaverde/lektor-theme-nix">first theme</a>, which is a simple theme based on the <a href="https://themes.gohugo.io/hugo-theme-nix/">Nix Hugo theme</a>.</p> +<p>I think this feature has a lot of potential. It's pretty exciting.</p> +<h2 id="improved-support-and-testing">Improved Support and Testing</h2><p>If you take a look at the changelog since version 2.0, you'll notice many references to bugfixes and dependency updates. We now support Python 3, and have a more extensive automated testing environment. We have upgraded the versions of Mistune (our current Markdown parser), and several JavaScript dependencies that drive the admin interface. Windows users have a few bugfixes to help them out, and added automated testing to catch more bugs before they reach a release.</p> +<h2 id="other-features">Other Features</h2><ul> +<li>Templates now have greater control of image quality and rotation.</li> +<li>Fixed and expanded handling of image EXIF data.</li> +<li>Improved date handling in the admin interface.</li> +<li>Added ability to publish from different file systems.</li> +<li>Fields can now be disabled for alternatives in the admin interface.</li> +<li>Another Plugin hook added between instantiating the Renderer and creating the Markdown Processor.</li> +<li><code>lektor dev shell</code> now uses IPython if it's installed.</li> +</ul> +<h2 id="support-for-mac-installer-paused">Support for Mac Installer Paused</h2><p>The code that was used to create the Mac installer for the Desktop App has <a href="https://github.com/lektor/lektor/issues/420">some problems</a>. We're (hopefully temporarily) pulling support for the desktop app because of this. If you have modern experience making executables (especially cross-platform) and would like to contribute, we'd love to have your support. We generally want to make Lektor as easy to use as possible, and a new desktop app could really help with that.</p> +<h2 id="want-to-contribute">Want to Contribute?</h2><p>Open Source Software lives and dies by the communities that use them, love them, and support them. If you're a developer looking to get your feet wet in OSS, we'd love to review your pull request. &lt;3</p> +<p>A larger task, if you're someone with React (and Python) knowledge, is our admin interface. It has served us pretty well so far, but it also has <a href="https://github.com/lektor/lektor/issues/458">some issues</a>. It could use some TLC.</p> + +</div>Lektor 2.0 Released2016-04-11T00:00:00ZArmin Ronacherurn:uuid:5588c5e7-cabd-3118-b6e8-b20b9324f814 +<div class="page-banner page-banner-500" style="background-image: url(banner.jpg)"></div> + +<div class="text-block text-block-default"> + <p>After quite a bit of wait, I'm happy to announce the 2.0 release of Lektor. +Some things that previously were supposed to go into this release were pushed +out a bit more because the wait just was too long and quite a few features +were already in this release.</p> +<p>Here is the changelog of what's in this release:</p> +<ul> +<li>Added <code>_discoverable</code> system field which controls if a page should show +up in <code>children</code>. The default is that a page is discoverable. Setting it +to <code>False</code> means in practical terms that someone needs to know the URL as +all collection operations will not return it.</li> +<li>Added <code>for_page</code> function to pagination that returns the pagiantion for a +specific page.</li> +<li>Make pagination next_page and prev_page be None on the edges.</li> +<li>Allow plugins to provide publishers.</li> +<li>Added <code>|markdown</code> filter.</li> +<li>Added French translations.</li> +<li>Unicode filenames as final build artifacts are now explicitly disallowed.</li> +<li>Serve up a 404.html as an error page in the dev server.</li> +<li>Improvements to the path normalization and alt handling. This should support +URL generation in more complex cases between alts now.</li> +<li>Show a clearer error message when URL generation fails because a source +object is virtual (does not have a path).</li> +<li>Empty text is now still valid markdown.</li> +<li>Lektor clean now loads the plugins as well.</li> +<li>Basic support for type customization.</li> +<li>Fields that are absent in a content file from an alternative are now pulled +from the primary content file.</li> +<li>Development server now resolves index.html for assets as well.</li> +<li>Markdown processing now correctly adjusts links relative to where the +rendered output is rendered.</li> +<li>Added Dutch translations.</li> +<li>Added Record.get_siblings()</li> +<li>Added various utilties: build_url, join_path, parse_path</li> +<li>Added support for virtual paths and made pagination work with it.</li> +<li>Added support for Query.distinct</li> +<li>Add support for pagination url resolving on root URL.</li> +<li>Server information can now also contain extra key/value pairs that +can be used by publishers to affect the processing.</li> +<li>The thumbnails will now always have the correct width and height set +as an attribute.</li> +<li>added datetime type</li> +<li>added support for the process_image utility functions so that plugins +can use it directly.</li> +<li>added support for included_assets and excluded_assets in the project file.</li> +<li>added Spanish translations.</li> +<li>added Japanese translations.</li> +<li>added support for discovering existing alts of sources.</li> +<li>added support for image cropping.</li> +<li>added preliminary support for publishing on windows.</li> +<li>children and attachments can now have a hidden flag configured explicitly. +Attachments will also no longer inherit the hidden flag of the parent +record as that is not a sensible default.</li> +<li>changed internal sqlite consistency mode to improve performance on HDDs.</li> +<li>allow SVG files to be treated as images. This is something that does not +work in all situations yet (in particular thumbnailing does not actually +do anything for those)</li> +</ul> +<p>As always you can install the release as mentioned in the release notes. +If you had a previous version of Lektor the install process should auto +upgrade. If you use the OS X desktop build, just drag the new application over +the already existing one.</p> + +</div>Lektor at Rails Girls Summer of Code 20162016-03-17T00:00:00ZArmin Ronacherurn:uuid:e50b8ae4-067c-3841-9d45-5abad5c5455a +<div class="page-banner page-banner-500" style="background-image: url(banner.jpg)"></div> + +<div class="text-block text-block-default"> + <p>I'm happy to announce that Lektor is participating as a project in this year's +<a href="http://railsgirlssummerofcode.org/">Rails Girls Summer of Code</a> (RGSOC). +Unlike what the name would suggest, RGSOC is open for all Open Source projects +and not just Ruby.</p> +<p>The goal of RGSOC is to bring more women into programming. To quote the +website:</p> +<blockquote><p>Rails Girls Summer of Code is a global fellowship program aimed at bringing +more diversity into Open Source. Successful applicants are paid a monthly +stipend, from July-September, to work on Open Source projects of their +choice.</p> +</blockquote> +<p>Lektor was accepted as a particpating project. For more information about +the project there refer to the <a href="https://teams.railsgirlssummerofcode.org/projects/115-lektor-cms">project overview on +RGSOC</a>.</p> +<p>We want to make it as easy as possible to work on Lektor during the event which +is why we will be very flexible with regards to which area interested +developers want to work on.</p> +<p>If you are interested in working on Lektor you can reach out to us via +Twitter at <a href="https://twitter.com/getlektor">@getlektor</a> or +<a href="https://gitter.im/lektor/lektor" +class="js-gitter-toggle-chat-button">Gitter</a>.</p> + +</div>Road to Lektor 2.02016-03-10T00:00:00ZArmin Ronacherurn:uuid:c3f89a5c-5503-3f0d-9725-933145c96f57 +<div class="page-banner page-banner-500" style="background-image: url(header.jpg)"></div> + +<div class="text-block text-block-default"> + <p>It's great to see what people have been building with Lektor so far. It also +shows us what still needs to be built. For a lot of things we improved for +Lektor 2.0 which is going to release very soon indeed. To give you some ideas +what's going to change here is a current brief look into the changelog and +what has been changed so far.</p> +<h2 id="page-discovery">Page Discovery</h2><p>One of the biggest frustrations users have voiced is the inability to control +discoverability of pages. In Lektor 1.0 you can only hide pages entirely in +which case the build process skips over them but there was no way to hide them +by default from queries. While you could always hide pages by changing the +query, this did not work for pagination and it also required you to be quite +careful with the queries you are writing in templates.</p> +<p>In Lektor 2.0 we introduced the system <code>_discoverable</code> attribute which allows +you to easily hide pages from any query. Queries can explicitly include +undiscoverable pages but you do not need to take care of this yourself. This +makes it possible to automatically hide drafts from blogs for instance. Lektor +will still build it but without knowing the URL you cannot see it on the +overview.</p> +<h2 id="virtual-paths">Virtual Paths</h2><p>The biggest change in Lektor 2.0 is the introduction of virtual paths and +sources. This is somewhat of an under the hood change but it has big +implications on what is possible with Lektor plugins. Each page can have +virtual resources below it that can be provided by plugins. These virtual +resources are separated from the page through what is called a virtual path +which is indicated by the at-sign (<code>@</code>). For instance this blog here uses +a plugin which provides a blog archive available at <code>/blog@blog-archive</code> and +the year 2015 is available at <code>/blog@blog-archive/2015</code> etc.</p> +<h2 id="next/previous-page">Next / Previous Page</h2><p>Lektor 2.0 implements sibling support through it's virtual path system which +allows you to refer to the next or previous record easily. This is for +instance used by this blog here to link between blog posts.</p> +<h2 id="improved-alternative-support">Improved Alternative Support</h2><p>Alternatives were heavily improved. Individual fields that are absent in +content files now fall back to the primary content file. In addition it is +now possible to ask Lektor about which alternatives exist for a given source +or in total. This simplifies handling of internationalized pages greatly +but more work will be done in that field.</p> +<h2 id="improved-plugin-support">Improved Plugin Support</h2><p>Plugins now have the ability to do a few more things they could not do before:</p> +<ul> +<li>custom field types (want to render reStructuredText? You can now build a plugin)</li> +<li>custom build programs: because of the virtual source and path support you can +now build custom build programs that build things that do not exist in the +source tree. For instance you can build feeds, blog archives etc.</li> +</ul> + +</div>Lektor Loves Travis-CI and GitHub Pages2015-12-23T00:00:00ZArmin Ronacherurn:uuid:269329ed-591d-3721-9d49-924dccec040e +<div class="page-banner page-banner-500" style="background-image: url(header.jpg)"></div> + +<div class="text-block text-block-default"> + <p>Open Source projects need websites, that's a given, and one of the most popular +ways to host them these days is <a href="https://pages.github.com/" class="ext">GitHub Pages</a>. +It's a free service provided by <a href="https://github.com/" class="ext">GitHub</a> which allows +hosts a git repository as a website on a subdomain of <code>github.io</code>.</p> +<p>Wouldn't it be nice if you could easily host Lektor projects on there? Turns +out you can with the help of <a href="https://travis-ci.org/" class="ext">Travis-CI</a>. Because +Lektor has built-in support for deploying to GitHub Pages pairing up the three +is a breeze.</p> +<p>We <a href="../../../../docs/deployment/travisci/" class="ref">created a guide</a> and also recorded +a screencast that goes with it:</p> +<iframe width="100%" height=410 frameborder="0" allowfullscreen="allowfullscreen" + src="https://www.youtube.com/embed/3pj_EyZIL5A?autoplay=0&fs=1"> +</iframe> +</div>Hello Lektor!2015-12-21T00:00:00ZArmin Ronacherurn:uuid:7bca6045-8f90-31b1-9ed8-5757a4c665c6 +<div class="page-banner page-banner-500" style="background-image: url(banner.jpg)"></div> + +<div class="text-block text-block-default"> + <p>About <a href="http://w3techs.com/technologies/details/cm-wordpress/all/all">25% of the Internet uses +Wordpress</a> and +it's estimated that about 50% of Wordpress installations out there are +vulnerable to security problems because they have not been updated. This is a +very high number.</p> +<p>Because I know how much work it can be to keep software updated and my own +terrible track record of spending time of updating everything I'm running +I kept getting increasingly frustrated with the lack of software that would +allow me to run a simple website in a secure manner without having to resort +to all kinds of user-unfriendly hackery.</p> +<p>While there are many static site generators none of them really matched what I +actually wanted: a content management system that just happens to run +on the client. Most static website generators are too “hacker focused” in the +sense that they could not be used by people without programming experiences or +they are full fledged content management systems that need a server to run on +or require regular maintenance for security updates.</p> +<p>There the hacker's favorite projects like +<a href="https://github.com/getpelican/pelican">Pelican</a> or +<a href="https://jekyllrb.com/">Jekyll</a> which support generating websites out of static +files that are tracked through version control and there are CMS systems like +<a href="http://statamic.com/">Statamic</a> which store all of its data in flat files +— but as mentioned — needs PHP.</p> +<p>None of those were what I was looking for. Static file generators like Jekyll +are nice in a way but not just end user unfriendly, but also very limited in +what you can do with them. They are more suited for building blogs than +more complex sites. I tried a bunch of them and built different things +with them, but ultimately always felt like something was missing.</p> +<p>After about two years of frustration with that situation I finally sat down +and spend some time working on a system to solve this problem. May I +introduce: Lektor.</p> +<h2 id="what-is-lektor">What is Lektor?</h2><p>Lektor combines the experience of using a content management system like +Wordpress with a static website generator like Jekyll and has some of the +flexibility of a web development framework like Django. It can run locally +on your computer and deploy to remote servers. All source assets are stored +either in version control or Dropbox and when you are satisfied with the end +results, you can push them online from the UI to a remote server.</p> +<p>And this is what it roughly looks like when you look at the admin panel:</p> +<div class="screenshot-frame"><img src="admin.png"></div><h2 id="how-do-i-use-it">How do I use it?</h2><p>That depends on who you are. Lektor is based on the idea that there are +two parties to a website: the web developers and the editors. The former +create the design, layout, data layout and configures Lektor in general. The +latter change the contents of the website according to the general setup.</p> +<p>If you are a web developer you can install two versions of Lektor: you can +use the command line client or if you are on a Mac, you can install the +desktop version. Either version comes with a handy web interface that +can be used to preview and edit all pages.</p> +<p>Once you have configured Lektor to your liking you can put the project into +version control (or just Dropbox) and let your users modify the contents. All +they have to do is to install the Desktop version of Lektor, double click the +project in their Dropbox and start changing it.</p> +<p>If you just want to edit the contents of a project you can install the +Desktop version or maybe in the future use a cloud hosted version.</p> +<h2 id="project-layout">Project Layout</h2><p>To get an idea how it works, you can have a look at the <a href="https://github.com/lektor/lektor-website/">github repository of +this website</a> which contains the +project for this website and blog and have a look at the introduction +documentation: <a href="../../../../docs/quickstart/" class="ref">Getting Started</a>. You can +also find a screencast there.</p> +<p>On a very basic level Lektor takes <code>.lr</code> files which are basic text files +with a super simple format and generates out HTML files. The <code>.lr</code> files +correspond to a previously set up data model. They are pure text format for +key/value pairs. Each pair is separated by three dashes (<code>---</code>):</p> +<pre><code>field_1: value +--- +field_2: + +a longer value +</code></pre> +<p>You can set up data models for simple things like blog posts but also more +elaborate ones if you want to build portfolio sites. For instance you could +set up models for your projects and then access that data in the templates.</p> +<p>The content files are stored in folders in a tree like structure and at any +level you can add other files as attachments:</p> +<div class="screenshot-frame"><img src="structure.png"></div><h2 id="an-open-source-project">An Open Source Project</h2><p>Lektor is available under <a href="../../../../license/">a BSD license</a> and run as a +community Open Source project <a href="https://github.com/lektor/lektor/" class="ext">on github</a>. +The build system is written in Python, the UI in JavaScript with React and +the GUI components use Electron.</p> +<h2 id="feedback-appreciated">Feedback Appreciated</h2><p>Lektor took two attempts to get into a usable application and I'm sure that +there is more that needs to be done to scratch the needs of most users. +However I also know that there is no point in delaying an initial release +unnecessarily. What's being released today is the application as it exists +today and I think it's in a good shape to build really cool websites with +it. I welcome you to give it a try and give feedback on what you think +about it.</p> + +</div> \ No newline at end of file diff --git a/blog/header.jpg b/blog/header.jpg new file mode 100644 index 00000000..ed147d5c Binary files /dev/null and b/blog/header.jpg differ diff --git a/blog/index.html b/blog/index.html new file mode 100644 index 00000000..be0a7e78 --- /dev/null +++ b/blog/index.html @@ -0,0 +1,254 @@ + + + + + + + + + + The Transcript | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +
+
+ +

The Transcript

+ +
+

Lektor 3.2 Released

+

+ What's changed with Lektor 3.2 + Read more … +

+ by + + Andreas Runfalk + + on Aug 20, 2020 +

+
+ +
+

Plugin Play

+

+ Discovering and learning about plugins just got easier. + Read more … +

+ by + + Joseph Nix + + on May 15, 2018 +

+
+ +
+

Lektor 3.1 Released

+

+ What's changed with Lektor 3.1. + Read more … +

+ by + + Joseph Nix + + on Jan 29, 2018 +

+
+ +
+

Lektor 2.0 Released

+

+ After a long wait, Lektor 2.0 is now available for consumption. + Read more … +

+ by + + Armin Ronacher + + on Apr 11, 2016 +

+
+ +
+

Lektor at Rails Girls Summer of Code 2016

+

+ Lektor is participating as a project in the Rails Girls Summer of Code. + Read more … +

+ by + + Armin Ronacher + + on Mar 17, 2016 +

+
+ +
+

Road to Lektor 2.0

+

+ What's cooking for Lektor 2.0 and what's missing so far. + Read more … +

+ by + + Armin Ronacher + + on Mar 10, 2016 +

+
+ +
+

Lektor Loves Travis-CI and GitHub Pages

+

+ Read about how to use Lektor with Travis-CI and GitHub Pages. + Read more … +

+ by + + Armin Ronacher + + on Dec 23, 2015 +

+
+ +
+

Hello Lektor!

+

+ Welcome to Lektor, the static content management system that introduces a +new paradigm for developing beautiful websites. + Read more … +

+ by + + Armin Ronacher + + on Dec 21, 2015 +

+
+ + + + +
+
+

About This Blog

+

+ “The Transcript” is the blog about Lektor, a new solution in static content management. +

+ Subscribe for the latest news about Lektor as well as content + management and web development. +

+

Missed a Post?

+ +
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/community/header.jpg b/community/header.jpg new file mode 100644 index 00000000..7698fd86 Binary files /dev/null and b/community/header.jpg differ diff --git a/community/index.html b/community/index.html new file mode 100644 index 00000000..8bb8468c --- /dev/null +++ b/community/index.html @@ -0,0 +1,157 @@ + + + + + + + + + + Community | Lektor Static Content Management System + + + + +
+ + + + + + +
+ +
+
+
+ +

Community

+ +
+
+
+ + + + + +
+
+
+
+

Rules of Engagement

Working with Lektor is more fun when you can ask questions to other users.

+

Lektor is so new that there aren't many channels for it yet, but we look forward to growing the community! As projects scale up to involve multiple people it's important to set up rules and expectations about what is acceptable behavior. Lektor wants to be an inclusive and a friendly environment. We want try to mediate between participants to resolve conflict if one arises. As a participant in this community, you should be friendly, welcoming and considerate, and you should be careful and professional with the words you chose in conversation.

+

We're people from different culture and backgrounds, and we know disagreement is a fact of life. Keep technical discussions technical and abstain from making it personal. If you feel like someone overstepped a line, misbehaved or an incident has been mishandled, please reach out to us. Inquiries will be handled with the utmost respect and confidentiality.

+

Here is where you can find other Lektor users:

+ +

Want to get in contact with us otherwise?

+ + +
+
+
+
+ + + + + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/contact/header.jpg b/contact/header.jpg new file mode 100644 index 00000000..8a3eb012 Binary files /dev/null and b/contact/header.jpg differ diff --git a/contact/index.html b/contact/index.html new file mode 100644 index 00000000..ba14ddba --- /dev/null +++ b/contact/index.html @@ -0,0 +1,147 @@ + + + + + + + + + + Contact | Lektor Static Content Management System + + + + +
+ + + + + + +
+ +
+
+
+ +

Contact

+ +
+
+
+ + + + + +
+
+
+
+

Lektor is an Open Source project licensed under the three clause BSD +license. For detailed copyright and license information +see License & Copyright.

+

Imprint

Armin Ronacher
+Khünburg, 86
+9620 Hermagor; Austria

+

VAT number / UID: AT U68598289
+E-Mail: armin@ronacher.eu

+ +
+
+
+
+ + + + + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/artifact/artifact-name/index.html b/docs/api/build/artifact/artifact-name/index.html new file mode 100644 index 00000000..30914263 --- /dev/null +++ b/docs/api/build/artifact/artifact-name/index.html @@ -0,0 +1,275 @@ + + + + + + + + + + artifact_name | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

artifact_name

+ + + + + +

This property just returns the artifact name. This is mostly useful for +debugging purposes as in the majority of situations you already have +the artifact name from different sources.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/artifact/index.html b/docs/api/build/artifact/index.html new file mode 100644 index 00000000..64215f77 --- /dev/null +++ b/docs/api/build/artifact/index.html @@ -0,0 +1,370 @@ + + + + + + + + + + Artifact | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

lektor.builder.Artifact

+ + + +
    + + + +
+ +

During the build process Lektor creates artifact objects to represent final +build artifacts. Generally each Source Object will +generate one artifact for which it acts as a primary source.

+

There are however many cases in which a source object will create +sub-artifacts. For instance any thumbnail created in the context of a page +will be creating its own artifact. To give plugins the same ability the +artifact system is partially documented. See also sub_artifact to see how to create your own artifact +instances.

+

The most important function of an artifact is open which can +open the artifact for reading or writing. If the build goes well, Lektor +will commit those changes and persist them.

+

Example

ctx = get_ctx()
+@ctx.sub_artifact('artifact.txt')
+def build_stylesheet(artifact):
+    with artifact.open('w') as f:
+        f.write('Hello World!\n')
+
+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/artifact/is-current/index.html b/docs/api/build/artifact/is-current/index.html new file mode 100644 index 00000000..063eec1a --- /dev/null +++ b/docs/api/build/artifact/is-current/index.html @@ -0,0 +1,276 @@ + + + + + + + + + + is_current | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

is_current

+ + + + + +

This property on an artifact returns True if building is necessary or +False if not based on the state of all dependencies. When you are using +the sub-artifact system, the builder callback will only be invoked if the +artifact is not current.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/artifact/open/index.html b/docs/api/build/artifact/open/index.html new file mode 100644 index 00000000..b851bc45 --- /dev/null +++ b/docs/api/build/artifact/open/index.html @@ -0,0 +1,294 @@ + + + + + + + + + + open | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

open (mode='rb', ensure_dir=None)

+ + + + + +

This opens the artifact for reading or writing. The default behavior is that +if the artifact is opened for reading, the directory it's contained within +automatically is created. This can be disabled or enabled with the +ensure_dir parameter.

+

If the artifact is opened for writing, a copy will be created and only +committed when the entire build process goes through smoothly and the +changes are committed by the builder.

+

Example

ctx = get_ctx()
+@ctx.sub_artifact('artifact.txt')
+def build_stylesheet(artifact):
+    with artifact.open('w') as f:
+        f.write('Hello World!\n')
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/artifact/render-template-into/index.html b/docs/api/build/artifact/render-template-into/index.html new file mode 100644 index 00000000..346d88c9 --- /dev/null +++ b/docs/api/build/artifact/render-template-into/index.html @@ -0,0 +1,293 @@ + + + + + + + + + + render_template_into | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

render_template_into (template_name, this, fail=False, pad=None, this=None, values=None, alt=None)

+ + + + + +

This method renders a template into the artifact. The default behavior is to +catch the error and render it into the template with a failure marker. This +can be changed with the fail parameter. This is similar to the behavior of +the render_template method of the +environment.

+

Example

class MyBuildProgram(BuildProgram):
+    ...
+
+    def build_artifact(self, artifact):
+        artifact.render_template_into(
+            self.source['_template'], this=self.source)
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/artifact/replace-with-file/index.html b/docs/api/build/artifact/replace-with-file/index.html new file mode 100644 index 00000000..f505dd58 --- /dev/null +++ b/docs/api/build/artifact/replace-with-file/index.html @@ -0,0 +1,291 @@ + + + + + + + + + + replace_with_file | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

replace_with_file (filename, ensure_dir=None, copy=False)

+ + + + + +

This method will replace the artifact with another file on the file system +on commit. This is useful when you are dealing with external applications +that create temporaries. By default the file is moved as this is what's +common with temporaries but this can be changed into a copy with copy=True.

+

Example

ctx = get_ctx()
+@ctx.sub_artifact('artifact.txt')
+def build_stylesheet(artifact):
+    temporary_file = invoke_external_program()
+    artifact.replace_with_file(temporary_file)
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/artifact/source-obj/index.html b/docs/api/build/artifact/source-obj/index.html new file mode 100644 index 00000000..19f26c40 --- /dev/null +++ b/docs/api/build/artifact/source-obj/index.html @@ -0,0 +1,276 @@ + + + + + + + + + + source_obj | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

source_obj

+ + + + + +

If an artifact directly corresponds to a Source Object +then this will be a reference to it. For most plugins this is unlikely but +if you provide a source obj in the sub_artifact call it will be available +here.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/context/changed-base-url/index.html b/docs/api/build/context/changed-base-url/index.html new file mode 100644 index 00000000..38830f3f --- /dev/null +++ b/docs/api/build/context/changed-base-url/index.html @@ -0,0 +1,294 @@ + + + + + + + + + + changed_base_url | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

changed_base_url (value)

+ + + + + +

By default the URL generation is relative to the current source record +but in some cases this can lead to issues when plugins attempt more complex +operations. In these cases the base URL can temporarily be overridden +with this method.

+

Example

with get_ctx().changed_base_url('/downloads/'):
+    url = url_to('/')
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/context/gather-dependencies/index.html b/docs/api/build/context/gather-dependencies/index.html new file mode 100644 index 00000000..ca97352e --- /dev/null +++ b/docs/api/build/context/gather-dependencies/index.html @@ -0,0 +1,297 @@ + + + + + + + + + + gather_dependencies | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

gather_dependencies (func)

+ + + + + +

As code is executing in the context of the build process Lektor will +automatically track dependencies. However in some cases it might be +useful for a plugin to know exactly which dependencies are recorded.

+

In this case this method can be used as a context manager. Whenever Lektor +encounters a dependency it will invoke the passed function.

+

Example

deps = set()
+with get_ctx().gather_dependencies(deps.add):
+    items = pad.query('/path/to/some/pages').all()
+print('The dependencies are: %s' % deps)
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/context/index.html b/docs/api/build/context/index.html new file mode 100644 index 00000000..3c044dad --- /dev/null +++ b/docs/api/build/context/index.html @@ -0,0 +1,397 @@ + + + + + + + + + + Context | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

lektor.context.Context

+ + + +
    + + + +
+ +

When Lektor builds sources into finished build artifacts it performs many +operations in addition to just creating the end result. For instance it needs +to perform dependency tracking, it needs to remember that there might be +associated other artifacts and more. All this information is tracked on the +Context during a build of a single source. At a later point the builder +will look at the context to decide on further operations to perform.

+

The current context can be discovered by calling the get_ctx +function which will return it. If there is no artifact build ongoing then +the return value will be None.

+

Basic Example

from lektor.context import get_ctx
+
+ctx = get_ctx()
+print('The current source is %s' % ctx.source)
+
+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/context/locale/index.html b/docs/api/build/context/locale/index.html new file mode 100644 index 00000000..5e3653bb --- /dev/null +++ b/docs/api/build/context/locale/index.html @@ -0,0 +1,294 @@ + + + + + + + + + + locale | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

locale

+ + + + + +

For functionality in Lektor that is dependent on the locale (technical +term for language and territory) the context provides this information. It's +automatically resolved based on configuration from the current alt.

+

This is primarily useful for plugins that want to change their behavior based +on the current requested language.

+

Example

print get_ctx().locale
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/context/pad/index.html b/docs/api/build/context/pad/index.html new file mode 100644 index 00000000..dd2422df --- /dev/null +++ b/docs/api/build/context/pad/index.html @@ -0,0 +1,295 @@ + + + + + + + + + + pad | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

pad

+ + + + + +

To access the current pad from the context, this attribute can be used. It +refers to the active Pad.

+

Example

from lektor.context import get_ctx
+
+ctx = get_ctx()
+for child in ctx.pad.root.children:
+    do_something_with(child)
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/context/record-dependency/index.html b/docs/api/build/context/record-dependency/index.html new file mode 100644 index 00000000..d36a8f34 --- /dev/null +++ b/docs/api/build/context/record-dependency/index.html @@ -0,0 +1,313 @@ + + + + + + + + + + record_dependency | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

record_dependency (filename)

+ + + + + +

Because Lektor is a system that builds artifacts into static files, an +important part of it is the dependency graph. It tracks dependencies between +produced artifacts and source files to automatically determine which files +need to be rebuilt when sources change.

+

As such it's crucial that plugins record dependencies properly or changes +will not show up, even if sources change.

+

This can be achieved with the record_dependency context method. If a plugin +references a file which can affect the output of the plugin, it's important +to record this as a dependency.

+

Note that you should only track dependencies below the project folder. It +is possible to dependend to things outside of it, but the automatic watch +system of the builder will not track files there so they will not show up +unless a manual build is instructed.

+

Example

import os
+from lektor.pluginsystem import Plugin
+
+class IncludeFilePlugin(Plugin):
+
+    def setup_env(self, **extra):
+        def include_file(filename):
+            fn = os.path.join(self.env.root_path, 'inc', filename)
+            get_ctx().record_dependency(fn)
+            with open(fn) as f:
+                return f.read().decode('utf-8')
+        self.env.jinja_env.globals['include_file'] = include_file
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/context/record/index.html b/docs/api/build/context/record/index.html new file mode 100644 index 00000000..cdcd1313 --- /dev/null +++ b/docs/api/build/context/record/index.html @@ -0,0 +1,295 @@ + + + + + + + + + + record | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

record

+ + + + + +

This works almost exactly like the source property but the +difference is that it is None if the source object is not a +Record.

+

Example

from lektor.context import get_ctx
+
+ctx = get_ctx()
+print ctx.record.record_label
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/context/source/index.html b/docs/api/build/context/source/index.html new file mode 100644 index 00000000..1b91b961 --- /dev/null +++ b/docs/api/build/context/source/index.html @@ -0,0 +1,296 @@ + + + + + + + + + + source | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

source

+ + + + + +

The context is created for each target artifact. As most artifacts are +created from Source Objects, it's typically possible +to refer back to it. Note that there are situations in which artifacts are +created but no source is available. In this case the value will be None.

+

Example

from lektor.context import get_ctx
+
+ctx = get_ctx()
+print ctx.source.source_filename
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/context/sub-artifact/index.html b/docs/api/build/context/sub-artifact/index.html new file mode 100644 index 00000000..faaa52fd --- /dev/null +++ b/docs/api/build/context/sub-artifact/index.html @@ -0,0 +1,323 @@ + + + + + + + + + + sub_artifact | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

sub_artifact (artifact_name, sources=None, source_obj=None, config_hash=None)

+ + + + + +

This method can be used as Python decorator to inform the builder to create +an artifact that is related to the current artifact but locally contained +within it. For instance this is used to implement the thumbnailing and +similar things.

+

Each artifact needs at least a name which is what the final file will be +called. For instance /demo.css would place an artifact named demo.css +in the root folder. The sources is an optional list of files that indicate +that they are responsible for creating this artifact. It can be left empty +in which case the artifact just tracks the current file. The source_obj +can optionally point to a source object but for most plugins this will never +be set.

+

The artifact passed to the function is then the Artifact +object for modification. Note that the function will not be invoked if the +artifact is already considered up to date.

+

In addition a config_hash can be provided with can be a hash value. If +provided it can identify the configuration that the artifact was created +from. If the hash changes the artifact will be rebuilt. Such a hash +can for instance be generated with get_structure_hash.

+

Example

import os
+from lektor.pluginsystem import Plugin
+
+class IncludeFilePlugin(Plugin):
+
+    def setup_env(self, **extra):
+        def get_css(artifact_name='/demo.css'):
+            ctx = get_ctx()
+            @ctx.sub_artifact(artifact_name)
+            def build_stylesheet(artifact):
+                with artifact.open('w') as f:
+                    f.write('body { background: red; }\n')
+            return artifact_name
+        self.env.jinja_env.globals['get_demo_css'] = get_css
+
+

Inside a template it can be used like this:

+
<link rel=stylesheet href="{{ get_demo_css()|url }}">
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/get-ctx/index.html b/docs/api/build/get-ctx/index.html new file mode 100644 index 00000000..54f1e788 --- /dev/null +++ b/docs/api/build/get-ctx/index.html @@ -0,0 +1,270 @@ + + + + + + + + + + get_ctx | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

lektor.context.get_ctx ()

+ + + +
    + + + +
+ +

This function returns the currently active Build Context +or None if no context is active. This is the main method to access the +context. Generally the context is available if a build is active and None +if not. This means that if plugins only call that method in places where +they know a build is access it's not necessary to check if the context is +available.

+

For more information: Context.

+

Example

from lektor.context import get_ctx
+
+ctx = get_ctx()
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/index.html b/docs/api/build/index.html new file mode 100644 index 00000000..1b5b7180 --- /dev/null +++ b/docs/api/build/index.html @@ -0,0 +1,303 @@ + + + + + + + + + + Build System | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

Build System

+ + + +
    + + + +
+ +

The build system in Lektor is what is responsible for converting the source +files into the final website. Parts of it are currently documented so that +the plugin system can interact with it.

+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/program/build-artifact/index.html b/docs/api/build/program/build-artifact/index.html new file mode 100644 index 00000000..3f0042fd --- /dev/null +++ b/docs/api/build/program/build-artifact/index.html @@ -0,0 +1,273 @@ + + + + + + + + + + build_artifact | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

build_artifact (artifact)

+ + + + + +

This method is invoked for previously declared artifacts and is supposed to +write out the artifact. It's only invoked if the builder decided that the +artifact is outdated based on the information at hand.

+

For an example refer to the add_build_program documentation.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/program/declare-artifact/index.html b/docs/api/build/program/declare-artifact/index.html new file mode 100644 index 00000000..02d8891d --- /dev/null +++ b/docs/api/build/program/declare-artifact/index.html @@ -0,0 +1,281 @@ + + + + + + + + + + declare_artifact | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

declare_artifact (artifact_name, sources=None, extra=None)

+ + + + + +

This method is supposed to be called from produce_artifacts. For each of these invocations the builder will +later invoke the build_artifact function.

+

The parameters behave as follows:

+
    +
  • artifact_name: the name of the final artifact that will be built. This +will be converted into a filename appropriate for the operating system +automatically and should thus always use forward slashes.
  • +
  • sources: a list of source filenames that make up the artifact. This will +be tracked as main indication about how artifacts change.
  • +
  • extra: arbitrary extra information that is associated with the artifact so +that build_artifact can use it.
  • +
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/program/index.html b/docs/api/build/program/index.html new file mode 100644 index 00000000..c09cd962 --- /dev/null +++ b/docs/api/build/program/index.html @@ -0,0 +1,339 @@ + + + + + + + + + + BuildProgram | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

lektor.build_programs.BuildProgram

+ + + +
    + + + +
+ +

A build program is responsible for converting a Source Object into final build artifacts. Typically such a build +program implements two methods: produce_artifacts +and build_artifact.

+

The former should invoke declare_artifact for each +artifact that should be created from the source. The builder will then +invoke build_artifact for each of these declared +artifacts if the builder determiend that the artifact needs to be built.

+

For an example refer to the add_build_program documentation.

+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/program/iter-child-sources/index.html b/docs/api/build/program/iter-child-sources/index.html new file mode 100644 index 00000000..a06340d6 --- /dev/null +++ b/docs/api/build/program/iter-child-sources/index.html @@ -0,0 +1,285 @@ + + + + + + + + + + iter_child_sources | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

iter_child_sources ()

+ + + + + +

Optionally a builder can yield further sources that are then picked up by the +builder and processed normally. This is how the recursive build process in +Lektor is implemented for normal records.

+

Example

def iter_child_sources(self):
+    for child in self.sources.children:
+        yield child
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/program/produce-artifacts/index.html b/docs/api/build/program/produce-artifacts/index.html new file mode 100644 index 00000000..f83df03d --- /dev/null +++ b/docs/api/build/program/produce-artifacts/index.html @@ -0,0 +1,276 @@ + + + + + + + + + + produce_artifacts | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

produce_artifacts ()

+ + + + + +

This method needs to be overridden by subclasses. It's invoked at the +beginning of the build process and it's purpose is to invoke the +declare_artifact method for each artifact +that the build should generate. For each of these invocations later the +build_artifact method will be invoked if the +builder determined that the artifact needs to be rebuild.

+

For an example refer to the add_build_program documentation.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/build/program/source/index.html b/docs/api/build/program/source/index.html new file mode 100644 index 00000000..b47c0970 --- /dev/null +++ b/docs/api/build/program/source/index.html @@ -0,0 +1,271 @@ + + + + + + + + + + source | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

source

+ + + + + +

This refers to the source object that created the build program. It's primary +use is to build the artifact in build_artifact.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/databags/get-bag/index.html b/docs/api/databags/get-bag/index.html new file mode 100644 index 00000000..f22c7d63 --- /dev/null +++ b/docs/api/databags/get-bag/index.html @@ -0,0 +1,249 @@ + + + + + + + + + + get_bag | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

get_bag (name)

+ + + + + +

This method is a special case of lookup which just +looks up an entire data bag and returns it as dictionary. For most +intents and purposes lookup is what you want.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/databags/index.html b/docs/api/databags/index.html new file mode 100644 index 00000000..8f31951c --- /dev/null +++ b/docs/api/databags/index.html @@ -0,0 +1,330 @@ + + + + + + + + + + Databags | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

lektor.databags.Databags

+ + + +
    + + + +
+ +

The databag system is a simple support system in Lektor that allows a +Lektor website to load variables from simple key/value or JSON files. +This is primarily useful to load translations, API keys and similar +things that are needed in multiple templates.

+

From within templates you can use the bag +function to access databags.

+

Supported Formats

Databags go into the databags/ folder in your project. There are two +formats supported: key/value pairs as ini files as well as JSON files:

+ + + + + + + + + + + + + + + + +
ExtensionFormat
.jsonJSON
.iniINI Files with or without sections
+

Dotted notation is used to navigate into data bags which are globally +merged together. This means that if you have a file named i18n.ini +with a section [en] and a key CLICK_HERE the path i18n.en.CLICK_HERE +will target that key. For JSON files further nesting is possible. You +can also just target a section and the return value will be a dictionary +which can for instance be used with the tojson +filter.

+

Example Databag

This is a basic example of a data bag that contains configuration values +for google maps. It's stored in databags/gmaps.ini:

+
key = 1233456ABCDEFG
+api_url = https://www.google.com/maps/embed/v1/
+
+

This can then be usde to good effect in templates:

+
{% macro render_map(location, width=600, height=450) %}
+  <iframe
+    width="{{ width }}" height="{{ height }}"
+    frameborder="0" style="border:0"
+    src="{{ bag('gmaps.api_url') }}?q={{ location|urlencode
+      }}&key={{ bag('gmaps.key')|urlencode }}"
+    allowfullscreen></iframe>
+{% endmacro %}
+
+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/databags/lookup/index.html b/docs/api/databags/lookup/index.html new file mode 100644 index 00000000..4f41be2d --- /dev/null +++ b/docs/api/databags/lookup/index.html @@ -0,0 +1,262 @@ + + + + + + + + + + lookup | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

lookup (key)

+ + + + + +

This is the most common way to look up values from databags from regular +Python code. Within templates you can also use the bag function which is easier to call.

+

The key is in dotted notation. For more information about this refer +to the main databags documentation.

+

Example

def translate(pad, alt, key):
+    return pad.databags.get('i18n.%s.%s' % (alt, key), key)
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/expression/and/index.html b/docs/api/db/expression/and/index.html new file mode 100644 index 00000000..1567a46c --- /dev/null +++ b/docs/api/db/expression/and/index.html @@ -0,0 +1,338 @@ + + + + + + + + + + and | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

and (other)

+ + + + + +

This evaluates to true if both the expression on the left as well as the +expression on the right are true. This is one of the few operators that +differs between Python and templates. In templates you have to use the +and method whereas in Python have to use the & operator.

+

Template Example

<h3>3 Star or Higher</h3>
+<ul>
+{% for item in this.children.filter(
+    (F.type == 'hotel').and(F.stars >= 3)) %}
+  <li>{{ item.name }}: {{ item.stars }} stars</li>
+{% endfor %}
+</ul>
+
+

Python Example

def get_hotels(page):
+    return page.children.filter(
+        (F.type == 'hotel') & (F.stars >= 3))
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/expression/contains/index.html b/docs/api/db/expression/contains/index.html new file mode 100644 index 00000000..ebd41692 --- /dev/null +++ b/docs/api/db/expression/contains/index.html @@ -0,0 +1,330 @@ + + + + + + + + + + contains | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

contains (item)

+ + + + + +

This expression evaluates to true if an item is contained within a field. +This works with fields that are lists in nature or strings. For instance a string can be +contained in another string or a item can be contained within a list.

+

Template Example

<h3>Projects Tagged 'amazing'</h3>
+<ul>
+{% for item in this.children.filter(F.tags.contains('amazing')) %}
+  <li>{{ item.name }}</li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/expression/endswith-cs/index.html b/docs/api/db/expression/endswith-cs/index.html new file mode 100644 index 00000000..7591ec9d --- /dev/null +++ b/docs/api/db/expression/endswith-cs/index.html @@ -0,0 +1,330 @@ + + + + + + + + + + endswith_cs | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

endswith_cs (other)

+ + + + + +

This evaluates to true if the string +on the left side ends with the string on the right side. This method +operates in a case-sensitive manner. For the case-insensitive method +see endswith.

+

Example

<ul>
+{% for item in this.children.filter(F.name.endswith_cs('House')) %}
+  <li>{{ item.name }}</li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/expression/endswith/index.html b/docs/api/db/expression/endswith/index.html new file mode 100644 index 00000000..8d141ff5 --- /dev/null +++ b/docs/api/db/expression/endswith/index.html @@ -0,0 +1,330 @@ + + + + + + + + + + endswith | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

endswith (other)

+ + + + + +

This evaluates to true if the string +on the left side ends with the string on the right side. This method +operates in a case-insensitive manner. For the case-sensitive method +see endswith_cs.

+

Example

<ul>
+{% for item in this.children.filter(F.name.endswith('house')) %}
+  <li>{{ item.name }}</li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/expression/eq/index.html b/docs/api/db/expression/eq/index.html new file mode 100644 index 00000000..6802664b --- /dev/null +++ b/docs/api/db/expression/eq/index.html @@ -0,0 +1,329 @@ + + + + + + + + + + == | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

==

+ + + + + +

This checks if the left side of the expression matches the right side. +Typically it compares if a value matches a specific value exactly:

+

Example

<h2>Our Houses</h2>
+<ul>
+{% for project in this.children.filter(F.type == 'house') %}
+  <li>{{ project.name }}</li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/expression/ge/index.html b/docs/api/db/expression/ge/index.html new file mode 100644 index 00000000..7d679a0e --- /dev/null +++ b/docs/api/db/expression/ge/index.html @@ -0,0 +1,329 @@ + + + + + + + + + + >= | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

>=

+ + + + + +

This evaluates to true if the left side compares larger than the right side +or equal to it. This behavior works best with integers or floats.

+

Template Example

<h3>3 or more Stars</h3>
+<ul>
+{% for item in this.children.filter(F.stars >= 3) %}
+  <li>{{ item.name }}: {{ item.stars }} stars</li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/expression/gt/index.html b/docs/api/db/expression/gt/index.html new file mode 100644 index 00000000..95224ad3 --- /dev/null +++ b/docs/api/db/expression/gt/index.html @@ -0,0 +1,330 @@ + + + + + + + + + + > | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

>

+ + + + + +

This evaluates to true if the left side compares larger than the right side. +This behavior works best with integers +or floats.

+

Template Example

<h3>Well Rated Items</h3>
+<ul>
+{% for item in this.children.filter(F.stars > 3) %}
+  <li>{{ item.name }}: {{ item.stars }} stars</li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/expression/index.html b/docs/api/db/expression/index.html new file mode 100644 index 00000000..cd99fbb1 --- /dev/null +++ b/docs/api/db/expression/index.html @@ -0,0 +1,489 @@ + + + + + + + + + + Expression | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

lektor.db.Expression

+ + + +
    + + + +
+ +

Expressions are used to filter down Query objects. They +can be passed to the filter function in particular.

+

The most basic expression is created by accessing the F object +which will return an expression that points to a field. Further manipulation +of it can create more expressive expressions. F.name literally just means +that a field by that name exists and is set to a value.

+

The query syntax is mostly the same in Python as well as in the Jinja 2 +templates, the main difference are and and or.

+

Example

>>> p.children.filter((F.name == 'foo') | (F.name == 'bar')).all()
+[<Page model=u'page' id=u'bar'>, <Page model=u'page' id=u'foo'>]
+
+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/expression/le/index.html b/docs/api/db/expression/le/index.html new file mode 100644 index 00000000..0d3c1248 --- /dev/null +++ b/docs/api/db/expression/le/index.html @@ -0,0 +1,329 @@ + + + + + + + + + + <= | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

<=

+ + + + + +

This evaluates to true if the left side compares smaller than the right side +or equal to it. This behavior works best with integers or floats.

+

Template Example

<h3>Projects From Before Including 2000</h3>
+<ul>
+{% for item in this.children.filter(F.year <= 2000) %}
+  <li>{{ item.name }} ({{ item.year }})</li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/expression/lt/index.html b/docs/api/db/expression/lt/index.html new file mode 100644 index 00000000..6fb30dfb --- /dev/null +++ b/docs/api/db/expression/lt/index.html @@ -0,0 +1,329 @@ + + + + + + + + + + < | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

<

+ + + + + +

This evaluates to true if the left side compares smaller than the right side +or equal to it. This behavior works best with integers or floats.

+

Template Example

<h3>Projects From Before 2000</h3>
+<ul>
+{% for item in this.children.filter(F.year < 2000) %}
+  <li>{{ item.name }} ({{ item.year }})</li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/expression/ne/index.html b/docs/api/db/expression/ne/index.html new file mode 100644 index 00000000..0f9c9dd0 --- /dev/null +++ b/docs/api/db/expression/ne/index.html @@ -0,0 +1,329 @@ + + + + + + + + + + != | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

!=

+ + + + + +

This checks if the left side of the expression does not match the right side +by doing an exact comparison:

+

Example

<h2>Everything Other Than Houses</h2>
+<ul>
+{% for project in this.children.filter(F.type != 'house') %}
+  <li>{{ project.name }}</li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/expression/or/index.html b/docs/api/db/expression/or/index.html new file mode 100644 index 00000000..a6d691a8 --- /dev/null +++ b/docs/api/db/expression/or/index.html @@ -0,0 +1,338 @@ + + + + + + + + + + or | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

or (other)

+ + + + + +

This evaluates to true if either the expression on the left or the +expression on the right are true. This is one of the few operators that +differs between Python and templates. In templates you have to use the +or method whereas in Python have to use the | operator.

+

Template Example

<h3>Hotels or Apartments</h3>
+<ul>
+{% for item in this.children.filter(
+    (F.type == 'hotel').or(F.type == 'apartment')) %}
+  <li>{{ item.name }} ({{ item.type}})</li>
+{% endfor %}
+</ul>
+
+

Python Example

def get_hotels_or_apartments(page):
+    return page.children.filter(
+        (F.type == 'hotel') | (F.type == 'apartment'))
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/expression/startswith-cs/index.html b/docs/api/db/expression/startswith-cs/index.html new file mode 100644 index 00000000..dc2cd986 --- /dev/null +++ b/docs/api/db/expression/startswith-cs/index.html @@ -0,0 +1,331 @@ + + + + + + + + + + startswith_cs | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

startswith_cs (other)

+ + + + + +

This evaluates to true if the string +on the left side starts with the string on the right side. This method +operates in a case-sensitive manner. For the case-insensitive method +see startswith.

+

Example

<h1>A</h1>
+<ul>
+{% for item in this.children.filter(F.name.startswith_cs('A')) %}
+  <li>{{ item.name }}</li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/expression/startswith/index.html b/docs/api/db/expression/startswith/index.html new file mode 100644 index 00000000..194139f7 --- /dev/null +++ b/docs/api/db/expression/startswith/index.html @@ -0,0 +1,331 @@ + + + + + + + + + + startswith | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

startswith (other)

+ + + + + +

This evaluates to true if the string +on the left side starts with the string on the right side. This method +operates in a case-insensitive manner. For the case-sensitive method +see startswith_cs.

+

Example

<h1>A</h1>
+<ul>
+{% for item in this.children.filter(F.name.startswith('a')) %}
+  <li>{{ item.name }}</li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/f/index.html b/docs/api/db/f/index.html new file mode 100644 index 00000000..9b2dbe78 --- /dev/null +++ b/docs/api/db/f/index.html @@ -0,0 +1,290 @@ + + + + + + + + + + F | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

lektor.db.F

+ + + +
    + + +
  • Template variable: F
  • + + +
+ +

When filtering a Query it's often necessary to refer to a +field of an arbitrary record. This can be achieved with the F object. Any +attribute of it refers to a field in the record. To make this clearer, have a +look at the example below.

+

Accessing an attributes creates an Expression.

+

Example

<ul>
+{% for item in this.children.filter(F.status == 'published') %}
+  <li>{{ item.title }}</li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/get-alts/index.html b/docs/api/db/get-alts/index.html new file mode 100644 index 00000000..2adb05f1 --- /dev/null +++ b/docs/api/db/get-alts/index.html @@ -0,0 +1,293 @@ + + + + + + + + + + get_alts | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

lektor.db.get_alts (source=None, fallback=False)

+ + + +
    + + + +
  • New in Lektor Version 2.0
  • + +
+ +

Given a source this function returns the list of all Alternatives that the source exists as. It does not include +fallbacks unless fallback=True is passed. If no source is provided all +configured alts are returned. If alts are not configured at all, the return +value is an empty list.

+

This returns only the list of alt short IDs. Access to the configured name +of the alt within the project config is not available. Databags should be +used to provide alts with a humand readable title.

+

Example

<p>Other languages:
+<ul>
+{% for alt in get_alts(this) %}
+  <li><a href="{{ '.'|url(alt=alt) }}">{{ alt|title }}</a></li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/index.html b/docs/api/db/index.html new file mode 100644 index 00000000..cb46cab7 --- /dev/null +++ b/docs/api/db/index.html @@ -0,0 +1,394 @@ + + + + + + + + + + Database | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

Database

+ + + +
    + + + +
+ +

While Lektor does not have a real traditional SQL database, it has a tree +based data layer which is internally called the database. It's a very +powerful tool for building websites and is accessible from plugin API, +the shell command as well as from within the templates.

+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/obj/alt/index.html b/docs/api/db/obj/alt/index.html new file mode 100644 index 00000000..d2fadf6a --- /dev/null +++ b/docs/api/db/obj/alt/index.html @@ -0,0 +1,321 @@ + + + + + + + + + + alt | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

alt

+ + + + + +

For most source records there will be an associated alt. This attribute points to it. If the content +is not associated with an alt this can be None.

+

Example

<!-- generated from alt {{ this.alt }} -->
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/obj/index.html b/docs/api/db/obj/index.html new file mode 100644 index 00000000..f89cd754 --- /dev/null +++ b/docs/api/db/obj/index.html @@ -0,0 +1,505 @@ + + + + + + + + + + SourceObject | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

lektor.db.SourceObject

+ + + +
    + + + +
+ +

Source objects is the common interface for all things that come out of the +database. There are two types of source objects:

+
    +
  • Records which are pages and attachments from the +contents/ folder.
  • +
  • Assets which are files and directories from the +assets/ folder.
  • +
+

Whatever object you have in hand that comes from the database, they will +at least provide a minimal useful set of API methods and properties.

+

Plugins can subclass source objects to come up with their own source +objects if needed. In addition to that there is a special source object +called the VirtualSourceObject which is more useful for plugin usage.

+

Virtual Source Objects

Most plugins will not have source objects that actually originate on the +file system. This means that their "source" is entirely virtual. Because +this is a very common situation there is a base class, the +VirtualSourceObject which plugins can subclass. The constructor takes one +argument which is the source record the virtual source lives below. Virtual +sources are separated from the records they belong to with an at sign (@) +in the path. The part after the at sign is called the “virtual path”.

+

For instance in the below example the canonical path for the object would be +the record's path + @source. So if the record was /hello then the +path would be /hello@source. The true base record it belongs to can be +referenced from the record property.

+
from lektor.sourceobj import VirtualSourceObject
+from lektor.utils import build_url
+
+class Source(VirtualSourceObject):
+
+    @property
+    def path(self):
+        return self.record.path + '@source'
+
+    @property
+    def source_content(self):
+        with open(self.record.source_filename) as f:
+            return f.read().decode('utf-8')
+
+    @property
+    def url_path(self):
+        return build_url([self.record.url_path, 'source.txt'])
+
+

For more information see add-build-program as well as +virtualpathresolver.

+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/obj/is-child-of/index.html b/docs/api/db/obj/is-child-of/index.html new file mode 100644 index 00000000..b6b8225e --- /dev/null +++ b/docs/api/db/obj/is-child-of/index.html @@ -0,0 +1,325 @@ + + + + + + + + + + is_child_of | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

is_child_of (path, strict=False)

+ + + + + +

This method is a convenient way to check if a page is a child of another +page or not. The default behavior is to consider a page to be a child of +itself as this is more convenient in most situations but this can be +changed with the strict parameter. This method is particularly useful +when building a navigation.

+

Example

<a href="{{ '/projects'|url }}"{% if this.is_child_of('/projects')
+  %} class="active"{% endif %}>Projects</a>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/obj/is-discoverable/index.html b/docs/api/db/obj/is-discoverable/index.html new file mode 100644 index 00000000..92ba2915 --- /dev/null +++ b/docs/api/db/obj/is-discoverable/index.html @@ -0,0 +1,335 @@ + + + + + + + + + + is_discoverable | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

is_discoverable

+ + + +
    + +
  • Property of SourceObject
  • + + + +
  • New in Lektor Version 2.0
  • + +
+ +

Records can be discoverable or non discoverable. This is controlled by the +_discoverable system field which defaults to yes. This property can quickly +check if a record is considered non-discoverable by Lektor or not. In +particular a hidden record is also considered undiscoverable.

+

Undiscoverable records can be queried and final pages will be built but they +are exempt from queries of the record. This is useful for pages that should +be built but not show up yet on overview pages. For instance this can be used +to implement drafts of blog posts or similar things.

+

This property is implemented on the level of source objects to make it +possible to use this API in all cases. The default implementation of +source objects will always return true for discoverability checks.

+

Example

{% set downloads = site.get('/downloads') %}
+{% if downloads.is_discoverable %}
+  <p><a href="{{ downloads|url }}">Go to downloads</a>
+{% endif %}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/obj/is-hidden/index.html b/docs/api/db/obj/is-hidden/index.html new file mode 100644 index 00000000..d9396641 --- /dev/null +++ b/docs/api/db/obj/is-hidden/index.html @@ -0,0 +1,332 @@ + + + + + + + + + + is_hidden | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

is_hidden

+ + + + + +

Records can be hidden by setting the default _hidden system field to +yes. However records also get hidden automatically if any of their parents +are hidden. This property can quickly check if a record is considered hidden +by Lektor or not.

+

Hidden records can be queried but final pages will not be built. This is +useful for pages that should only exist for assisting other pages. For +instance hidden pages can be used to store configuration values.

+

This property is implemented on the level of source objects to make it +possible to use this API in all cases though the default implementation for +source objects is that they are always visible.

+

Example

{% set downloads = site.get('/downloads') %}
+{% if downloads.is_hidden %}
+  <p>Downloads are currently unavailable
+{% endif %}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/obj/is-undiscoverable/index.html b/docs/api/db/obj/is-undiscoverable/index.html new file mode 100644 index 00000000..dedbc220 --- /dev/null +++ b/docs/api/db/obj/is-undiscoverable/index.html @@ -0,0 +1,313 @@ + + + + + + + + + + is_undiscoverable | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

is_undiscoverable

+ + + +
    + +
  • Property of SourceObject
  • + + + +
  • New in Lektor Version 2.0
  • + +
+ +

This works like is_discoverable but the other +way around. It just exists for consistency and to make checks look a little +bit nicer in some places.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/obj/is-visible/index.html b/docs/api/db/obj/is-visible/index.html new file mode 100644 index 00000000..fca4c4e5 --- /dev/null +++ b/docs/api/db/obj/is-visible/index.html @@ -0,0 +1,323 @@ + + + + + + + + + + is_visible | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

is_visible

+ + + + + +

This is exactly the opposite of is_hidden.

+

Example

{% set downloads = site.get('/downloads') %}
+{% if downloads.is_visible %}
+  <p><a href="{{ downloads|url }}">go to downloads</a>
+{% endif %}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/obj/parent/index.html b/docs/api/db/obj/parent/index.html new file mode 100644 index 00000000..d2697754 --- /dev/null +++ b/docs/api/db/obj/parent/index.html @@ -0,0 +1,323 @@ + + + + + + + + + + parent | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

parent

+ + + + + +

For most source objects it's possible to discover their parents through +this property. It's not a requirement that this property is implemented but +most will have it. In particular it's useful for virtual source objects +where this property can be used to discover the associated parent object.

+

Example

<p>My parent is: {{ this.parent.path }}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/obj/path/index.html b/docs/api/db/obj/path/index.html new file mode 100644 index 00000000..d9b26423 --- /dev/null +++ b/docs/api/db/obj/path/index.html @@ -0,0 +1,312 @@ + + + + + + + + + + path | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

path

+ + + + + +

For source objects that have a file system representation this resolves to +the path that can be used to uniquely query the object via the database.

+

For some source objects (like assets or source objects from plugins) the path +will be None as the object cannot be queried (it's virtual).

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/obj/record/index.html b/docs/api/db/obj/record/index.html new file mode 100644 index 00000000..ac0db28e --- /dev/null +++ b/docs/api/db/obj/record/index.html @@ -0,0 +1,332 @@ + + + + + + + + + + record | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

record

+ + + +
    + +
  • Property of SourceObject
  • + + + +
  • New in Lektor Version 2.0
  • + +
+ +

Most records (other than the root) have a parent. This as +a concept generally makes in most situations. However when virtual sources +come into play the parent often just refers to another virtual source but not +the root record they all belong to.

+

This property for the most part refers back to the object itself. However +for virtual sources this refers back to the record that was associated with +the virtual source. Most of the time this matches parent but for nested +source objects it's useful to be able to refer back to the base in all cases +without having to walk up the parents.

+

Example

{% if this != this.record %}
+  <a href="{{ this.record|url }}">go back to overview</a>
+{% endif %}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/obj/source-filename/index.html b/docs/api/db/obj/source-filename/index.html new file mode 100644 index 00000000..e3993be6 --- /dev/null +++ b/docs/api/db/obj/source-filename/index.html @@ -0,0 +1,325 @@ + + + + + + + + + + source_filename | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

source_filename

+ + + + + +

This returns the primary source filename of the source object. So for +instance if this is an asset it will be the path to it, if it is a record +it will be the path to the lektor contents file. The path is relative +to the project folder.

+

Example

<p>
+  Generated from {{ this.source_filename }}
+</p>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/obj/url-path/index.html b/docs/api/db/obj/url-path/index.html new file mode 100644 index 00000000..0d0de39c --- /dev/null +++ b/docs/api/db/obj/url-path/index.html @@ -0,0 +1,311 @@ + + + + + + + + + + url_path | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

url_path

+ + + + + +

This is the absolute URL path to the page where the source object can be +reached when rendered. Typically the url +filter or the url_to method would be used.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/obj/url-to/index.html b/docs/api/db/obj/url-to/index.html new file mode 100644 index 00000000..6c02d7d4 --- /dev/null +++ b/docs/api/db/obj/url-to/index.html @@ -0,0 +1,331 @@ + + + + + + + + + + url_to | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

url_to (path, alt=None, absolute=None, external=None)

+ + + + + +

Calculates the URL from the current source object to the given other source +object. Alternatively a path can also be provided instead of a source object. +If the path starts with a leading bang (!) then no resolving is performed. +If no alt is provided the alt of the page is used.

+

This is what the |url filter uses internally to generate URLs.

+

In addition to that absolute can enforce the URL to be absolute instead of +relative to the current page and external can be used to also add the +domain part to the URL (if configured). The default behavior is to use the +configured URL style (which is relative) unless absolute or external were +explicitly provided. For more information read about this in the +Project Configuration.

+

Example

{% set downloads = site.get('/downloads') %}
+Path from downloads to here: {{ downloads.url_to(this) }}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/pad/databags/index.html b/docs/api/db/pad/databags/index.html new file mode 100644 index 00000000..f170baeb --- /dev/null +++ b/docs/api/db/pad/databags/index.html @@ -0,0 +1,291 @@ + + + + + + + + + + databags | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

databags

+ + + +
    + +
  • Property of Pad
  • + + + +
+ +

Through this attribute you can access the stored databags.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/pad/get-root/index.html b/docs/api/db/pad/get-root/index.html new file mode 100644 index 00000000..64c605aa --- /dev/null +++ b/docs/api/db/pad/get-root/index.html @@ -0,0 +1,306 @@ + + + + + + + + + + get_root | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

get_root (alt='_primary')

+ + + +
    + +
  • Method of Pad
  • + + + +
+ +

The tree only has one root record but it can come in different +Alternatives. This method can be used +to target the root page of a specific one. If no alt is provided, then the +primary alt is loaded.

+

Example

{% set root = site.get_root(alt='de') %}
+<a href="{{ root|url }}">Go to German Page</a>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/pad/get/index.html b/docs/api/db/pad/get/index.html new file mode 100644 index 00000000..827251e3 --- /dev/null +++ b/docs/api/db/pad/get/index.html @@ -0,0 +1,324 @@ + + + + + + + + + + get | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

get (id, alt='_primary', page_num=None)

+ + + +
    + +
  • Method of Pad
  • + + + +
+ +

This can look up a single Record and return it. In templates this method +is particularly useful when having to work with other pages that are well +known to the system but some information should be pulled from. Note that +this loads by default the "primary" Alternative.

+

The path needs to be absolute with folder separated by slashes.

+

The default behavior is to load the unpaginated version of a record. If you +want to select a specific page for pagination, then you need to pass +page_num with a valid page number or you use the virtual path (@1 for the +first page for instance).

+

Examples

This is a simple example that shows how to use the method in a template:

+
{% set root = site.get('/') %}
+<title>{{ this.title }} | {{ root.title }}</title>
+
+

Here another example that loads the current page but in another language:

+
{% set other_lang = site.get(this._path, alt='ru') %}
+<p>This page in Russian: {{ other_lang.title }}
+
+

Virtual Paths

This method can also be used to look up virtual paths. For instance to fetch a specific version of a +pagination you can use a virtual path instead of using the page_num +parameter:

+
>>> pad.get('/blog@3')
+<Page model=u'blog' path='/blog' page_num=3>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/pad/index.html b/docs/api/db/pad/index.html new file mode 100644 index 00000000..7d3d6ac8 --- /dev/null +++ b/docs/api/db/pad/index.html @@ -0,0 +1,416 @@ + + + + + + + + + + Pad | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

lektor.db.Pad

+ + + +
    + + +
  • Template variable: site
  • + + +
+ +

The Pad is a helper class that provides basic access to querying the +database. Inside templates an instance of it is available under the +site variable automatically.

+

To understand what the pad does you need to consider what it is. The +pad is similar to a connection in a regular database. Whenever you +load a record it's temporarily cached on the pad. So unless you overflow +the cache, loading the object a second time will most likely return an +already loaded instance from the pad. This also means that the pad +is not threadsafe. So if you want (for whatever reason) use multiple +threads you have to create a separate pad for each thread.

+

This typically only comes up in the context of plugins or more complex +command line scripts.

+

Template Usage

A ready-configured pad is always available under the site name which +allows you to easily discover other pages. Here is a basic example of +how to do this through the get method:

+
{% set root = site.get('/') %}
+<title>{{ this.title }} | {{ root.title }}</title>
+
+

Plugin Usage

Within plugins it's typically not a good idea to construct a new Pad. +Instead you can get access to the current pad from the active context:

+
from lektor.context import get_ctx
+
+ctx = get_ctx()
+if ctx is not None:
+    pad = get_ctx().pad
+
+

Note that you can only get access to a pad if a context is available. This +will not be the case when the plugin is currently being initialized for +instance.

+

Manual Pad Creation

If you want to work with the database from a script, you can create a +pad from the Environment with the help of +the new_pad method:

+
from lektor.project import Project
+
+project = Project.discover()
+env = project.make_env()
+pad = env.new_pad()
+root_record = pad.root
+
+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/pad/query/index.html b/docs/api/db/pad/query/index.html new file mode 100644 index 00000000..483121ef --- /dev/null +++ b/docs/api/db/pad/query/index.html @@ -0,0 +1,309 @@ + + + + + + + + + + query | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

query (path=None, alt='_primary')

+ + + +
    + +
  • Method of Pad
  • + + + +
+ +

This is one of the many ways to create a Query object in +Lektor. It creates a query at a specific path and alt. This is an +alternative to accessing the children of the root record +and will also include hidden pages.

+

Example

<ul>
+{% for project in site.query('/projects') %}
+  <li>{{ project.name }}: {{ project.year }}</li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/pad/resolve-url-path/index.html b/docs/api/db/pad/resolve-url-path/index.html new file mode 100644 index 00000000..73c687cf --- /dev/null +++ b/docs/api/db/pad/resolve-url-path/index.html @@ -0,0 +1,316 @@ + + + + + + + + + + resolve_url_path | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

resolve_url_path (url_path, include_invisible=False, include_assets=False, alt_fallback=True)

+ + + +
    + +
  • Method of Pad
  • + + + +
+ +

This method is used by Lektor to resolve a URL path to a +Source Object. This is not particularly useful to use +within templates but it's very useful in the shell to debug what's +happening in Lektor.

+

This can resolve into any source object, so not just records. If you only +want to resolve to records you can pass include_assets=False and only +records will be included.

+

Examples

Shows an example of how to resolve paths into assets:

+
>>> pad.resolve_url_path('/docs/api')
+<Page model=u'doc-page' path=u'/docs/api'>
+>>> pad.resolve_url_path('/header.jpg')
+<Image model='none' path=u'/header.jpg'>
+>>> pad.resolve_url_path('/static')
+<Directory '/static'>
+>>> pad.resolve_url_path('/missing-page') is None
+True
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/pad/root/index.html b/docs/api/db/pad/root/index.html new file mode 100644 index 00000000..537aa192 --- /dev/null +++ b/docs/api/db/pad/root/index.html @@ -0,0 +1,303 @@ + + + + + + + + + + root | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

root

+ + + +
    + +
  • Property of Pad
  • + + + +
+ +

This works exactly like get_root but always returns +the primary alternative and is implemented as a property.

+

Example

<a href="{{ site.root|url }}">Go to Index</a>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/query/all/index.html b/docs/api/db/query/all/index.html new file mode 100644 index 00000000..4f7b00ab --- /dev/null +++ b/docs/api/db/query/all/index.html @@ -0,0 +1,333 @@ + + + + + + + + + + all | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

all ()

+ + + +
    + +
  • Method of Query
  • + + + +
+ +

This method returns all matching Records that match +the query as a list. In many cases just iterating over the query achieve +the same result, but if you want an actual list this method comes in +handy.

+

Example

{% items = site.query('/projects').include_hidden(false).all() %}
+{% if items %}
+  <ul>
+  {% for item in items %}
+    <li>{{ item.name }}</li>
+  {% endfor %}
+  </ul>
+{% endif %}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/query/count/index.html b/docs/api/db/query/count/index.html new file mode 100644 index 00000000..1acd9c64 --- /dev/null +++ b/docs/api/db/query/count/index.html @@ -0,0 +1,324 @@ + + + + + + + + + + count | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

count ()

+ + + +
    + +
  • Method of Query
  • + + + +
+ +

This is a simple way to count the total number of items a query matches.

+

Example

{% set project_count = site.query('/projects').count() %}
+<p>We built {{ project_count }} projects.
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/query/distinct/index.html b/docs/api/db/query/distinct/index.html new file mode 100644 index 00000000..917d7ae4 --- /dev/null +++ b/docs/api/db/query/distinct/index.html @@ -0,0 +1,341 @@ + + + + + + + + + + distinct | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

distinct (field_name)

+ + + +
    + +
  • Method of Query
  • + + + +
  • New in Lektor Version 2.0
  • + +
+ +

Returns a set with all values for field_name of all +Records in this query.

+

Example

If your blog posts have a field called tags:

+
# blog-post.ini
+
+[field.tags]
+name = Tags
+type = strings
+
+

You can display all your blog posts' tags with:

+
{% set tags = site.query('/blog').distinct('tags') %}
+{% if tags %}
+  <ul>
+    {% for tag in tags|sort %}
+      <li>{{ tag }}</li>
+    {% endfor %}
+  </ul>
+{% endif %}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/query/filter/index.html b/docs/api/db/query/filter/index.html new file mode 100644 index 00000000..a406b5ea --- /dev/null +++ b/docs/api/db/query/filter/index.html @@ -0,0 +1,332 @@ + + + + + + + + + + filter | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

filter (expr)

+ + + +
    + +
  • Method of Query
  • + + + +
+ +

This filters a query further down by an Expression. +Most expressions involve filtering by fields through F +which allows you to perform comparisons with values that fields have.

+

Multiple filter calls can be chained as an alternative to using an and +expression.

+

Example

Here a basic example of how to filter something in a template:

+
<ul>
+{% for item in this.children.filter(F.status == 'published') %}
+  <li>{{ item.title }}</li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/query/first/index.html b/docs/api/db/query/first/index.html new file mode 100644 index 00000000..fbdfdd4f --- /dev/null +++ b/docs/api/db/query/first/index.html @@ -0,0 +1,328 @@ + + + + + + + + + + first | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

first ()

+ + + +
    + +
  • Method of Query
  • + + + +
+ +

This method returns the first Record that matches the +query. If no such record can be produced, None is returned.

+

Example

{% set first_visible = this.children.first() %}
+{% if first_visible %}
+  <h2>Explore More ...</h2>
+  <p>{{ first_visible.title }}
+{% endif %}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/query/get/index.html b/docs/api/db/query/get/index.html new file mode 100644 index 00000000..04513423 --- /dev/null +++ b/docs/api/db/query/get/index.html @@ -0,0 +1,328 @@ + + + + + + + + + + get | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

get (id, page_num=...)

+ + + +
    + +
  • Method of Query
  • + + + +
+ +

This method mostly exists for consistency. It's an alternative to using +the get method of the pad but respects the currently +applied filtering. If page_num is provided it overrides the currently +requested page number from the query for pagination.

+

Example

{% set p1 = this.children.get('project-1') %}
+<h2>{{ p1.name }}</h2>
+<p>Our favorite!
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/query/include-hidden/index.html b/docs/api/db/query/include-hidden/index.html new file mode 100644 index 00000000..4419114f --- /dev/null +++ b/docs/api/db/query/include-hidden/index.html @@ -0,0 +1,334 @@ + + + + + + + + + + include_hidden | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

include_hidden (value)

+ + + +
    + +
  • Method of Query
  • + + + +
+ +

This controls how the query should behave with regards to hidden records. +A query created from the children attribute of +a record will not include hidden records (or undiscoverable) by default. The +opposite is true for queries created from the query +method of the pad.

+

The parameter can be set to True to include hidden or False to exclude +hidden records.

+

Example

Here a basic example of how to filter something in a template:

+
<ul>
+{% for item in this.children.include_hidden(true) %}
+  <li>{{ item.title }}{% if item.is_hidden %} (hidden){% endif %}</li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/query/include-undiscoverable/index.html b/docs/api/db/query/include-undiscoverable/index.html new file mode 100644 index 00000000..23a7b742 --- /dev/null +++ b/docs/api/db/query/include-undiscoverable/index.html @@ -0,0 +1,335 @@ + + + + + + + + + + include_undiscoverable | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

include_undiscoverable (value)

+ + + +
    + +
  • Method of Query
  • + + + +
  • New in Lektor Version 2.0
  • + +
+ +

This controls how the query should behave with regards to undiscoverable +records. A query (either created from the children +attribute or the query method of the pad) will not +include undiscoverable records by default.

+

If undiscoverable records should included this method needs to be used. +Set it to True to include hidden or False to exclude them (default).

+

Example

Here a basic example of how to filter something in a template:

+
<ul>
+{% for item in this.children.include_undiscoverable(true) %}
+  <li>{{ item.title }}</li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/query/index.html b/docs/api/db/query/index.html new file mode 100644 index 00000000..0fa3ccfc --- /dev/null +++ b/docs/api/db/query/index.html @@ -0,0 +1,490 @@ + + + + + + + + + + Query | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

lektor.db.Query

+ + + +
    + + + +
+ +

The query class is used to filter queries to the database. It's available +through either the Pad or through things like the +children property of records.

+

Most operations on a query object return another one which will return a +more filtered result.

+

Example

Here a basic example of how to filter something in a template:

+
<ul>
+{% for item in this.children.filter(F.status == 'published') %}
+  <li>{{ item.title }}</li>
+{% endfor %}
+</ul>
+
+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/query/limit/index.html b/docs/api/db/query/limit/index.html new file mode 100644 index 00000000..96a12da9 --- /dev/null +++ b/docs/api/db/query/limit/index.html @@ -0,0 +1,329 @@ + + + + + + + + + + limit | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

limit (offset)

+ + + +
    + +
  • Method of Query
  • + + + +
+ +

The offset method can be used to limit the return value to a certain number +of matching records.

+

Example

<h3>Our Top 3</h3>
+<ul>
+{% for item in this.children.order_by('-rating').limit(3) %}
+  <li>{{ item.title }}</li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/query/offset/index.html b/docs/api/db/query/offset/index.html new file mode 100644 index 00000000..324f635a --- /dev/null +++ b/docs/api/db/query/offset/index.html @@ -0,0 +1,327 @@ + + + + + + + + + + offset | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

offset (offset)

+ + + +
    + +
  • Method of Query
  • + + + +
+ +

The offset method can be used to skip a certain number of items. Typically +this is not useful as pagination comes built-in, but it can be helpful in +some manual scenarios when working with data from the shell.

+

This is typically combined with limit.

+

Example

>>> pad.query('/projects').limit(5).offset(10).all()
+[...]
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/query/order-by/index.html b/docs/api/db/query/order-by/index.html new file mode 100644 index 00000000..eb905c46 --- /dev/null +++ b/docs/api/db/query/order-by/index.html @@ -0,0 +1,334 @@ + + + + + + + + + + order_by | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

order_by (*fields)

+ + + +
    + +
  • Method of Query
  • + + + +
+ +

This is a handy way to change the order of the items returned. The default +order is defined in the model config but can be overridden this way. The +method accepts an arbitrary number of strings, each of which refers to the +name of a field. If a string is prefixed with a minus sign (-) then the +order is reversed.

+

If two records have the same value for a field, then the ordering is defined on +the next argument given. So if you order by ('year', 'name') it will first +order by year and within a year it will order by name.

+

Example

<ul>
+{% for project in this.children.order_by('-year', 'name') %}
+  <li>{{ project.year }}: {{ project.name }}</li>
+{% endif %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/query/request-page/index.html b/docs/api/db/query/request-page/index.html new file mode 100644 index 00000000..363fd60b --- /dev/null +++ b/docs/api/db/query/request-page/index.html @@ -0,0 +1,336 @@ + + + + + + + + + + request_page | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

request_page (page_num)

+ + + +
    + +
  • Method of Query
  • + + + +
+ +

When pagination is enabled it's often quite useful to select a specific +page of a record that is paginated. When dealing with child records the +default behavior is to return an unpaginated version of the record. With +this parameter it's possible to change this. The parameter is the number +of the page to access.

+

Truth be told: this method exists mostly for consistency and less because +there is a good reason to use it.

+

Example

<ul>
+{% for child in this.children.request_page(1) %}
+  <li>
+    Items on the first page of {{ child.title }}:
+    {{ child.pagination.items.count() }}
+  </li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/query/self/index.html b/docs/api/db/query/self/index.html new file mode 100644 index 00000000..58bbdecf --- /dev/null +++ b/docs/api/db/query/self/index.html @@ -0,0 +1,327 @@ + + + + + + + + + + self | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

self

+ + + +
    + +
  • Property of Query
  • + + + +
+ +

Because a query object filters "downwards" there this is a way access the item +at the level of the query object. It's particularly useful for debugging +in the shell:

+

Example

>>> root = pad.root
+>>> root.children.query.self == root
+True
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/record/attachments/index.html b/docs/api/db/record/attachments/index.html new file mode 100644 index 00000000..6e58d821 --- /dev/null +++ b/docs/api/db/record/attachments/index.html @@ -0,0 +1,335 @@ + + + + + + + + + + attachments | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

attachments

+ + + +
    + +
  • Property of Record
  • + + + +
+ +

This returns a Query to all attachments of a page. This +query can be further filtered to access specific types of attachments if +needed.

+

Example

<div class="images">
+{% for image in this.attachments.images %}
+  <img src="{{ image.thumbnail(240) }}">
+{% endfor %}
+</div>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/record/children/index.html b/docs/api/db/record/children/index.html new file mode 100644 index 00000000..5dec5fe9 --- /dev/null +++ b/docs/api/db/record/children/index.html @@ -0,0 +1,344 @@ + + + + + + + + + + children | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

children

+ + + +
    + +
  • Property of Record
  • + + + +
+ +

Because of Lektor's tree based nature almost all records can have children +below them. The children attribute provides a convenient way to access +those. It returns a Query object that can be used to +further filter down children.

+

Attachments of pages are not considered children even though they technically +are. These are accessible via the attachments +property instead which works largely the same.

+

If a record is an attachment neither children nor attachments are +available.

+

What's important to know about children is that the default query will +exclude hidden children. This is different from creating a query object +via the query method of the pad.

+

Example

<ul>
+{% for child in this.children %}
+  <li>{{ child.title }}</li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/record/contents/index.html b/docs/api/db/record/contents/index.html new file mode 100644 index 00000000..253a9ef2 --- /dev/null +++ b/docs/api/db/record/contents/index.html @@ -0,0 +1,396 @@ + + + + + + + + + + contents | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

contents

+ + + +
    + +
  • Property of Record
  • + + + +
+ +

This property provides access to the raw contents of a record. For attachments +this gives access to the contents of the actual attachments, for other records +it gives access to the record's contents.lr file.

+

It provides many useful attributes and methods to do something with the +contents of that file:

+

Properties

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyDescription
sha1The SHA1 hash of the contents as hexadecimal string
md5The MD5 hash of the contents as hexadecimal string
integrityA subresource integritry string (read about it)
mimetypeThe guessed mimetype of the object
bytesThe number of bytes for the contents as integer
+

Methods

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
MethodDescription
as_data_url()Returns a data URL for the contents. Optionally accepts a different mimetype than the guesed one.
as_text()Returns the contents of the file as text. UTF-8 is assumed.
as_bytes()Returns the contents of the file as bytes.
as_base64()Returns the contents of the file as base64 encoded bytes.
open()Opens the file for editing. Accepts r or rb as modes and a second argument which is the file encoding.
+

Example

Here are some ideas of what you can do with it:

+
<img src="{{ image.contents.as_data_url() }}" alt="">
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/record/exif/index.html b/docs/api/db/record/exif/index.html new file mode 100644 index 00000000..314f4cf9 --- /dev/null +++ b/docs/api/db/record/exif/index.html @@ -0,0 +1,446 @@ + + + + + + + + + + exif | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

exif

+ + + +
    + +
  • Property of Record
  • + + + +
+ +

This property gives access to some of the EXIF information that might be +embedded in the picture. Not all pictures might contain that information +and some information might be unavailable. In those cases the attribute +will be null.

+

In addition the to_dict() method can be used to convert the EXIF data +into a dictionary that can be dumped to JSON for instance.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
artistThe name of the photographer
copyrightThe embedded copyright message
created_atThe timestamp of the image
cameraCombined name of camera make and model
camera_makeThe name of the camera manufacturer
camera_modelThe name of the camera model
lensCombined name of the lense make and model
lens_makeThe name of the lense manufacturer
lens_modelThe name of the lense model
apertureThe aperture value as floating point number
f_numThe F-number as actual number
fThe f-number as string (ƒ/2.2 for instance)
isoThe ISO speed as integer
exposure_timeThe exposure time as string
shutter_speedThe shutter speed as string
focal_lengthThe focal length as string
focal_length_35mmThe focal length as string in the 35mm equivalent
flash_infoInformation text about the flash usage
locationLongitude and latitude as floating point tuple.
latitudeThe longitude as floating point value.
longitudeThe longitude as floating point value.
altitudeThe altitude in meters as floating point value.
documentnameThe image document name as a string.
descriptionThe image description as a string.
+

Example

{% if image.exif.location %}
+  <h2>Picture Location</h2>
+  <iframe width="600" height="450" frameborder="0" style="border:0"
+    src="https://www.google.com/maps/embed/v1/place?q={{
+    (image.exif.latitude ~ ', ' ~
+     image.exif.longitude)|urlencode }}&key=..."
+    allowfullscreen></iframe>
+{% endif %}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/record/format/index.html b/docs/api/db/record/format/index.html new file mode 100644 index 00000000..c2fe970c --- /dev/null +++ b/docs/api/db/record/format/index.html @@ -0,0 +1,332 @@ + + + + + + + + + + format | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

format

+ + + +
    + +
  • Property of Record
  • + + + +
+ +

This returns the format of the attachment as a string. This is currently +only implemented for attachments that are images.

+

Example

{% for image in this.attachments.images %}
+  <p>{{ image._id }}: {{ image.format }}
+{% endfor %}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/record/get_siblings/index.html b/docs/api/db/record/get_siblings/index.html new file mode 100644 index 00000000..efb5a9c8 --- /dev/null +++ b/docs/api/db/record/get_siblings/index.html @@ -0,0 +1,345 @@ + + + + + + + + + + get_siblings | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

get_siblings ()

+ + + +
    + +
  • Method of Record
  • + + + +
+ +

Get the previous and next record in this record's parent's list of children.

+

The returned object has attributes prev_page and next_page. +Each can be a Record or None.

+

If the parent record has pagination enabled, then use the pagination query to +filter and order the children. Otherwise, the parent's standard configuration +for children is used. +See the pagination guide and the +page order guide.

+

Example

{% set siblings = this.get_siblings() %}
+
+{% if siblings.prev_page %}
+  <a href="{{ siblings.prev_page|url }}">previous</a>
+{% endif %}
+
+{% if siblings.next_page %}
+  <a href="{{ siblings.next_page|url }}">next</a>
+{% endif %}
+
+

See also: has_prev and has_next.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/record/getitem/index.html b/docs/api/db/record/getitem/index.html new file mode 100644 index 00000000..3f201a79 --- /dev/null +++ b/docs/api/db/record/getitem/index.html @@ -0,0 +1,335 @@ + + + + + + + + + + [] | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

[]

+ + + +
    + +
  • Operator of Record
  • + + + +
+ +

The “get-item” operator is used to look up a field from a record. Within +templates attribute access automatically falls back to this operator which +is why you can typically access foo.bar instead of foo['bar'] unless a +conflict with a record property exists.

+

All available fields can be accessed this way (model defined fields as well +as system fields which are prefixed by an underscore).

+

Example

for child in this.children:
+    print('ID: %s' % child['_id'])
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/record/has_next/index.html b/docs/api/db/record/has_next/index.html new file mode 100644 index 00000000..ef9b9ef2 --- /dev/null +++ b/docs/api/db/record/has_next/index.html @@ -0,0 +1,339 @@ + + + + + + + + + + has_next | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

has_next ()

+ + + +
    + +
  • Method of Record
  • + + + +
+ +

True if there is a next record in the parent's list of children.

+

If the parent record has pagination enabled, then use the pagination query to +filter and order the children. Otherwise, the parent's standard configuration +for children is used. +See the pagination guide and the +page order guide.

+

Example

{% if this.has_next() %}
+  <a href="{{ this.get_siblings().next_page|url }}">next</a>
+{% else %}
+  <p>This is the last entry.
+{% endif %}
+
+

See also: has_prev and get_siblings.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/record/has_prev/index.html b/docs/api/db/record/has_prev/index.html new file mode 100644 index 00000000..593bab3e --- /dev/null +++ b/docs/api/db/record/has_prev/index.html @@ -0,0 +1,339 @@ + + + + + + + + + + has_prev | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

has_prev ()

+ + + +
    + +
  • Method of Record
  • + + + +
+ +

True if there is a previous record in the parent's list of children.

+

If the parent record has pagination enabled, then use the pagination query to +filter and order the children. Otherwise, the parent's standard configuration +for children is used. +See the pagination guide and the +page order guide.

+

Example

{% if this.has_prev() %}
+  <a href="{{ this.get_siblings().prev_page|url }}">previous</a>
+{% else %}
+  <p>This is the first entry.
+{% endif %}
+
+

See also: has_next and get_siblings.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/record/height/index.html b/docs/api/db/record/height/index.html new file mode 100644 index 00000000..438ce69d --- /dev/null +++ b/docs/api/db/record/height/index.html @@ -0,0 +1,335 @@ + + + + + + + + + + height | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

height

+ + + +
    + +
  • Property of Record
  • + + + +
+ +

If you are dealing with an attachment that is an image, this property becomes +available and indicates the height of the image in pixels if that information +is available.

+

Example

{% for image in this.attachments.images %}
+  <img src="{{ image|url }}"
+    height="{{ image.height }}"
+    height="{{ image.height }}">
+{% endfor %}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/record/index.html b/docs/api/db/record/index.html new file mode 100644 index 00000000..1b5de2b4 --- /dev/null +++ b/docs/api/db/record/index.html @@ -0,0 +1,522 @@ + + + + + + + + + + Record | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

lektor.db.Record

+ + + +
    + + + +
+ +

Records are Source Objects that come from the content/ +folder and correspond to Data Models. They provide +a wider range of functionality compared to a standard source object but +they also provide all the functionality a regular source object does.

+

In addition to the functionality here, they also expose all the configured +fields.

+

Accessing Data

Most of the time things will just work as you expect. If you access these +objects from templates they give access to their built-in attributes as well +as custom fields through the attribute syntax. If however a built-in +attribute overlaps with your custom field, you need to access the fields +with the subscript syntax ([]):

+
<p>Built-in Path: {{ obj.path }}
+<p>Path field: {{ obj['path'] }}
+
+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/record/is-attachment/index.html b/docs/api/db/record/is-attachment/index.html new file mode 100644 index 00000000..fbc58835 --- /dev/null +++ b/docs/api/db/record/is-attachment/index.html @@ -0,0 +1,335 @@ + + + + + + + + + + is_attachment | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

is_attachment

+ + + +
    + +
  • Property of Record
  • + + + +
+ +

This property indicates whether the record is a page or attachment. If it's +an attachment this will be true. Because some functionality only exists +on one type but not the other this can be useful in some utility code to +change the behavior.

+

Example

{% macro render_record_link(record) %}
+  <a href="{{ record|url }}">{{ record.record_label }}</a>
+  {% if record.is_attachment %} ({{ record._attachment_type }}){% endif %}
+{% endmacro %}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/record/pagination/index.html b/docs/api/db/record/pagination/index.html new file mode 100644 index 00000000..9b6ad225 --- /dev/null +++ b/docs/api/db/record/pagination/index.html @@ -0,0 +1,423 @@ + + + + + + + + + + pagination | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

pagination

+ + + +
    + +
  • Property of Record
  • + + + +
+ +

When pagination is enabled for a page, then pagination will return a +pagination controller that gives access to a query that is specific for the +actual page that was navigated to, instead of including all children as well +as information about the current page. In a nutshell: when pagination is +enabled, you should use pagination.items instead of children on an +overview page.

+

The following attributes exist on the pagination object:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeDescription
currentThe current record
prevThe record for the last page (might be None)
nextThe record for the next page (might be None)
totalThe total number of items across all pages
pagesThe total number of pages
pageThe number of current page
has_prevTrue if a previous page exists
has_nextTrue if a next page exists
itemsThe query that resolves to the children of the current page.
for_page()Returns the record for a different page.
+

The for_page() function accepts a page number and returns the record for +the other page. For more information also see the virtual path example +below.

+

Changed in Lektor 2.0: The for_page() method was added.

Item Query Example

Simple example that shows how to iterate over the items specific to a +page:

+
<ul>
+{% for child in this.pagination.items %}
+  <li>{{ child.title }}</li>
+{% endfor %}
+</ul>
+
+

Pagination Example

This example shows how to render a basic pagination with a previous and +next page link as well as the number of the current page:

+
<div class="pagination">
+  {% if this.pagination.has_prev %}
+    <a href="{{ this.pagination.prev_page|url }}">&laquo;</a>
+  {% else %}
+    <span class="disabled">&laquo;</span>
+  {% endif %}
+  — <strong>{{ this.pagination.page }}</strong> —
+  {% if this.pagination.has_next %}
+    <a href="{{ this.pagination.next_page|url }}">&raquo;</a>
+  {% else %}
+    <span class="disabled">&raquo;</span>
+  {% endif %}
+</div>
+
+

Virtual Paths

New in Lektor 2.0: virtual paths did not exist in earlier Lektor versions.

The pagination is implemented in a way where each page in the pagination is +a virtual path below the record itself. The value of the path is just the +number of the page. So for instance to link to the second page you can just +do this:

+
<a href="{{ '@2'|url }}">Go to Page 2</a>
+
+

Alternatively you can also use the for_path() function which returns the +entire pagination for a page:

+
<a href="{{ this.pagination.for_page(2)|url }}">Go to Page 2</a>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/record/record-label/index.html b/docs/api/db/record/record-label/index.html new file mode 100644 index 00000000..bae9db15 --- /dev/null +++ b/docs/api/db/record/record-label/index.html @@ -0,0 +1,337 @@ + + + + + + + + + + record_label | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

record_label

+ + + +
    + +
  • Property of Record
  • + + + +
+ +

Each record in Lektor has a configured Record label that is used by the +admin interface to show a human readable version of it. Typically this is +the title or something similar. This functionality can also be used outside +of the admin panel. This is particularly useful when rendering children of +a page that might use different independent models.

+

Example

<ul>
+{% for child in this.children %}
+  <li><a href="{{ child|url }}">{{ child.record_label }}</a></li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/record/thumbnail/index.html b/docs/api/db/record/thumbnail/index.html new file mode 100644 index 00000000..4020534f --- /dev/null +++ b/docs/api/db/record/thumbnail/index.html @@ -0,0 +1,362 @@ + + + + + + + + + + thumbnail | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

thumbnail (width=None, height=None, mode=None, upscale=None, quality=None)

+ + + +
    + +
  • Method of Record
  • + + + +
+ +

From Lektor 2.0 to 3.1.2 cropping was set with crop=True. This is now deprecated and instead crop is an available mode, which can be set as mode="crop".

This method is available on attachments that are images and can be used to +automatically generate a thumbnail. The return value is a thumbnail proxy +that can be either used directly or with the |url filter.

+

The outcome differs depending on the operation mode, which can be one of "fit" +(the default), "crop" or "stretch".

+

In "fit" mode, the thumbnail is scaled to fit into the rectangle of given +width and height. If either dimension is None, it will be computed to match +the other one accordingly.

+

In "crop" mode, width and height are both required. The image is scaled +to cover the given rectangle, center-aligned, and then cropped so that +anything outside those bounds gets trimmed.

+

In "stretch" mode, the image is resized precisely to the required dimensions, +so the original proportions are not preserved. Most of the time this is not +what you want.

+

By setting the upscale parameter to False you can prevent the images +from being scaled up if the resulting thumbnail would be larger than the original +image. In this case the original is returned instead. +(Note that in a future version this will be the default in "fit" mode.)

+

The quality parameter determines the compression of images where possible. If not passed the jpeg images get a default quality of 85 and png images get a default quality of 75.

+

It provides the following attributes:

+
    +
  • width: the thumbnail width in pixels.
  • +
  • height: the thumbnail height in pixels.
  • +
  • url_path the URL path of the thumbnail. This is absolute and needs to +be made relative with the |url filter.
  • +
+

Example

{% for image in this.attachments.images %}
+  <img src="{{ image.thumbnail(64)|url }}">
+{% endfor %}
+
+
{% for image in this.attachments.images %}
+  <img src="{{ image.thumbnail(height=64)|url }}">
+{% endfor %}
+
+
<img src="{{ image.thumbnail(1920, 1080, mode="crop", quality=40)|url }}">
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/record/width/index.html b/docs/api/db/record/width/index.html new file mode 100644 index 00000000..1835e481 --- /dev/null +++ b/docs/api/db/record/width/index.html @@ -0,0 +1,335 @@ + + + + + + + + + + width | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

width

+ + + +
    + +
  • Property of Record
  • + + + +
+ +

If you are dealing with an attachment that is an image, this property becomes +available and indicates the width of the image in pixels if that information +is available.

+

Example

{% for image in this.attachments.images %}
+  <img src="{{ image|url }}"
+    width="{{ image.width }}"
+    height="{{ image.height }}">
+{% endfor %}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/system-fields/alt/index.html b/docs/api/db/system-fields/alt/index.html new file mode 100644 index 00000000..8c36ebb7 --- /dev/null +++ b/docs/api/db/system-fields/alt/index.html @@ -0,0 +1,306 @@ + + + + + + + + + + _alt | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

_alt

+ + + +
    + + + +
+ +

This field points to the Alternative of +the page. This should be considered as an internal field that is exposed +through the alt source object property instead.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/system-fields/attachment-type/index.html b/docs/api/db/system-fields/attachment-type/index.html new file mode 100644 index 00000000..797e62aa --- /dev/null +++ b/docs/api/db/system-fields/attachment-type/index.html @@ -0,0 +1,309 @@ + + + + + + + + + + _attachment_type | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

_attachment_type

+ + + +
    + + + +
+ +

This indicates the type of the attachment, which is detected by file extension. +Currently only a small set of attachment types are detected, with the most +useful one being image.

+

This feature in many ways does not entirely work as you would expect +and should be taken as something that will improve in future versions.

Read more about attachments +in the content section

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/system-fields/discoverable/index.html b/docs/api/db/system-fields/discoverable/index.html new file mode 100644 index 00000000..20cd29a3 --- /dev/null +++ b/docs/api/db/system-fields/discoverable/index.html @@ -0,0 +1,314 @@ + + + + + + + + + + _discoverable | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

_discoverable

+ + + +
    + + + +
  • New in Lektor Version 2.0
  • + +
+ +

By default any non hidden page is returned from .children on iteration. This +field can be set to no to hide a page from such default queries. This +implicitly hides a page for most template operations but Lektor will still +build it. This for instance is very useful for draft blog posts. If a post is +set to not being discoverable it will be hidden from the blog index without +further custom template code, but someone who knows the URL can still find it.

+

This is also particularly useful to hide special pages such as sitemap.xml +which would otherwise cause problems because generic code might not expect +it.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/system-fields/gid/index.html b/docs/api/db/system-fields/gid/index.html new file mode 100644 index 00000000..294ece70 --- /dev/null +++ b/docs/api/db/system-fields/gid/index.html @@ -0,0 +1,320 @@ + + + + + + + + + + _gid | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

_gid

+ + + +
    + + + +
+ +

The _gid is the MD5 hashed version of the page's _path. This +is useful in situations where a stable ID is needed that follows a certain +format. For instance it can come in useful when a ID is needed for a DOM +element.

+

Example

<body class="page-{{ this._gid }}">
+...
+</body>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/system-fields/hidden/index.html b/docs/api/db/system-fields/hidden/index.html new file mode 100644 index 00000000..3e6fd630 --- /dev/null +++ b/docs/api/db/system-fields/hidden/index.html @@ -0,0 +1,311 @@ + + + + + + + + + + _hidden | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

_hidden

+ + + +
    + + + +
+ +

This field controls if Lektor should process the page into a build artifact. +By default each page is built into a build artifact (HTML page) and each +attachment is processed. This can be prevented by setting _hidden to yes.

+

This also automatically applies to all children of a page unless they +forcefully override this setting.

+

This is useful for more advanced setups like Single Page Applications.

+

Hidden pages are automatically also removed from the .children property +of records but stay available for querying via the pad.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/system-fields/id/index.html b/docs/api/db/system-fields/id/index.html new file mode 100644 index 00000000..34788f8d --- /dev/null +++ b/docs/api/db/system-fields/id/index.html @@ -0,0 +1,329 @@ + + + + + + + + + + _id | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

_id

+ + + +
    + + + +
+ +

Each record has an _id. This ID is basically a form of the filename. +Depending on if you are looking at an attachment or a page the rules are +slightly different.

+

For pages the ID is the name of the folder. So if you have a page called +docs/overview/contents.lr then _id is overview. If you have however +an attachment named docs/overview/screenshot.jpg the _id will be the +filename of the attachment: screenshot.jpg.

+

Note that IDs are not globally unique! There is also the _path which is +the entire path if the record.

+

The _id is automatically set and cannot be overridden.

+

Example

<ul class="nav">
+{% for item in site.query('/projects') %}
+  <li{% if item._id == this._id %} class="active"{%
+    endif %}>{{ item.name }}</li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/system-fields/index.html b/docs/api/db/system-fields/index.html new file mode 100644 index 00000000..d811bb7f --- /dev/null +++ b/docs/api/db/system-fields/index.html @@ -0,0 +1,445 @@ + + + + + + + + + + System Fields | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

System Fields

+ + + +
    + + + +
+ +

All records have a few system fields available in addition to the fields +defined by the data model. These fields are always there and control internal +behavior in Lektor. They are prefixed by an underscore to separate them +from the fields a model defines.

+

Many system fields are hidden from the admin panel but some can be changed +there (_template, _hidden, and a few others).

+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/system-fields/model/index.html b/docs/api/db/system-fields/model/index.html new file mode 100644 index 00000000..fdee8e66 --- /dev/null +++ b/docs/api/db/system-fields/model/index.html @@ -0,0 +1,322 @@ + + + + + + + + + + _model | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

_model

+ + + +
    + + + +
+ +

This field selects the model that should be used for non-system fields. In +many situations the model is picked automatically but for equally many +situations it needs to be selected manually.

+

This field is most useful for filtering when operating on mixed collections.

+

Example

<ul class="projects">
+{% for child in this.children.filter(F._model == 'project') %}
+  <li>{{ child.name }}</li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/system-fields/path/index.html b/docs/api/db/system-fields/path/index.html new file mode 100644 index 00000000..f492b669 --- /dev/null +++ b/docs/api/db/system-fields/path/index.html @@ -0,0 +1,321 @@ + + + + + + + + + + _path | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

_path

+ + + +
    + + + +
+ +

The _path is the more complete version of the _id. It contains +the entire path of records that are the parents of a record. So if you have a +record named docs/api/db/contents.lr the _id would be db but the _path +would be docs/api/db.

+

The path can be used to uniquely identify a page but for that purpose the +_gid can also be used which is a hashed hexadecimal version of +the page.

+

Example

<!-- generated from {{ this._path }} -->
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/system-fields/slug/index.html b/docs/api/db/system-fields/slug/index.html new file mode 100644 index 00000000..1958a678 --- /dev/null +++ b/docs/api/db/system-fields/slug/index.html @@ -0,0 +1,306 @@ + + + + + + + + + + _slug | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

_slug

+ + + +
    + + + +
+ +

This field defines the URL slug of the record. If not set it defaults to +either the _id or an expansion of what the parent defines for all children.

+

For more information about this refer to URLs and Slugs.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/system-fields/source-alt/index.html b/docs/api/db/system-fields/source-alt/index.html new file mode 100644 index 00000000..1613d8c1 --- /dev/null +++ b/docs/api/db/system-fields/source-alt/index.html @@ -0,0 +1,319 @@ + + + + + + + + + + _source_alt | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

_source_alt

+ + + +
    + + + +
+ +

This field points to the true source Alternative of the page. This primarily exists internally +to support the builder. In particular the difference to the _alt field is +that this one will indicate if an alt falls back to a different alternative. +At present pages can only fall back to the _primary alternative which will +be reflected by this field.

+

Example

<!-- generated from language {{ this._source_alt }} -->
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/system-fields/template/index.html b/docs/api/db/system-fields/template/index.html new file mode 100644 index 00000000..fde8f1b9 --- /dev/null +++ b/docs/api/db/system-fields/template/index.html @@ -0,0 +1,306 @@ + + + + + + + + + + _template | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

_template

+ + + +
    + + + +
+ +

This field sets the template that Lektor uses for rendering. It defaults to +model name + .html. If the _model is page the name of the template +will be page.html. In some situations it makes sense to override this.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/type/index.html b/docs/api/db/type/index.html new file mode 100644 index 00000000..068f995a --- /dev/null +++ b/docs/api/db/type/index.html @@ -0,0 +1,346 @@ + + + + + + + + + + Type | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

lektor.types.Type (env, options)

+ + + +
    + + + +
  • New in Lektor Version 2.0
  • + +
+ +

The fields in Records use types to specify the behavior of +the values. Lektor comes with a wide range of built-in field types but it is possible to build your own by subclassing types +class. A type is instantiated with two parameters: a reference to the +Environment that it belongs to and a dictionary +with configuration options from the ini file.

+

A field type has to implement the value_from_raw +method and set the widget property as a very basic requirement.

+

To create a type you need to create a subclass. The name of the class needs +to match the type name. If you want to name your type mything then it +needs to be called MyThingType. Afterwards you can register it with the +environment in setup_env:

+
from lektor.types import Type
+
+class MyThingType(Type):
+    widget = 'singleline-text'
+
+    def value_from_raw(self, raw):
+        return raw.value
+
+def setup_env(self, **extra):
+    self.env.add_type(MyThingType)
+
+

For more information see value_from_raw.

+

There is a more complete example in the +Plugin How To.

+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/type/to-json/index.html b/docs/api/db/type/to-json/index.html new file mode 100644 index 00000000..a59be625 --- /dev/null +++ b/docs/api/db/type/to-json/index.html @@ -0,0 +1,287 @@ + + + + + + + + + + to_json | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

to_json (pad, record=None, alt='_primary')

+ + + +
    + +
  • Method of Type
  • + + + +
  • New in Lektor Version 2.0
  • + +
+ +

This method is used to export a type definition to JSON. Primarily this is +used to drive some more special widgets for the admin UI. For the moment this +is largely undocumented as widgets are not yet customizable. For more +information you will need to read the Lektor docs.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/type/value-from-raw/index.html b/docs/api/db/type/value-from-raw/index.html new file mode 100644 index 00000000..dd00e921 --- /dev/null +++ b/docs/api/db/type/value-from-raw/index.html @@ -0,0 +1,348 @@ + + + + + + + + + + value_from_raw | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

value_from_raw (raw)

+ + + +
    + +
  • Method of Type
  • + + + +
  • New in Lektor Version 2.0
  • + +
+ +

This method needs to be implemented to perform the type conversion from the +raw value from the content file into a value that Lektor can process in the +database layer. This can be any Python type for as long as it makes sense. +It must either return a valid value or a special value that indicates a bad +value. For more information see the raw value information below and the +example provided.

+

Example

from lektor.types import Type
+
+class LocationType(Type):
+    widget = 'singleline-text'
+
+    def value_from_raw(self, raw):
+        if raw.value is None:
+            return raw.missing_value('Location was not supplied')
+        try:
+            lng, lat = [float(x.strip()) for x in
+                        raw.value.split(';')]
+        except (TypeError, ValueError):
+            return raw.bad_value('Location was malformed')
+        return (lng, lat)
+
+def setup_env(self, **extra):
+    self.env.add_type(LocationType)
+
+

Raw Value

The value passed is a raw value type. It has a few properties and methods:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeDescription
nameThe name of the field
valueThe raw value as unicode string or None if missing
padA reference to the pad
bad_value(rsn)Creates a value that indicates a bad value with a reason.
missing_value(rsn)Similar to bad_valuebut indicates an absent value.
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/type/widget/index.html b/docs/api/db/type/widget/index.html new file mode 100644 index 00000000..bd558c97 --- /dev/null +++ b/docs/api/db/type/widget/index.html @@ -0,0 +1,324 @@ + + + + + + + + + + widget | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

widget

+ + + +
    + +
  • Property of Type
  • + + + +
  • New in Lektor Version 2.0
  • + +
+ +

It's currently not yet possible to create your own widgets for the admin panel +but you can select one of the built-in widgets for your own type. Note that +not all widgets will necessarily will work directly with your type as such. +For instance the select widget and some others will currently require some +extra values be supplied in the to_json method.

+

Example

from lektor.types import Type
+
+class MyThingType(Type):
+    widget = 'singleline-text'
+
+    def value_from_raw(self, raw):
+        return raw.value
+
+

Available Widgets

These widgets are currently available:

+
    +
  • singleline-text: single-line text input field
  • +
  • multiline-text: multi-line text input field
  • +
  • datepicker: a date input field (currently not yet an actual date picker)
  • +
  • integer: an integer input field
  • +
  • float: a floating point value input field
  • +
  • checkbox: a checkbox
  • +
  • url: a URL input field
  • +
  • slug: input field for URL slugs
  • +
  • checkboxes: an input field with multiple checkboxes *
  • +
  • select: an input field in the form of a select box *
  • +
+

* checkboxes and select require a choices list to be supplied which is +a list of [value, label] tuples where value is the stored value and label +is a dictionary of internationalized values for the UI. For more information +you will currently have to refer to the Lektor sourcecode.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/types/boolean/index.html b/docs/api/db/types/boolean/index.html new file mode 100644 index 00000000..216864e5 --- /dev/null +++ b/docs/api/db/types/boolean/index.html @@ -0,0 +1,363 @@ + + + + + + + + + + boolean | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

boolean

+ + + +
    + + + +
+ +

The boolean type is a basic checkbox that can be either true or false. +It's most useful for representing flags that can be enabled or disabled.

+

Since it's stored as text, the following values correspond to true and +false:

+ + + + + + + + + + + + + + + + + + + + +
Considered TrueConsidered False
truefalse
yesno
10
+

The checkbox_label attribute can be used to give a description to the +checkbox which otherwise looks a little bit lonely in the admin panel.

+

Field Usage

[fields.render_big]
+label = Render big
+type = boolean
+checkbox_label = If true, then the page will be rendered larger.
+default = false
+
+

Template Usage

<div class="page{% if this.render_big %} page-large{% endif %}">
+  ...
+</div>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/types/checkboxes/index.html b/docs/api/db/types/checkboxes/index.html new file mode 100644 index 00000000..3d753015 --- /dev/null +++ b/docs/api/db/types/checkboxes/index.html @@ -0,0 +1,359 @@ + + + + + + + + + + checkboxes | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

checkboxes

+ + + +
    + + + +
+ +

The checkboxes type is a useful type that allows you to select multiple +values in the admin panel from a list of choices. These choices can be +either defined in the model or dynamically loaded from the tree of pages.

+

The configuration of the type is a bit more involved because of it's +flexibility. The following options exist:

+
    +
  • source: if provided it should be an expression that evaluates to an +iterable of records. The variable record thereby points to the current +record.
  • +
  • choices: instead of source this can be provided in which case it is a +comma separated list of values.
  • +
  • choice_labels: when choices is given, this is used as labels to display +it in the UI. It's a comma separated list of values.
  • +
  • item_key: an template format expression to convert a source item into +the value that is stored. This defaults to {{ this._id }} which means +that the ID of the selected record is stored.
  • +
  • item_label: similar to item_key but for the UI part. This has no +default which means that the record's configured title will be used as +label.
  • +
+

In the contents file the values are stored as comma separated list.

+

Field Usage

[fields.slideshow]
+label = Slideshow
+type = checkboxes
+description = Attached images to include in the slidehow
+source = record.attachments.images
+
+

Template Usage

{% for image in this.attachments.images %}
+  {% if image._id in this.slideshow %}
+    <img src="{{ image.thumbnail(500) }}" class="slide">
+  {% endif %}
+{% endfor %}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/types/date/index.html b/docs/api/db/types/date/index.html new file mode 100644 index 00000000..b0c9efe9 --- /dev/null +++ b/docs/api/db/types/date/index.html @@ -0,0 +1,336 @@ + + + + + + + + + + date | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

date

+ + + +
    + + + +
+ +

The date type can store a date. Because it knows a bit more about dates +than a plain old string some basic operations can be provided in the +templates.

+

The canonical format for the type in text form is YYYY-MM-DD.

+

Field Usage

[fields.pub_date]
+label = Publication date
+type = date
+
+

Template Usage

<p>Published: {{ this.pub_date.strftime('%d/%m/%Y') }}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/types/datetime/index.html b/docs/api/db/types/datetime/index.html new file mode 100644 index 00000000..75b096d3 --- /dev/null +++ b/docs/api/db/types/datetime/index.html @@ -0,0 +1,366 @@ + + + + + + + + + + datetime | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

datetime

+ + + +
    + + + +
  • New in Lektor Version 2.0
  • + +
+ +

The datetime type can store a date and time. +datetime value can also include time zone info.

+

The canonical format for the type in text form is YYYY-MM-DD HH:MM:SS[ Z].

+

Z is optional information. +You can use Z field with below informations.

+
    +
  • Time Zone Abbreviations such as UTC, EST
  • +
  • Time Zone Name such as America/Dominica
  • +
  • Timedelta such as +0900, -0930
  • +
+

You can also use datetimeformat +filter with this type.

+

Valid Examples

pub_date: 2016-01-13 07:53:22
+
+or
+
+pub_date: 2016-01-13 07:53:22 UTC
+
+or
+
+pub_date: 2016-01-13 07:53:22 EST
+
+or
+
+pub_date: 2016-01-13 07:53:22 America/Dominica
+
+or
+
+pub_date: 2016-01-13 07:53:22 +0900
+
+

Field Usage

[fields.pub_date]
+label = Publication date
+type = datetime
+
+

Template Usage

<p>Published: {{ this.pub_date.strftime('%Y-%m-%d %H:%M:%S') }}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/types/float/index.html b/docs/api/db/types/float/index.html new file mode 100644 index 00000000..b8264132 --- /dev/null +++ b/docs/api/db/types/float/index.html @@ -0,0 +1,339 @@ + + + + + + + + + + float | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

float

+ + + +
    + + + +
+ +

The float type is similar to the integer one but it +can store floating points instead of just integer values.

+

Field Usage

[fields.percentage]
+label = Percentage
+type = float
+description = Just a percentage of a progress bar.
+addon_label = %
+
+

Template Usage

<div class="progress-bar">
+  <span class="progress" style="width: {{ this.percentage }}%"></span>
+  <span class="label">{{ this.percentage }}%</span>
+</div>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/types/flow/index.html b/docs/api/db/types/flow/index.html new file mode 100644 index 00000000..d3bf77c1 --- /dev/null +++ b/docs/api/db/types/flow/index.html @@ -0,0 +1,375 @@ + + + + + + + + + + flow | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

flow

+ + + +
    + + + +
+ +

The flow type is a special type that allows you to use +Flow Blocks in a page. Blocks are small +items that work like page models but can be used for a specific field. Such +a flow field can hold as many blocks as you want in a well defined order +which allows you to build complex pages out of these blocks.

+

Each block typically renders a specific template automatically although this +can be customized.

+

For configuration you can define which blocks are allowed by setting the +flow_blocks parameter which is a comma separated list of flow blocks +that are allowed. If not defined, all flow blocks become available.

+

The text format for flow blocks in the contents.lr file looks a bit more +complex because of its nested nature, but in essence it's this:

+
#### name-of-flow-block ####
+field-1: value 1
+----
+field-2: value 2
+
+

Because flow blocks are stored within another field the --- needs to be +escaped to ----. Likewise flow blocks within flow blocks would also +require an additional level by adding additional hashes for the name of the +flow block:

+
##### nested-flow-block #####
+field-1: value 1
+-----
+field-2: value 2
+
+

In the template the flow type automatically renders out all the blocks +within it, but the blocks can be individually accessed through the +blocks attribute. Each block's attributes are the individual fields which +you are free to access if so desired.

+

Field Usage

[fields.body]
+label = Body
+type = flow
+flow_blocks = text, image
+
+

Template Usage

<div class="body">
+  {{ this.body }}
+</div>
+
+

or more complex:

+
<div class="body">
+  {% for item in this.body.blocks %}
+    <div class="block">{{ item }}</div>
+  {% endfor %}
+</div>
+
+

To see how the actual blocks are rendered have a look at the main +Flow Documentation which covers templating +in detail.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/types/html/index.html b/docs/api/db/types/html/index.html new file mode 100644 index 00000000..d3eff054 --- /dev/null +++ b/docs/api/db/types/html/index.html @@ -0,0 +1,336 @@ + + + + + + + + + + html | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

html

+ + + +
    + + + +
+ +

The html type is basically the same as the text type but +in templates it's rendered directly as HTML instead of being escaped.

+

It renders as a multi-line input field in the admin interface.

+

Field Usage

[fields.tracking_code]
+label = Tracking Code
+description = raw HTML that is inserted for ad tracking purposes.
+type = html
+
+

Template Usage

{{ this.tracking_code }}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/types/index.html b/docs/api/db/types/index.html new file mode 100644 index 00000000..85cbcbf9 --- /dev/null +++ b/docs/api/db/types/index.html @@ -0,0 +1,502 @@ + + + + + + + + + + Builtin Field Types | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

Builtin Field Types

+ + + +
    + + + +
+ +

Lektor supports many different types that can be used for data modelling.

+

Plugins can add additional types, see the +plugin "how to".

+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/types/integer/index.html b/docs/api/db/types/integer/index.html new file mode 100644 index 00000000..8a7f43d0 --- /dev/null +++ b/docs/api/db/types/integer/index.html @@ -0,0 +1,341 @@ + + + + + + + + + + integer | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

integer

+ + + +
    + + + +
+ +

The integer type is one of the most basic ones in Lektor. It can store +arbitrary natural numbers both negative and positive. It should be used +instead of a string when a real number with such behavior is wanted as it +sorts numbers correctly and the numbers can be manipulated.

+

Field Usage

[fields.image_width]
+label = Image width
+type = integer
+description = The intended image width in pixels.
+addon_label = px
+
+

Template Usage

<img
+  src="{{ this.image.thumbnail(this.image_width - 10) }}"
+  alt="a thumbnail of that image"
+  style="border: 5px;">
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/types/markdown/index.html b/docs/api/db/types/markdown/index.html new file mode 100644 index 00000000..c17bf811 --- /dev/null +++ b/docs/api/db/types/markdown/index.html @@ -0,0 +1,358 @@ + + + + + + + + + + markdown | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

markdown

+ + + +
    + + + +
+ +

The markdown format is a special form of the text type but +instead of rendering unformatted text, it parses it as +Markdown and converts it into +HTML.

+

Normally accessing the Markdown field just returns the rendered HTML but +there are some special attributes on it to access more information:

+ + + + + + + + + + + + + + + + +
AttributeExplanation
htmlthe rendered Markdown as HTML string
sourcethe unprocessed Markdown source
+

Additional attributes can become available through the use of plugins.

+

Field Usage

[fields.body]
+label = Body
+type = markdown
+
+

Template Usage

<div class="body">
+  {{ this.body }}
+</div>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/types/select/index.html b/docs/api/db/types/select/index.html new file mode 100644 index 00000000..c3887455 --- /dev/null +++ b/docs/api/db/types/select/index.html @@ -0,0 +1,340 @@ + + + + + + + + + + select | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

select

+ + + +
    + + + +
+ +

The select type works exactly like the checkboxes type +but unlike it you can only select a single item. For configuration options +refer directly to the checkboxes type.

+

In the contents file the values are stored as a single textual item.

+

Field Usage

[fields.class]
+label = Class
+type = select
+choices = full-width, pull-left, pull-right
+choice_labels = Full Width, Pull Left, Pull Right
+
+

Template Usage

<div class="{{ this.class }}">
+  ...
+</div>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/types/sort-key/index.html b/docs/api/db/types/sort-key/index.html new file mode 100644 index 00000000..c71905f1 --- /dev/null +++ b/docs/api/db/types/sort-key/index.html @@ -0,0 +1,333 @@ + + + + + + + + + + sort_key | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

sort_key

+ + + +
    + + + +
+ +

The sort_key type is similar to the integer type which is one of the most +basic ones in Lektor. It can store arbitrary natural numbers both negative and +positive. It's intended for giving pages a sort order. The reason it's a +special type is that future versions of Lektor can take advantage of this to +implement a widget for ordering.

+

Field Usage

[fields.sort_key]
+label = Sort order
+type = sort_key
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/types/string/index.html b/docs/api/db/types/string/index.html new file mode 100644 index 00000000..99367787 --- /dev/null +++ b/docs/api/db/types/string/index.html @@ -0,0 +1,339 @@ + + + + + + + + + + string | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

string

+ + + +
    + + + +
+ +

The string type is the most basic of all types as it can store one line of +arbitrary text. It's useful for many places where you want to show a bit of +text without any special formatting (titles, basic summaries and more).

+

It renders as a basic input field in the admin interface.

+

Field Usage

[fields.title]
+label = Title
+type = string
+size = large
+description = The title of the page
+addon_label = [[header]]
+
+

Template Usage

<h1>{{ this.title }}</h1>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/types/strings/index.html b/docs/api/db/types/strings/index.html new file mode 100644 index 00000000..058f0a01 --- /dev/null +++ b/docs/api/db/types/strings/index.html @@ -0,0 +1,343 @@ + + + + + + + + + + strings | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

strings

+ + + +
    + + + +
+ +

The strings type one that is a mixture of the string +and text type. It renders as a multi-line text area in the +admin but the template will see each line of text separately. It's primarily +useful for some advanced scenarios where enumerations and other things +should be rendered.

+

Field Usage

[fields.things_to_buy]
+label = Things to buy
+type = strings
+description = A list of things that would be good to buy
+
+

Template Usage

<h2>Shopping List</h2>
+<ul>
+{% for item in this.things_to_buy %}
+  <li>{{ item }}</li>
+{% endfor %}
+</ul>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/types/text/index.html b/docs/api/db/types/text/index.html new file mode 100644 index 00000000..c82f8954 --- /dev/null +++ b/docs/api/db/types/text/index.html @@ -0,0 +1,336 @@ + + + + + + + + + + text | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

text

+ + + +
    + + + +
+ +

The text type is very similar to the string: type but +can store multiple lines. It does not support any formatting but is very +useful for storing code and other things.

+

It renders as a multi-line input field in the admin interface.

+

Field Usage

[fields.code]
+label = Code
+type = text
+
+

Template Usage

<pre>{{ this.code }}</pre>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/db/types/url/index.html b/docs/api/db/types/url/index.html new file mode 100644 index 00000000..a4a1cee6 --- /dev/null +++ b/docs/api/db/types/url/index.html @@ -0,0 +1,383 @@ + + + + + + + + + + url | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

url

+ + + +
    + + + +
+ +

The url type is basically a more fancy version of the basic +string type but it performs a basic validation in the +admin UI of being a URL. In addition to that, it gives access to parts +of the URL for better displaying.

+

Within templates the URL can be rendered as such, but it also has a few +other attributes that are useful:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeDescription
urlThe URL is a basic string for further manipulation
hostJust the host portion of the URL.
portJust the port of the URL.
pathThe path of the URL
queryThe query string of the URL
fragmentThe part after the hash symbol (#) in the URL
schemeThe URL schema (http etc.)
ascii_urlSame as url but guaranteed to be ASCII only
ascii_hostSame as host but guaranteed to be ASCII only
+

Field Usage

[fields.website]
+label = Website
+type = url
+
+

Template Usage

<a href="{{ this.url }}">{{ this.url.host }}</a>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/environment/add-build-program/index.html b/docs/api/environment/add-build-program/index.html new file mode 100644 index 00000000..9b2f99dd --- /dev/null +++ b/docs/api/environment/add-build-program/index.html @@ -0,0 +1,328 @@ + + + + + + + + + + add_build_program | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

add_build_program (cls, program)

+ + + + + +

This is very experimental API and used to register build programs for +custom source objects. This can be used to implement virtual items. This +works in combination with generator and +urlresolver and is responsible for generating +artifacts out of source objects.

+

Example

from lektor.sourceobj import VirtualSourceObject
+from lektor.build_programs import BuildProgram
+from lektor.utils import build_url
+
+class Source(VirtualSourceObject):
+
+    @property
+    def path(self):
+        return self.record.path + '@source'
+
+    @property
+    def source_content(self):
+        with open(self.record.source_filename) as f:
+            return f.read().decode('utf-8')
+
+    @property
+    def url_path(self):
+        return build_url([self.record.url_path, 'source.txt'])
+
+class SourceBuildProgram(BuildProgram):
+
+    def produce_artifacts(self):
+        self.declare_artifact(
+            self.source.url_path,
+            sources=list(self.source.iter_source_filenames()))
+
+    def build_artifact(self, artifact):
+        artifact.render_template_into('view_source.html',
+                                      this=self.source)
+
+env.add_build_program(Source, SourceBuildProgram)
+
+@env.virtualpathresolver('source')
+def resolve_virtual_path(record, pieces):
+    if not pieces:
+        return Source(record)
+
+

And here the example view_source.html template:

+
<h2>Source for {{ this.parent.path }}</h2>
+<pre>{{ this.source_content }}</pre>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/environment/add-publisher/index.html b/docs/api/environment/add-publisher/index.html new file mode 100644 index 00000000..6bf58eef --- /dev/null +++ b/docs/api/environment/add-publisher/index.html @@ -0,0 +1,294 @@ + + + + + + + + + + add_publisher | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

add_publisher (scheme, publisher)

+ + + +
    + +
  • Method of Environment
  • + + + +
  • New in Lektor Version 2.0
  • + +
+ +

This method can be used to register a new publisher for a given URL scheme +with Lektor. This allows plugins to provide custom deployment methods. For +more information on implementing these see Publisher.

+

Example

from lektor.publisher import Publisher
+
+class MyPublisher(Publisher):
+    pass
+
+env.add_publisher('my', MyPublisher)
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/environment/add-type/index.html b/docs/api/environment/add-type/index.html new file mode 100644 index 00000000..06815f41 --- /dev/null +++ b/docs/api/environment/add-type/index.html @@ -0,0 +1,296 @@ + + + + + + + + + + add_type | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

add_type (type)

+ + + +
    + +
  • Method of Environment
  • + + + +
  • New in Lektor Version 2.0
  • + +
+ +

This registers a new Field Type with the environment

+

Example

from lektor.types import Type
+
+class MyThingType(Type):
+    widget = 'singleline-text'
+
+    def value_from_raw(self, raw):
+        return raw.value
+
+def setup_env(self, **extra):
+    self.env.add_type(MyThingType)
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/environment/generator/index.html b/docs/api/environment/generator/index.html new file mode 100644 index 00000000..904a2145 --- /dev/null +++ b/docs/api/environment/generator/index.html @@ -0,0 +1,308 @@ + + + + + + + + + + generator | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

generator ()

+ + + + + +

This is very experimental API and used to register a function that can +generate source objects relative to another one. This works in combination +with urlresolver but handles the build-all part of +the equation.

+

The registered function is invoked for each source after it was build. As +such it's important to only return items if a virtual sub resource actually +exists for a page.

+

Example

from lektor.sourceobj import VirtualSourceObject
+from lektor.db import Record
+from lektor.utils import build_url
+
+class Source(VirtualSourceObject):
+
+    @property
+    def path(self):
+        return self.record.path + '@source'
+
+    @property
+    def url_path(self):
+        return build_url([self.record.url_path, 'source.txt'])
+
+@env.generator
+def generate_source_file(node):
+    if isinstance(node, Record) and not node.is_attachment:
+        yield Source(node)
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/environment/index.html b/docs/api/environment/index.html new file mode 100644 index 00000000..da4d3b6a --- /dev/null +++ b/docs/api/environment/index.html @@ -0,0 +1,427 @@ + + + + + + + + + + Environment | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

lektor.environment.Environment

+ + + +
    + + + +
+ +

This class holds all the relevant information for building a Lektor +Project. It can be reused between builds and only +holds state that is immutable after initialization. For instance it +will hold all loaded plugins, the configuration for the Jinja 2 +template engine and more.

+

Plugins have access to the environment at any point by accessing self.env.

+

Example

from lektor.project import Project
+
+project = Project.discover()
+env = project.make_env()
+
+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/environment/jinja-env/index.html b/docs/api/environment/jinja-env/index.html new file mode 100644 index 00000000..6fcb3685 --- /dev/null +++ b/docs/api/environment/jinja-env/index.html @@ -0,0 +1,299 @@ + + + + + + + + + + jinja_env | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

jinja_env

+ + + + + +

This object is a configured Jinja2 environment. For more information you can +refer to the Jinja 2 Documentation.

+

This is where plugins can inject additional data like custom filters, tests +or global functions.

+

Plugin Example

from lektor.pluginsystem import Plugin
+
+class MyPlugin(Plugin):
+    ...
+
+    def on_setup_env(self, **extra):
+        def shout_filter(value):
+            return unicode(value).upper() + '!!!!1111'
+        self.env.jinja_env.filters['shout'] = shout_filter
+
+

Then you can use this filter from templates:

+
<h1>{{ page.title|shout }}</h1>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/environment/load-config/index.html b/docs/api/environment/load-config/index.html new file mode 100644 index 00000000..9ab5c66a --- /dev/null +++ b/docs/api/environment/load-config/index.html @@ -0,0 +1,295 @@ + + + + + + + + + + load_config | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

load_config ()

+ + + + + +

Because the environment is reused between builds, the config is not cached +on the environment but needs to be explicitly loaded. This happens with +the help of the load_config method. It returns a config object that +gives access to the settings in the project file.

+

These settings are work in progress and if you want to know how to use +the config file and what to do with it, you have to consult the source +code.

+

Example

from lektor.project import Project
+
+project = Project.discover()
+env = project.make_env()
+config = env.load_config()
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/environment/load-plugins/index.html b/docs/api/environment/load-plugins/index.html new file mode 100644 index 00000000..ebb12732 --- /dev/null +++ b/docs/api/environment/load-plugins/index.html @@ -0,0 +1,291 @@ + + + + + + + + + + load_plugins | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

load_plugins ()

+ + + + + +

Normally when an environment is constructed plugins are loaded automatically. +If you disabled this when creating the environment you can still at a later +point load the plugins by invoking this method.

+

Example

from lektor.project import Project
+
+project = Project.discover()
+env = project.make_env(load_plugins=False)
+env.load_plugins()
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/environment/new-pad/index.html b/docs/api/environment/new-pad/index.html new file mode 100644 index 00000000..103fbd95 --- /dev/null +++ b/docs/api/environment/new-pad/index.html @@ -0,0 +1,293 @@ + + + + + + + + + + new_pad | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

new_pad ()

+ + + + + +

To access the Database from an environment you need to +first construct a Pad. This method can do that for +you. For more information about how the pad works, you can refer to the +general documentation of it.

+

Example

from lektor.project import Project
+
+project = Project.discover()
+env = project.make_env()
+pad = env.new_pad()
+root_record = pad.root
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/environment/render-template/index.html b/docs/api/environment/render-template/index.html new file mode 100644 index 00000000..e28055a1 --- /dev/null +++ b/docs/api/environment/render-template/index.html @@ -0,0 +1,307 @@ + + + + + + + + + + render_template | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

render_template (name, pad=None, this=None, values=None, alt=None)

+ + + + + +

Whenever Lektor needs to render a template, it will use this exact +method. Here are the parameters and what they mean:

+
    +
  • name: this is the name of the template that should be rendered. It's +the local filename relative to the templates folder and uses slashes +for paths.
  • +
  • pad: when a Pad is available, it should be provided +so that the site variable can be populated. If a context is available +then the pad will also be pulled from the context if needed.
  • +
  • this: the value of the this variable in templates. This should always +be the closest renderable thing. Typically this is a Record or flow block or something similar.
  • +
  • values: optional additional variables can be provided as a dictionary here.
  • +
  • alt: this can override the default selected alt. If not provided it's +discovered from this and it will default to _primary if no other +information can be found.
  • +
+

Example

from lektor.project import Project
+
+project = Project.discover()
+env = project.make_env(load_plugins=False)
+pad = env.new_pad()
+rv = env.render_template('hello.html', pad=pad, this={
+    'title': 'Demo Object'
+})
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/environment/urlresolver/index.html b/docs/api/environment/urlresolver/index.html new file mode 100644 index 00000000..e4bc13f7 --- /dev/null +++ b/docs/api/environment/urlresolver/index.html @@ -0,0 +1,309 @@ + + + + + + + + + + urlresolver | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

urlresolver ()

+ + + + + +

This is very experimental API and used to register a custom URL resolver +function with the environment. It's invoked whenever a node has matched but +more data is left to parse. This can be used to implement virtual items. +This works in combination with generator but handles the +URL matching part of the equation.

+

The registered function is invoked with a source object and a list of +URL path segments.

+

Example

from lektor.sourceobj import VirtualSourceObject
+from lektor.utils import build_url
+
+class Source(VirtualSourceObject):
+
+    @property
+    def path(self):
+        return self.record.path + '@source'
+
+    @property
+    def url_path(self):
+        return build_url([self.record.url_path, 'source.txt'])
+
+@env.urlresolver
+def match_source_file(node, url_path):
+    if url_path == ['source.txt'] \
+       and isinstance(node, Record) \
+       and not node.is_attachment:
+        return Source(node)
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/environment/virtualpathresolver/index.html b/docs/api/environment/virtualpathresolver/index.html new file mode 100644 index 00000000..b6c4ec0e --- /dev/null +++ b/docs/api/environment/virtualpathresolver/index.html @@ -0,0 +1,328 @@ + + + + + + + + + + virtualpathresolver | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

virtualpathresolver (prefix)

+ + + +
    + +
  • Method of Environment
  • + + + +
  • New in Lektor Version 2.0
  • + +
+ +

When implementing Virtual Source Objects it's important +that you can locate them. While virtual sources do not appear as children of +pages they can be navigated to through the database pad. This is achieved +through custom virtual path resolvers.

+

Each source object needs to be a unique prefix which identifies all instances +of it. For instance if you want to implement a special page (like a feed) +that would exist for specific pages, then you can register the virtual path +prefix feed with your plugin. Though you should use more descriptive names +for your plugins as these paths are shared.

+

If a user then resolves the page /my-page@feed it would invoke your URL +resolver with the record my-page and an empty list (rest of the path +segments). If they would request /my-page@feed/recent then it would +pass ['recent'] as path segments.

+

Example

Here an example that would implement a virtual source for feeds and an +associated virtual path resolver:

+
from lektor.sourceobj import VirtualSourceObject
+from lektor.utils import build_url
+
+class Feed(VirtualSourceObject):
+
+    def __init__(self, record, version='default'):
+        VirtualSourceObject.__init__(self, record)
+        self.version = version
+
+    @property
+    def path(self):
+        return '%s@feed%s' % (
+            self.record.path,
+            '/' + self.version if self.version != 'default' else '',
+        )
+
+    @property
+    def url_path(self):
+        return build_url([self.record.url_path, 'feed.xml'])
+
+
+def on_setup_env(self, **extra):
+    @self.env.virtualpathresolver('feed')
+    def resolve_virtual_path(record, pieces):
+        if not pieces:
+            return Feed(record)
+        elif pieces == ['recent']:
+            return Feed(record, version='recent')
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/index.html b/docs/api/index.html new file mode 100644 index 00000000..474ad288 --- /dev/null +++ b/docs/api/index.html @@ -0,0 +1,332 @@ + + + + + + + + + + API | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

API

+ + + +
    + + + +
+ +

Lektor consists of many interfaces that you can interface with through +various different ways. Not just when developing plugins, but also from +within the templates. This part of the documentation covers all those +areas in detail.

+ + + + + + + + + + +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/events/after-build-all/index.html b/docs/api/plugins/events/after-build-all/index.html new file mode 100644 index 00000000..2f8ba7d8 --- /dev/null +++ b/docs/api/plugins/events/after-build-all/index.html @@ -0,0 +1,298 @@ + + + + + + + + + + after-build-all | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

after-build-all (builder)

+ + + +
    + + + +
+ +

This event is emitted after the builder build all sources. It works similar +to the before-build-all event otherwise.

+ + +
+

+ Plugins That Use This Event +

+ + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/events/after-build/index.html b/docs/api/plugins/events/after-build/index.html new file mode 100644 index 00000000..919289fe --- /dev/null +++ b/docs/api/plugins/events/after-build/index.html @@ -0,0 +1,298 @@ + + + + + + + + + + after-build | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

after-build (builder, build_state, source, prog)

+ + + +
    + + + +
+ +

This event is emitted right after a source is being built into a final build +artifact. It works pretty much exactly the same as the before-build event.

+ + +
+

+ Plugins That Use This Event +

+ + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/events/after-prune/index.html b/docs/api/plugins/events/after-prune/index.html new file mode 100644 index 00000000..c7a0fd7f --- /dev/null +++ b/docs/api/plugins/events/after-prune/index.html @@ -0,0 +1,297 @@ + + + + + + + + + + after-prune | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

after-prune (builder, all)

+ + + +
    + + + +
+ +

This event is emitted after before Lektor searches the build directory for data that does not match a known artifact, and removes that data. This event is also emitted after a clean, that is, when the build directory is completely purged of all data.

+ + +
+

+ Plugins That Use This Event +

+ + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/events/before-build-all/index.html b/docs/api/plugins/events/before-build-all/index.html new file mode 100644 index 00000000..5a8ade83 --- /dev/null +++ b/docs/api/plugins/events/before-build-all/index.html @@ -0,0 +1,316 @@ + + + + + + + + + + before-build-all | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

before-build-all (builder)

+ + + +
    + + + +
+ +

This event is emitted before the builder decides to build all sources. It's +most useful for preprocessing sources on the file system before the rest of +the build process should pick it up. For instance here a plugin could inject +additional files into the asset folder and similar things.

+

As an example, this is what the Webpack Support uses.

+

Example

import subprocess
+
+def on_before_build_all(self, builder, **extra):
+    root = ospath.join(self.env.root_path, 'webpack')
+    subprocess.Popen(['webpack'], cwd=root).wait()
+
+ + +
+

+ Plugins That Use This Event +

+ + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/events/before-build/index.html b/docs/api/plugins/events/before-build/index.html new file mode 100644 index 00000000..f9ab14e0 --- /dev/null +++ b/docs/api/plugins/events/before-build/index.html @@ -0,0 +1,324 @@ + + + + + + + + + + before-build | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

before-build (builder, build_state, source, prog)

+ + + +
    + + + +
+ +

This event is emitted right before a source is being built into a final build +artifact. Note that this event in itself does not indicate if the build will +actually take place or not due to the artifact being current already as such +the usefulness is limited.

+

The parameters being passed are:

+
    +
  • builder: a reference to the builder.
  • +
  • build_state: a reference to the build state object.
  • +
  • source: the source object that is being processed. (See +Source Object for more information)
  • +
  • prog: the build program that is being used to process the source. (See +Build Program for more information)
  • +
+

Note that currently both the builder as well as the build state are +undocumented and unsupported! This means that if a plugin choses to use those +references to do something with it they should consider that they might break +in future versions.

Example

def on_before_build(self, source, prog, **extra):
+    print('building %s' % source.source_filename)
+
+ + +
+

+ Plugins That Use This Event +

+ + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/events/before-prune/index.html b/docs/api/plugins/events/before-prune/index.html new file mode 100644 index 00000000..a07392e4 --- /dev/null +++ b/docs/api/plugins/events/before-prune/index.html @@ -0,0 +1,297 @@ + + + + + + + + + + before-prune | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

before-prune (builder, all)

+ + + +
    + + + +
+ +

This event is emitted right before Lektor searches the build directory for data that does not match a known artifact. Orphaned data is then removed. This event is also emitted before a clean, that is, when the build directory is completely purged of all data.

+ + +
+

+ Plugins That Use This Event +

+ + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/events/index.html b/docs/api/plugins/events/index.html new file mode 100644 index 00000000..c17d148f --- /dev/null +++ b/docs/api/plugins/events/index.html @@ -0,0 +1,486 @@ + + + + + + + + + + Events | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

Events

+ + + +
    + + + +
+ +

As Lektor executes and builds it emits various events that plugins can +respond to. This gives a list of all of those events.

+

Handling Events

Events are handled by implementing a method with the name of the event and +the prefix on_ on the plugin and underscores instead of dashes. So for +instance if the event is called process-template-context the method to implement is +on_process_template_context. It's important to additionally always +catch extra parameters in a **extra parameter so that the plugin does +not break if an event starts sending additional parameters in the future.

+

Emitting Events

If you want to emit your own events you can do that from the environment's +plugin controller:

+
self.emit('your-signal', parameter='value')
+
+

This emits a signal named your-plugin-your-signal. The signal prefix is +taken from the plugin ID which is set in setup.py.

+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/events/markdown-config/index.html b/docs/api/plugins/events/markdown-config/index.html new file mode 100644 index 00000000..53496fb8 --- /dev/null +++ b/docs/api/plugins/events/markdown-config/index.html @@ -0,0 +1,318 @@ + + + + + + + + + + markdown-config | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

markdown-config (config)

+ + + +
    + + + +
+ +

Future versions of Lektor may change its Markdown parser away from Mistune, and the various markdown related event hooks may be completely removed or work differently if that happens.

This event is emitted right after MarkdownConfig is instantiated, in which configuration can be set. This is done before the renderer is made.

+

Example

lektor-markdown-header-anchors uses this to register a renderer mixin:

+
def on_markdown_config(self, config, **extra):
+    class HeaderAnchorMixin(object):
+        def header(renderer, text, level, raw):
+            if self.get_config().get('anchor-type') == "random":
+                anchor = uuid.uuid4().hex[:6]
+            else:
+                anchor = slugify(raw)
+            renderer.meta['toc'].append((level, anchor, Markup(text)))
+            return '<h%d id="%s">%s</h%d>' % (level, anchor, text, level)
+    config.renderer_mixins.append(HeaderAnchorMixin)
+
+ + +
+

+ Plugins That Use This Event +

+ + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/events/markdown-lexer-config/index.html b/docs/api/plugins/events/markdown-lexer-config/index.html new file mode 100644 index 00000000..13881f60 --- /dev/null +++ b/docs/api/plugins/events/markdown-lexer-config/index.html @@ -0,0 +1,299 @@ + + + + + + + + + + markdown-lexer-config | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

markdown-lexer-config (config, renderer)

+ + + +
    + + + +
  • New in Lektor Version 3.1
  • + +
+ +

Future versions of Lektor may change its Markdown parser away from Mistune, and the various markdown related event hooks may be completely removed or work differently if that happens.

This event is emitted right after markdown renderer is made, but before it is used to render markdown. This is where lexer configuration can be set.

+ + +
+

+ Plugins That Use This Event +

+ + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/events/markdown-meta-init/index.html b/docs/api/plugins/events/markdown-meta-init/index.html new file mode 100644 index 00000000..ec08233a --- /dev/null +++ b/docs/api/plugins/events/markdown-meta-init/index.html @@ -0,0 +1,310 @@ + + + + + + + + + + markdown-meta-init | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

markdown-meta-init (meta, record)

+ + + +
    + + + +
+ +

Future versions of Lektor may change its Markdown parser away from Mistune, and the various markdown related event hooks may be completely removed or work differently if that happens.

This event is emitted before the markdown meta information is set. This can be used to add custom meta variables to the markdown object.

+

Example

lektor-markdown-header-anchors uses this to initialize a meta var as an empty list:

+
def on_markdown_meta_init(self, meta, **extra):
+    meta['toc'] = []
+
+ + +
+

+ Plugins That Use This Event +

+ + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/events/markdown-meta-postprocess/index.html b/docs/api/plugins/events/markdown-meta-postprocess/index.html new file mode 100644 index 00000000..026f8adb --- /dev/null +++ b/docs/api/plugins/events/markdown-meta-postprocess/index.html @@ -0,0 +1,327 @@ + + + + + + + + + + markdown-meta-postprocess | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

markdown-meta-postprocess (meta, record)

+ + + +
    + + + +
+ +

Future versions of Lektor may change its Markdown parser away from Mistune, and the various markdown related event hooks may be completely removed or work differently if that happens.

This event is emitted after the markdown has been rendered. This can be used to change the markdown object meta information after the fact.

+

Example

lektor-markdown-header-anchors uses this to populate a meta var:

+
def on_markdown_meta_postprocess(self, meta, **extra):
+    prev_level = None
+    toc = []
+    stack = [toc]
+
+    for level, anchor, title in meta['toc']:
+        if prev_level is None:
+            prev_level = level
+        elif prev_level == level - 1:
+        stack.append(stack[-1][-1][2])
+            prev_level = level
+        elif prev_level > level:
+            while prev_level > level:
+                if len(stack) > 1:
+                    stack.pop()
+                prev_level -= 1
+        stack[-1].append(TocEntry(anchor, title, []))
+
+    meta['toc'] = toc
+
+ + +
+

+ Plugins That Use This Event +

+ + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/events/process-template-context/index.html b/docs/api/plugins/events/process-template-context/index.html new file mode 100644 index 00000000..f9fc1a0c --- /dev/null +++ b/docs/api/plugins/events/process-template-context/index.html @@ -0,0 +1,322 @@ + + + + + + + + + + process-template-context | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

process-template-context (context, template=None)

+ + + +
    + + + +
+ +

This event is emitted right before a template is rendered and can be used +to inject values directly into the template context. The context is always +provided and is a dictionary that can be modified.

+

It's important to know that this is not the only way to modify the template +context. Another method is to modify the underlying Jinja Environment on the environment directly. The +difference is that the globals from the jinja_env are available in all +templates whereas the modified template context is only available in the +toplevel template. This becomes apparent when you are dealing with imported +template macros. A macro will not have access to values you provide here +unless they are explicitly passed to it.

+

The filename of the template is passed as template but is only available +if the template was indeed loaded from the templates folder. There are many +more places where templates are rendered in those cases the value will +not be provided.

+

Example

def on_process_template_context(self, context, **extra):
+    context['my_variable'] = 'my value'
+
+ + +
+

+ Plugins That Use This Event +

+ + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/events/server-spawn/index.html b/docs/api/plugins/events/server-spawn/index.html new file mode 100644 index 00000000..a72ba7b4 --- /dev/null +++ b/docs/api/plugins/events/server-spawn/index.html @@ -0,0 +1,326 @@ + + + + + + + + + + server-spawn | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

server-spawn ()

+ + + +
    + + + +
+ +

When the development server boots up it emits this event if plugins want +to spawn their own development tools. For instance it can be used to +start a background process that kicks off webpack or similar tools. There +is a second event called server-stop which can be +used to detect server shutdowns.

+

Example

import os
+from subprocess import Popen
+
+class MyPlugin(Plugin):
+    ...
+
+    webpack = None
+
+    def on_server_spawn(self, **extra):
+        path = os.path.join(self.env.root_path, 'webpack')
+        self.webpack = Popen(['webpack', '--watch'], cwd=path)
+
+    def on_server_stop(self, **extra):
+        if self.webpack is not None:
+            self.webpack.kill()
+
+ + +
+

+ Plugins That Use This Event +

+ + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/events/server-stop/index.html b/docs/api/plugins/events/server-stop/index.html new file mode 100644 index 00000000..c0a835db --- /dev/null +++ b/docs/api/plugins/events/server-stop/index.html @@ -0,0 +1,298 @@ + + + + + + + + + + server-stop | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

server-stop ()

+ + + +
    + + + +
+ +

This is emitted when the server stops. For more information see +server-spawn which shows how to use it.

+ + +
+

+ Plugins That Use This Event +

+ + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/events/setup-env/index.html b/docs/api/plugins/events/setup-env/index.html new file mode 100644 index 00000000..a258fa16 --- /dev/null +++ b/docs/api/plugins/events/setup-env/index.html @@ -0,0 +1,312 @@ + + + + + + + + + + setup-env | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

setup-env ()

+ + + +
    + + + +
+ +

This event is emitted right after the plugin was initialized and associated +with the environment. This can be used to +reconfigure it. For instance this is the perfect place to inject Jinja 2 +filters and global variables.

+

Example

def on_setup_env(self, **extra):
+    self.env.jinja_env.globals['my_variable'] = 'my value'
+
+ + +
+

+ Plugins That Use This Event +

+ + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/get-plugin/index.html b/docs/api/plugins/get-plugin/index.html new file mode 100644 index 00000000..0cba022f --- /dev/null +++ b/docs/api/plugins/get-plugin/index.html @@ -0,0 +1,265 @@ + + + + + + + + + + get_plugin | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

lektor.pluginsystem.get_plugin (plugin_id_or_class, env=None)

+ + + +
    + + + +
+ +

This function can look up a plugin instance for an environment by plugin ID +or plugin class. This is particularly useful to retrieve state from a plugin. +If the env is not given a context needs to be active and the env of the +context is used.

+

Example

from lektor.pluginsystem import get_plugin
+
+plugin = get_plugin('the-plugin-id')
+cfg = plugin.get_config()
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/index.html b/docs/api/plugins/index.html new file mode 100644 index 00000000..cb21391d --- /dev/null +++ b/docs/api/plugins/index.html @@ -0,0 +1,290 @@ + + + + + + + + + + Plugins | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

Plugins

+ + + +
    + + + +
+ +

Lektor allows plugins to depend on plugins to extend functionality. This is +achieved through a flexible and ever growing plugin interface. If you are +new to it have a look at the Guide.

+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/plugin/config-filename/index.html b/docs/api/plugins/plugin/config-filename/index.html new file mode 100644 index 00000000..4129eeda --- /dev/null +++ b/docs/api/plugins/plugin/config-filename/index.html @@ -0,0 +1,301 @@ + + + + + + + + + + config_filename | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

config_filename

+ + + +
    + +
  • Property of Plugin
  • + + + +
+ +

This property returns the path to the file that holds the config for this +plugin in the loaded project. This is by default in configs/<plugin-id>.ini. +Plugins could override this in theory but it's not recommended. The primary +use of this property is to track dependencies.

+

For a convenient way to load the config see get_config.

+

Example

from lektor.pluginsystem import Plugin
+from lektor.context import get_ctx
+
+
+class MyPlugin(Plugin):
+
+    def on_env_setup(self, **extra):
+        color = self.get_config().get('color')
+        def get_css(artifact_name='/static/demo.css'):
+            ctx = get_ctx()
+            @ctx.sub_artifact(artifact_name, sources=[
+                self.config_filename])
+            def build_stylesheet(artifact):
+                with artifact.open('w') as f:
+                    f.write('body { background: %s }\n' % color)
+            return artifact_name
+        self.env.jinja_env.globals['get_css'] = get_css
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/plugin/description/index.html b/docs/api/plugins/plugin/description/index.html new file mode 100644 index 00000000..9bdd7d8a --- /dev/null +++ b/docs/api/plugins/plugin/description/index.html @@ -0,0 +1,287 @@ + + + + + + + + + + description | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

description

+ + + +
    + +
  • Property of Plugin
  • + + + +
+ +

This is a short string with some more explanation of what the plugin does. +It's shown in the UI to give the user some ideas about its operation.

+

Example

from lektor.pluginsystem import Plugin
+
+
+class MyPlugin(Plugin):
+    name = 'My Plugin'
+    description = 'This is a small plugin I wrote for testing purposes'
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/plugin/emit/index.html b/docs/api/plugins/plugin/emit/index.html new file mode 100644 index 00000000..6deb6ae3 --- /dev/null +++ b/docs/api/plugins/plugin/emit/index.html @@ -0,0 +1,298 @@ + + + + + + + + + + emit | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

emit (event, **extra)

+ + + +
    + +
  • Method of Plugin
  • + + + +
+ +

This method can be used to emit an event that other plugins can hook. The +event name is prefixed with the plugin ID.

+

Example

from lektor.pluginsystem import Plugin
+
+
+class MyPlugin(Plugin):
+
+    def on_env_setup(self, **extra):
+        self.emit('setup', foo=42)
+
+

Another plugin can then hook this:

+
from lektor.pluginsystem import Plugin
+
+
+class MyPlugin(Plugin):
+
+    def on_my_plugin_setup(self, foo, **extra):
+        print('got %s' % foo)
+
+

(This assumes the plugin id is set to my-plugin in setup.py)

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/plugin/env/index.html b/docs/api/plugins/plugin/env/index.html new file mode 100644 index 00000000..910e53a6 --- /dev/null +++ b/docs/api/plugins/plugin/env/index.html @@ -0,0 +1,271 @@ + + + + + + + + + + env | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

env

+ + + +
    + +
  • Property of Plugin
  • + + + +
+ +

This is just a reference back to the Environment +that the plugin belongs to.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/plugin/get-config/index.html b/docs/api/plugins/plugin/get-config/index.html new file mode 100644 index 00000000..bb9da81a --- /dev/null +++ b/docs/api/plugins/plugin/get-config/index.html @@ -0,0 +1,290 @@ + + + + + + + + + + get_config | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

get_config (fresh=False)

+ + + +
    + +
  • Method of Plugin
  • + + + +
+ +

This loads the config of the plugin as an Ini File.

+

Dotted paths are used to navigate into sections. So get('foo.bar') would +navigate to the bar key in the [foo] section.

+

Example

from lektor.pluginsystem import Plugin
+
+
+class MyPlugin(Plugin):
+
+    def on_env_setup(self, **extra):
+        color = self.get_config().get('color')
+        self.env.jinja_env.globals['my_color'] = color
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/plugin/index.html b/docs/api/plugins/plugin/index.html new file mode 100644 index 00000000..a2e29150 --- /dev/null +++ b/docs/api/plugins/plugin/index.html @@ -0,0 +1,344 @@ + + + + + + + + + + Plugin | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

lektor.pluginsystem.Plugin

+ + + +
    + + + +
+ +

This is the baseclass of all plugins in Lektor. It does not just hold +event handlers and similar things, but also provides some helper methods +that are useful for plugins.

+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/plugins/plugin/name/index.html b/docs/api/plugins/plugin/name/index.html new file mode 100644 index 00000000..3329010b --- /dev/null +++ b/docs/api/plugins/plugin/name/index.html @@ -0,0 +1,286 @@ + + + + + + + + + + name | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

name

+ + + +
    + +
  • Property of Plugin
  • + + + +
+ +

This property needs to be set to a human readable name for the plugin. It's +what's shown in the UI to show the UI.

+

Example

from lektor.pluginsystem import Plugin
+
+
+class MyPlugin(Plugin):
+    name = 'My Plugin'
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/project/discover/index.html b/docs/api/project/discover/index.html new file mode 100644 index 00000000..855d1bb5 --- /dev/null +++ b/docs/api/project/discover/index.html @@ -0,0 +1,266 @@ + + + + + + + + + + discover | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

discover (base=None)

+ + + + + +

This is the way Lektor by defaults discovers project files. It will start +out with the current path (of a given base path) and search upwards until it +finds a folder with a single project file in and then loads this. If none +of that leads to a file then None is returned.

+

Example

from lektor.project import Project
+
+project = Project.discover()
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/project/from-file/index.html b/docs/api/project/from-file/index.html new file mode 100644 index 00000000..24e83836 --- /dev/null +++ b/docs/api/project/from-file/index.html @@ -0,0 +1,265 @@ + + + + + + + + + + from_file | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

from_file (filename)

+ + + + + +

This is the most common way to create a project instance. It's a class +method that given the path to a project file will load the project. If +the file does not exist then None is returned.

+

Example

from lektor.project import Project
+
+project = Project.from_file('/path/to/the/project.lektorproject')
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/project/index.html b/docs/api/project/index.html new file mode 100644 index 00000000..776c20a6 --- /dev/null +++ b/docs/api/project/index.html @@ -0,0 +1,293 @@ + + + + + + + + + + Project | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

lektor.project.Project

+ + + +
    + + + +
+ +

The project class is one of the most basic classes that Lektor uses to +implement its building process. It's generated very early on when the +application needs to interact with the project file on disk. This +class is mostly useful for building scripts that use the Lektor API and +not so much in other situations as it's not directly playing a role in +the main build process.

+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/project/make-env/index.html b/docs/api/project/make-env/index.html new file mode 100644 index 00000000..285923b8 --- /dev/null +++ b/docs/api/project/make-env/index.html @@ -0,0 +1,268 @@ + + + + + + + + + + make_env | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

make_env (load_plugins=True)

+ + + + + +

Once a project is loaded this method can be used to create a +Environment object to work with. This is the +preferred way to construct such a thing.

+

By default plugins will be loaded and initialized but this can be disabled +by passing load_plugins=False.

+

Example

from lektor.project import Project
+
+project = Project.discover()
+env = project.make_env()
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/publisher/env/index.html b/docs/api/publisher/env/index.html new file mode 100644 index 00000000..9a71b96a --- /dev/null +++ b/docs/api/publisher/env/index.html @@ -0,0 +1,256 @@ + + + + + + + + + + env | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

env

+ + + +
    + +
  • Property of Publisher
  • + + + +
  • New in Lektor Version 2.0
  • + +
+ +

As each publisher is bound to an Environment that +created it. This is useful to discover related information.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/publisher/fail/index.html b/docs/api/publisher/fail/index.html new file mode 100644 index 00000000..2811cb34 --- /dev/null +++ b/docs/api/publisher/fail/index.html @@ -0,0 +1,277 @@ + + + + + + + + + + fail | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

fail (message)

+ + + +
    + +
  • Method of Publisher
  • + + + +
  • New in Lektor Version 2.0
  • + +
+ +

This method takes a message and raises an appropriate failure that aborts +the publishing process. This is invoked from within the publish method to indicate a failure:

+

Example

from lektor.publisher import Publisher
+
+
+class MyPublisher(Publisher):
+    def publish(self, target_url, credentials=None, **extra):
+        self.fail('This publisher cannot publish :(')
+
+
+class MyPlugin(Plugin):
+    def on_setup_env(self, **extra):
+        self.env.add_publisher('my', MyPublisher)
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/publisher/index.html b/docs/api/publisher/index.html new file mode 100644 index 00000000..a8037870 --- /dev/null +++ b/docs/api/publisher/index.html @@ -0,0 +1,311 @@ + + + + + + + + + + Publisher | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

lektor.publisher.Publisher

+ + + +
    + + + +
  • New in Lektor Version 2.0
  • + +
+ +

This class can be subclassed to implement custom deployment methods. +Internally these are called “publishers” and to register them with the +environment the add_publisher method can +be used.

+

Publishers have one method called publish which is used to +trigger the actual deployment process. It also has a reference back to the +environment it belongs to as well as the output path of the build process.

+

For a minimal example of a publisher refer to the documentation of the +publish method.

+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/publisher/output-path/index.html b/docs/api/publisher/output-path/index.html new file mode 100644 index 00000000..81ca24af --- /dev/null +++ b/docs/api/publisher/output-path/index.html @@ -0,0 +1,259 @@ + + + + + + + + + + output_path | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

output_path

+ + + +
    + +
  • Property of Publisher
  • + + + +
  • New in Lektor Version 2.0
  • + +
+ +

This attribute holds the path to the folder where the build process put the +final artifacts. Usually a publisher walks that folder and does something +with all contents of it. The publishers however are heavily encouraged to +ignore the special .lektor folder which contains lektor specific information +that should not end up on the resulting server.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/publisher/publish/index.html b/docs/api/publisher/publish/index.html new file mode 100644 index 00000000..0f40207b --- /dev/null +++ b/docs/api/publisher/publish/index.html @@ -0,0 +1,324 @@ + + + + + + + + + + publish | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

publish (target_url, credentials=None, **extra)

+ + + +
    + +
  • Method of Publisher
  • + + + +
  • New in Lektor Version 2.0
  • + +
+ +

This method implements the actual publishing process. It's supposed to +implement a generator that reports the progress of the publishing. If at any +point something happens that would cause an error for the deployment this can +be signalled with the fail method which aborts the execution +and reports an error.

+

The parameters to the function are as follows:

+
    +
  • target_url: a URL object with the parsed URL. This object comes from the +Werkzeug library and gives access to the individual parts of a URL by the +exposed attributes (Read about the URL object).
  • +
  • credentials: an optional dictionary with command line supplied credentials. +Note that these credentials might be completely absent and the keys which are +provided might change with future versions of Lektor.
  • +
  • **extra: for forwards compatibility publishers are required to ignore extra +keyword arguments.
  • +
+

Each line in the generator must be a string which is then either logged to +the output in the console or in the deploy/publish window in the admin UI.

+

Example

This example implements a simple publisher that just copies all built files +into a new location.

+
import os
+import shutil
+from lektor.publisher import Publisher
+
+
+class CopyPublisher(Publisher):
+
+    def publish(self, target_url, credentials=None, **extra):
+        src_path = self.output_path
+        dst_path = target_url.path
+        strip = len(src_path) + 1
+
+        for path, folders, filenames in os.walk(src_path):
+            # Ignore the .lektor folder.
+            folders[:] = [x for x in folders if x != '.lektor']
+
+            # Copy all files over
+            for filename in filenames:
+                full_path = os.path.join(src_path, path, filename)
+                dst = os.path.join(path, full_path[strip:])
+
+                # Make sure the destination folder exists.
+                try:
+                    os.makedirs(os.path.dirname(dst))
+                except (OSError, IOError):
+                    pass
+
+                # Copy the file
+                yield 'Copy %s' % filename
+                shutil.copy(full_path, dst)
+
+        yield 'Done'
+
+
+class MyPlugin(Plugin):
+    def on_setup_env(self, **extra):
+        self.env.add_publisher('copy', CopyPublisher)
+
+

This publisher registers with the copy scheme and could be used like this:

+
target_url = copy:///path/to/destination/folder
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/templates/filters/asseturl/index.html b/docs/api/templates/filters/asseturl/index.html new file mode 100644 index 00000000..290334ae --- /dev/null +++ b/docs/api/templates/filters/asseturl/index.html @@ -0,0 +1,288 @@ + + + + + + + + + + asseturl | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

asseturl (alt=None)

+ + + +
    + + + +
+ +

This works similar to the url one but can only link to assets from +the assets/ folder. However unlike |url it will append a dummy query +string with a hash of the source asset. This ensures that when the asset +changes it will be newly cached.

+

Example

<link rel="stylesheet" href="{{ '/static/styles.css'|asseturl }}">
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/templates/filters/dateformat/index.html b/docs/api/templates/filters/dateformat/index.html new file mode 100644 index 00000000..6b593787 --- /dev/null +++ b/docs/api/templates/filters/dateformat/index.html @@ -0,0 +1,319 @@ + + + + + + + + + + dateformat | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

dateformat (date, format='medium', locale=None)

+ + + +
    + + + +
+ +

To format a proper date (this is created by the date type) into a string this filter can +be used. It will automatically format based on the language used by the +current context which is based on the locale of the current alt.

+

A different language can be provided with the locale parameter.

+

The following formats are locale specific:

+ + + + + + + + + + + + + + + + + + + + + + + + +
FormatHow it Looks
fullSaturday, December 5, 2015
longDecember 5, 2015
mediumDec 5, 2015
short12/5/15
+

In addition to that format codes from the CLDR project can be used. For +more information see CLDR Date/Time Symbols.

+

Examples

<p>Date: {{ this.pub_date|dateformat('full') }}
+
+

Or with custom CLDR format strings:

+
<p>Date: {{ this.pub_date|dateformat('EEE, MMM d, ''yy') }}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/templates/filters/datetimeformat/index.html b/docs/api/templates/filters/datetimeformat/index.html new file mode 100644 index 00000000..dbc600bf --- /dev/null +++ b/docs/api/templates/filters/datetimeformat/index.html @@ -0,0 +1,319 @@ + + + + + + + + + + datetimeformat | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

datetimeformat (datetime, format='medium', locale=None)

+ + + +
    + + + +
+ +

To format a proper date (this is created by the datetime type) into a string this filter can +be used. It will automatically format based on the language used by the +current context which is based on the locale of the current alt.

+

A different language can be provided with the locale parameter.

+

The following formats are locale specific:

+ + + + + + + + + + + + + + + + + + + + + + + + +
FormatHow it Looks
fullWednesday, January 13, 2016 at 7:08:35 AM GMT+00:00
longJanuary 13, 2016 at 7:08:35 AM +0000
mediumJan 13, 2016, 7:08:35 AM
short1/13/16, 7:08 AM
+

In addition to that format codes from the CLDR project can be used. For +more information see CLDR Date/Time Symbols.

+

Examples

<p>Date: {{ this.pub_date|datetimeformat('full') }}
+
+

Or with custom CLDR format strings:

+
<p>Date: {{ this.pub_date|datetimeformat('yyyyy.MMMM.dd GGG hh:mm a') }}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/templates/filters/index.html b/docs/api/templates/filters/index.html new file mode 100644 index 00000000..d905a806 --- /dev/null +++ b/docs/api/templates/filters/index.html @@ -0,0 +1,387 @@ + + + + + + + + + + Filters | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

Filters

+ + + +
    + + + +
+ +

These is the list of custom filters added by Lektor in addition to the +built in filters.

+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/templates/filters/latformat/index.html b/docs/api/templates/filters/latformat/index.html new file mode 100644 index 00000000..6bef8b79 --- /dev/null +++ b/docs/api/templates/filters/latformat/index.html @@ -0,0 +1,288 @@ + + + + + + + + + + latformat | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

latformat (value, secs=True)

+ + + +
    + + + +
+ +

This formats a latitude in float format into a human readable string in the +format degrees, minutes and seconds. See also longformat +and latlongformat.

+

Examples

<p>Lat: {{ image.exif.latitude|latformat }}
+<p>Long: {{ image.exif.longitude|longformat }}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/templates/filters/latlongformat/index.html b/docs/api/templates/filters/latlongformat/index.html new file mode 100644 index 00000000..ea5428ff --- /dev/null +++ b/docs/api/templates/filters/latlongformat/index.html @@ -0,0 +1,286 @@ + + + + + + + + + + latlongformat | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

latlongformat (value, secs=True)

+ + + +
    + + + +
+ +

This formats a latitude and longitude tuple into a human readable string +in the format degrees, minutes and seconds. See also latformat and longformat.

+

Examples

<p>Location: {{ image.exif.location|latlongformat }}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/templates/filters/longformat/index.html b/docs/api/templates/filters/longformat/index.html new file mode 100644 index 00000000..f1a6f27c --- /dev/null +++ b/docs/api/templates/filters/longformat/index.html @@ -0,0 +1,288 @@ + + + + + + + + + + longformat | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

longformat (value, secs=True)

+ + + +
    + + + +
+ +

This formats a longitude in float format into a human readable string in the +format degrees, minutes and seconds. See also latformat +and latlongformat.

+

Examples

<p>Lat: {{ image.exif.latitude|latformat }}
+<p>Long: {{ image.exif.longitude|longformat }}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/templates/filters/markdown/index.html b/docs/api/templates/filters/markdown/index.html new file mode 100644 index 00000000..0fe199a2 --- /dev/null +++ b/docs/api/templates/filters/markdown/index.html @@ -0,0 +1,290 @@ + + + + + + + + + + markdown | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

markdown (source)

+ + + +
    + + + +
  • New in Lektor Version 2.0
  • + +
+ +

This filter converts a markdown string into HTML. This behaves the same as +the Markdown Type.

+

Example

<div class="example">
+  {{ "Hello **World**"|markdown }}
+</div>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/templates/filters/tojson/index.html b/docs/api/templates/filters/tojson/index.html new file mode 100644 index 00000000..0d5b14c7 --- /dev/null +++ b/docs/api/templates/filters/tojson/index.html @@ -0,0 +1,294 @@ + + + + + + + + + + tojson | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

tojson ()

+ + + +
    + + + +
+ +

This filter converts a value to JSON. It supports any of the types that are +supported by JSON directly and the return value will be in a format that +allows safe embedding in HTML. However if you want to use this value in an +attribute of an element it needs to use single quotes otherwise it will +generate a syntax error due to the embedded quotes.

+

Examples

<script type="text/javascript">
+  var options = {{ {'foo': 'bar'}|tojson }};
+</script>
+
+

If used in attributes, single quotes are required:

+
<a href="#" data-foo='{{ my_data|tojson }}'>Click here</a>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/templates/filters/url/index.html b/docs/api/templates/filters/url/index.html new file mode 100644 index 00000000..34fc85d5 --- /dev/null +++ b/docs/api/templates/filters/url/index.html @@ -0,0 +1,310 @@ + + + + + + + + + + url | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

url (alt=None, absolute=None, external=None)

+ + + +
    + + + +
+ +

This filter is the most useful filter for URL generation and it comes in two +flavors. It takes one optional argument which is the alt if it should +differ from the current one (see Alternatives). +The filter can be applied to either a string or a Record object.

+

Note that the URL filter operates on paths as they exist in your tree, not +as the final URLs. This is important when a page forcefully overrides the +URL path. In this case it could be that linking to /project for instance +would generate the URL de/projekte/ if that's what's configured.

+

If you want to override this behavior you can prefix the URL with ! and +no resolving will take place.

+

Note that the URL filter always generates a relative URL. So for instance +if you are currently at /info/about/ and you want to link to /projects/ +it will generate a link in the form of ../../projects/. This makes it +possible to easily deploy the website to a folder outside of the root of +the website.

+

Examples

<ul class="nav">
+  <li><a href="{{ '/'|url }}">Index</a></li>
+  <li><a href="{{ '/about'|url }}">About</a></li>
+</ul>
+
+

Same page to other alternative:

+
<a href="{{ '.'|url(alt='ru') }}">Русский</a>
+
+

If you already know 100% where to link to, and you do not want any resolving +to take place, then you can prefix a path with !. For instance this always +links to the root of the website:

+
<a href="{{ '!/'|url }}">To Root</a>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/templates/globals/bag/index.html b/docs/api/templates/globals/bag/index.html new file mode 100644 index 00000000..b8c6bb2b --- /dev/null +++ b/docs/api/templates/globals/bag/index.html @@ -0,0 +1,283 @@ + + + + + + + + + + bag | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

bag (...)

+ + + +
    + + +
  • Template variable: bag
  • + + +
+ +

This handy function can look up data from Databags. +The path to the values is a dotted path but alternatively multiple parameters +can be provided that will be concatenated into a dotted path.

+

Simple Example

<title>{{ bag('site.title') }}</title>
+
+

alternative method that does the same:

+
<title>{{ bag('site', 'title') }}</title>
+
+

Example with Alternatives

Because you can use arbitrary variables in it, this is a simple way to +load translations from a data bag:

+
<a href="#">{{ bag('i18n', alt, 'CLICK_HERE') }}</a>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/templates/globals/f/index.html b/docs/api/templates/globals/f/index.html new file mode 100644 index 00000000..98625f59 --- /dev/null +++ b/docs/api/templates/globals/f/index.html @@ -0,0 +1,262 @@ + + + + + + + + + + F | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

F

+ + + +
    + + +
  • Template variable: F
  • + + +
+ +

This gives access to the F object for creating +expressions involving fields. For more information see the page there.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/templates/globals/get-random-id/index.html b/docs/api/templates/globals/get-random-id/index.html new file mode 100644 index 00000000..01c5c4b5 --- /dev/null +++ b/docs/api/templates/globals/get-random-id/index.html @@ -0,0 +1,276 @@ + + + + + + + + + + get_random_id | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

get_random_id ()

+ + + + + +

In some situations it can be very useful to generate a unique ID in templates. +This is particularly useful when creating templates for the Flow system and you need unique IDs for the DOM.

+

Example

{% set id = get_random_id() %}
+<div id="{{ id }}">
+  <button data-target="{{ id }}" class="toggle">Hide This</button>
+</div>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/templates/globals/index.html b/docs/api/templates/globals/index.html new file mode 100644 index 00000000..346636d1 --- /dev/null +++ b/docs/api/templates/globals/index.html @@ -0,0 +1,311 @@ + + + + + + + + + + Globals | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

Globals

+ + + +
    + + + +
+ +

Certain variables and functions are always available in templates. Mostly this +gives you access to things like the Pad but also useful +helper functions.

+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/templates/globals/site/index.html b/docs/api/templates/globals/site/index.html new file mode 100644 index 00000000..853b25ae --- /dev/null +++ b/docs/api/templates/globals/site/index.html @@ -0,0 +1,262 @@ + + + + + + + + + + site | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

site

+ + + +
    + + +
  • Template variable: site
  • + + +
+ +

This gives access to the current database Pad. For +more information see the page there.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/templates/index.html b/docs/api/templates/index.html new file mode 100644 index 00000000..e1363bef --- /dev/null +++ b/docs/api/templates/index.html @@ -0,0 +1,273 @@ + + + + + + + + + + Template API | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

Template API

+ + + +
    + + + +
+ +

Lektor extends the Jinja2 templating language +with many useful helpers. We do not document Jinja 2 itself here, but all +the specific helpers are explained.

+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/utils/build-url/index.html b/docs/api/utils/build-url/index.html new file mode 100644 index 00000000..398477c6 --- /dev/null +++ b/docs/api/utils/build-url/index.html @@ -0,0 +1,281 @@ + + + + + + + + + + build_url | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

lektor.utils.build_url (pieces, trailing_slash=None)

+ + + +
    + + + +
  • New in Lektor Version 2.0
  • + +
+ +

This function assists in creating URL paths from individual segments. This +is particularly useful for building virtual source objects. It takes a bunch +of path segments and returns an absolute path. The default behavior is to +guess the trailing slash based on the presence of a dot in the last path +segment. If you want to override the detection you can explicitly pass +True to enforce a trailing slash or False to avoid it.

+

Example

>>> from lektor.utils import build_url
+>>> build_url(['foo', 42])
+u'/foo/42/'
+>>> build_url(['foo', None, 23])
+u'/foo/23/'
+>>> build_url(['foo', 'hello.html'])
+u'/foo/hello.html'
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/utils/get-structure-hash/index.html b/docs/api/utils/get-structure-hash/index.html new file mode 100644 index 00000000..b1393415 --- /dev/null +++ b/docs/api/utils/get-structure-hash/index.html @@ -0,0 +1,274 @@ + + + + + + + + + + get_structure_hash | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

lektor.utils.get_structure_hash (params)

+ + + +
    + + + +
+ +

Given a Python object (typically a dictionary or tuple) it generates a stable +MD5 hash from those recursively. This is useful for the config_hash +parameter with artifacts.

+

Example

>>> from lektor.utils import get_structure_hash
+>>> get_structure_hash([1, 2, 3])
+'fbcf00cb8f6fc7631af7fbff70ca6f87'
+>>> get_structure_hash([1, 2, 3, 4])
+'390e449c9748b72d6b9194a1c768d434'
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/utils/index.html b/docs/api/utils/index.html new file mode 100644 index 00000000..a424a66d --- /dev/null +++ b/docs/api/utils/index.html @@ -0,0 +1,332 @@ + + + + + + + + + + Utilities | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

Utilities

+ + + +
    + + + +
+ +

For plugins there are some useful utilities provided with Lektor. This list +will only grow with time.

+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/utils/join-path/index.html b/docs/api/utils/join-path/index.html new file mode 100644 index 00000000..43dea1ea --- /dev/null +++ b/docs/api/utils/join-path/index.html @@ -0,0 +1,289 @@ + + + + + + + + + + join_path | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

lektor.utils.join_path (a, b)

+ + + +
    + + + +
  • New in Lektor Version 2.0
  • + +
+ +

Given two Lektor paths this joins them together with the rules that Lektor +set up for this. In particular this is important in the presence of +virtual paths which have their own join semantics.

+

Example

>>> from lektor.utils import join_path
+>>> join_path('/blog', 'hello-world')
+'/blog/hello-world'
+>>> join_path('/blog', '@archive')
+'/blog@archive'
+>>> join_path('/blog@archive', '2015')
+'/blog@archive/2015'
+>>> join_path('/blog@archive/2015', '..')
+'/blog@archive'
+>>> join_path('/blog@archive', '..')
+'/blog'
+
+

Special note should be taken for the numeric virtual path of paginations. It +is considered to be on the same level as the actual record:

+
>>> join_path('/blog@2', '..')
+'/'
+>>> join_path('/blog@2', '.')
+'/blog@2'
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/utils/parse-path/index.html b/docs/api/utils/parse-path/index.html new file mode 100644 index 00000000..0715cc0f --- /dev/null +++ b/docs/api/utils/parse-path/index.html @@ -0,0 +1,276 @@ + + + + + + + + + + parse_path | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

lektor.utils.parse_path ()

+ + + +
    + + + +
  • New in Lektor Version 2.0
  • + +
+ +

This function parses a path into the individual components it's made from. +The path is always assumed to be absolute and made absolute if it's not yet +so. The root path is the empty list.

+

Example

>>> from lektor.utils import parse_path
+>>> parse_path('/foo/bar')
+['foo', 'bar']
+>>> parse_path('/')
+[]
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/utils/process-image/index.html b/docs/api/utils/process-image/index.html new file mode 100644 index 00000000..96208e6e --- /dev/null +++ b/docs/api/utils/process-image/index.html @@ -0,0 +1,297 @@ + + + + + + + + + + process_image | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

lektor.imagetools.process_image (ctx, source_image, dst_filename, width=None, height=None, mode=ThumbnailMode.DEFAULT)

+ + + +
    + + + +
  • New in Lektor Version 2.0
  • + +
+ +

This function takes a Context object, the +absolute paths to the image's source and target files, the target image's +width and/or height, and the operation mode. +In the default mode, if width or height are None, they are calculated +from the source image's dimensions so that the image is scaled proportionally.

+

Used internally for the implementation of thumbnail, and exposed as an API for image-processing plugins.

+

Example

from lektor.build_programs import AttachmentBuildProgram
+from lektor.context import get_ctx
+from lektor.db import Image
+from lektor.imagetools import process_image, ThumbnailMode
+from lektor.pluginsystem import Plugin
+
+
+class ImageCropBuildProgram(AttachmentBuildProgram):
+    def build_artifact(self, artifact):
+        ctx = get_ctx()
+        width, height = 600, 400
+        source_img = artifact.source_obj.attachment_filename
+        artifact.ensure_dir()
+
+        process_image(ctx,
+                      source_img,
+                      artifact.dst_filename,
+                      width, height, mode=ThumbnailMode.CROP)
+
+
+class ImageCropPlugin(Plugin):
+    def on_setup_env(self, **extra):
+        self.env.add_build_program(Image, ImageCropBuildProgram)
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/api/utils/url-to/index.html b/docs/api/utils/url-to/index.html new file mode 100644 index 00000000..452c616e --- /dev/null +++ b/docs/api/utils/url-to/index.html @@ -0,0 +1,261 @@ + + + + + + + + + + url_to | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

lektor.context.url_to (path, alt=None, absolute=None, external=None)

+ + + +
    + + + +
+ +

Calculates the URL from the current source object on the context to the given +other source object. Alternatively a path can also be provided instead of a +source object. If the path starts with a leading bang (!) then no +resolving is performed. If no alt is provided the alt of the page is used.

+

This works exactly the same as the method with the same name on source objects.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/cli/build/index.html b/docs/cli/build/index.html new file mode 100644 index 00000000..9519630f --- /dev/null +++ b/docs/cli/build/index.html @@ -0,0 +1,274 @@ + + + + + + + + + + build | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

build

+ + + +
    + + + +
+ +

lektor build

+

Builds the entire project into the final artifacts.

+

The default behavior is to build the project into the default build +output path which can be discovered with the project-info command +but an alternative output folder can be provided with the --output-path +option.

+

The default behavior is to perform a build followed by a pruning step +which removes no longer referenced artifacts from the output folder. +Lektor will only build the files that require rebuilding if the output +folder is reused.

+

To enforce a clean build you have to issue a clean command first.

+

If the build fails the exit code will be 1 otherwise 0. This can be +used by external scripts to only deploy on successful build for instance.

+

Options

    +
  • -O, --output-path PATH: The output path.
  • +
  • --watch: If this is enabled the build process goes into an automatic +loop where it watches the file system for changes and rebuilds.
  • +
  • --prune / --no-prune: Controls if old artifacts should be pruned. +This is the default.
  • +
  • -v, --verbose: Increases the verbosity of the logging.
  • +
  • --source-info-only: Instead of building only updates the source infos. +The source info is used by the web admin panel to quickly find +information about the source files (for instance jump to files).
  • +
  • -f, --build-flag TEXT: Defines an arbitrary build flag. These can be +used by plugins to customize the build process. More information can be +found in the documentation of affected plugins.
  • +
  • --profile: Enable build profiler.
  • +
  • --help: print this help page.
  • +
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/cli/clean/index.html b/docs/cli/clean/index.html new file mode 100644 index 00000000..f3b2cd98 --- /dev/null +++ b/docs/cli/clean/index.html @@ -0,0 +1,255 @@ + + + + + + + + + + clean | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

clean

+ + + +
    + + + +
+ +

lektor clean

+

Cleans the entire build folder.

+

If not build folder is provided, the default build folder of the project +in the Lektor cache is used.

+

Options

    +
  • -O, --output-path PATH: The output path.
  • +
  • -v, --verbose: Increases the verbosity of the logging.
  • +
  • --yes: Confirms the cleaning.
  • +
  • --help: print this help page.
  • +
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/cli/content-file-info/index.html b/docs/cli/content-file-info/index.html new file mode 100644 index 00000000..fa9181f3 --- /dev/null +++ b/docs/cli/content-file-info/index.html @@ -0,0 +1,253 @@ + + + + + + + + + + content-file-info | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

content-file-info

+ + + +
    + + + +
+ +

lektor content-file-info [FILES]...

+

Given a list of files this returns the information for those files +in the context of a project. If the files are from different projects +an error is generated.

+

Options

    +
  • --json: Prints out the data as json.
  • +
  • --help: print this help page.
  • +
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/cli/deploy/index.html b/docs/cli/deploy/index.html new file mode 100644 index 00000000..534984e0 --- /dev/null +++ b/docs/cli/deploy/index.html @@ -0,0 +1,268 @@ + + + + + + + + + + deploy | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

deploy

+ + + +
    + + + +
+ +

lektor deploy [SERVER]

+

This command deploys the entire contents of the build folder +(--output-path) onto a configured remote server. The name of the +server must fit the name from a target in the project configuration. +If no server is supplied then the default server from the config is +used.

+

The deployment credentials are typically contained in the project config +file but it's also possible to supply them here explicitly. In this +case the --username and --password parameters (as well as the +LEKTOR_DEPLOY_USERNAME and LEKTOR_DEPLOY_PASSWORD environment +variables) can override what's in the URL.

+

For more information see the deployment chapter in the documentation.

+

Options

    +
  • -O, --output-path PATH: The output path.
  • +
  • --username TEXT: An optional username to override the URL.
  • +
  • --password TEXT: An optional password to override the URL or the +default prompt.
  • +
  • --key-file TEXT: The path to a key file that should be used for the +authentication of the deployment.
  • +
  • --key TEXT: The contents of a key file directly a string that should +be used for authentication of the deployment.
  • +
  • --help: print this help page.
  • +
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/cli/dev/index.html b/docs/cli/dev/index.html new file mode 100644 index 00000000..c6f90e28 --- /dev/null +++ b/docs/cli/dev/index.html @@ -0,0 +1,305 @@ + + + + + + + + + + dev | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

dev

+ + + +
    + + + +
+ +

lektor dev

+

Development commands for Lektor.

+

This provides various development support commands for Lektor. This is +primarily useful for Lektor plugin development but also if you want to +extend Lektor itself. Additional functionality can be unlocked by +exporting the LEKTOR_DEV=1 environment variable.

+

Options

    +
  • --help: print this help page.
  • +
+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/cli/dev/new-plugin/index.html b/docs/cli/dev/new-plugin/index.html new file mode 100644 index 00000000..14e7774b --- /dev/null +++ b/docs/cli/dev/new-plugin/index.html @@ -0,0 +1,266 @@ + + + + + + + + + + new-plugin | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

new-plugin

+ + + +
    + + + +
+ +

lektor dev new-plugin [PLUGIN_NAME]

+

This command creates a new plugin.

+

This will present you with a very short wizard that guides you through +creation of a new plugin. At the end of it, it will create a plugin +in the packages folder of the current project or the path you defined.

+

This is the fastest way to creating a new plugin.

+

Options

    +
  • --path PATH: The destination path
  • +
  • --help: print this help page.
  • +
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/cli/dev/publish-plugin/index.html b/docs/cli/dev/publish-plugin/index.html new file mode 100644 index 00000000..d38a9cfc --- /dev/null +++ b/docs/cli/dev/publish-plugin/index.html @@ -0,0 +1,263 @@ + + + + + + + + + + publish-plugin | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

publish-plugin

+ + + +
    + + + +
+ +

lektor dev publish-plugin

+

Publishes the current version of the plugin in the current folder.

+

This generally requires that your setup.py has at least the bare minimum +configuration for valid publishing to PyPI.

+

Options

    +
  • --help: print this help page.
  • +
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/cli/dev/shell/index.html b/docs/cli/dev/shell/index.html new file mode 100644 index 00000000..14cfed5b --- /dev/null +++ b/docs/cli/dev/shell/index.html @@ -0,0 +1,270 @@ + + + + + + + + + + shell | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

shell

+ + + +
    + + + +
+ +

lektor dev shell

+

Starts a Python shell in the context of a Lektor project.

+

This is particularly useful for debugging plugins and to explore the +API. To quit the shell just use quit(). Within the shell various +utilities are available right from the get-go for you.

+
    +
  • project: the loaded project as object.
  • +
  • env: an environment for the loaded project.
  • +
  • pad: a database pad initialized for the project and environment +that is ready to use.
  • +
+

Options

    +
  • --help: print this help page.
  • +
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/cli/index.html b/docs/cli/index.html new file mode 100644 index 00000000..c8a836ff --- /dev/null +++ b/docs/cli/index.html @@ -0,0 +1,393 @@ + + + + + + + + + + Command Line | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

Command Line

+ + + +
    + + + +
+ +

Lektor comes with a handy lektor command line executable you can use from +your terminal to manage all of Lektor in addition to the GUI. If you do +not have the Lektor command available because you only installed the GUI, +have a look at Installation Documentation to see +how to remedy this.

+

All the commands documented here show up as subcommands to the global +lektor command. So to invoke build you would write lektor build.

+

Options

There are some general options that can be set on the lektor command +to change the behavior.

+
    +
  • --project PATH: explicitly provide the path to the project to work on. +If this is not provided then the project is searched upwards from the +current working directory until a folder is found with a single +.lektorproject file in it.
  • +
  • --language LANG: admin interface language, defaults to en. Available +options are: ca, de, en, es, fr, it, ja, ko, nl, pl, +pt, ru, zh.
  • +
  • --version: if this is passed it prints out the version of Lektor and +aborts further execution.
  • +
  • --help: prints out help about the command line interface.
  • +
+

Environment Variables

There are a few environment variables which control how Lektor executes:

+

LEKTOR_PROJECT

+

This can be used alternatively to --project to set the path to a +project that Lektor should be using. If neither this variable nor +--project is set, Lektor will look for a project upwards from the current +working directory.

+
+

LEKTOR_OUTPUT_PATH

+

Overrides the default output path with a different path. By default the +output path will be a path unique to the project but in a default cache +folder under Lektor's control. --output-path on some commands overrides +this value.

+
+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/cli/plugins/add/index.html b/docs/cli/plugins/add/index.html new file mode 100644 index 00000000..a80edb74 --- /dev/null +++ b/docs/cli/plugins/add/index.html @@ -0,0 +1,272 @@ + + + + + + + + + + add | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

add

+ + + +
    + + + +
+ +

lektor plugins add NAME

+

This command can add a new plugin to the project. If just given +the name of the plugin the latest version of that plugin is added to +the project.

+

The argument is either the name of the plugin or the name of the plugin +suffixed with @version with the version. For instance to install +the version 0.1 of the plugin demo you would do demo@0.1.

+

Options

    +
  • --help: print this help page.
  • +
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/cli/plugins/flush-cache/index.html b/docs/cli/plugins/flush-cache/index.html new file mode 100644 index 00000000..955fdd67 --- /dev/null +++ b/docs/cli/plugins/flush-cache/index.html @@ -0,0 +1,269 @@ + + + + + + + + + + flush-cache | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

flush-cache

+ + + +
    + + + +
+ +

lektor plugins flush-cache

+

This uninstalls all plugins in the cache. On next usage the plugins +will be reinstalled automatically. This is mostly just useful during +plugin development when the cache got corrupted.

+

Options

    +
  • --help: print this help page.
  • +
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/cli/plugins/index.html b/docs/cli/plugins/index.html new file mode 100644 index 00000000..e385e437 --- /dev/null +++ b/docs/cli/plugins/index.html @@ -0,0 +1,332 @@ + + + + + + + + + + plugins | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

plugins

+ + + +
    + + + +
+ +

lektor plugins

+

This command group provides various helpers to manages plugins +in a Lektor project.

+

Options

    +
  • --help: print this help page.
  • +
+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/cli/plugins/list/index.html b/docs/cli/plugins/list/index.html new file mode 100644 index 00000000..f4cbfae2 --- /dev/null +++ b/docs/cli/plugins/list/index.html @@ -0,0 +1,273 @@ + + + + + + + + + + list | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

list

+ + + +
    + + + +
+ +

lektor plugins list

+

This returns a list of all currently actively installed plugins +in the project. By default it only prints out the plugin IDs and +version numbers but the entire information can be returned by +increasing verbosity with -v. Additionally JSON output can be +requested with --json.

+

Options

    +
  • --json: Prints out the data as json.
  • +
  • -v, --verbose: Increases the verbosity of the output.
  • +
  • --help: print this help page.
  • +
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/cli/plugins/reinstall/index.html b/docs/cli/plugins/reinstall/index.html new file mode 100644 index 00000000..00716f48 --- /dev/null +++ b/docs/cli/plugins/reinstall/index.html @@ -0,0 +1,271 @@ + + + + + + + + + + reinstall | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

reinstall

+ + + +
    + + + +
+ +

lektor plugins reinstall

+

Forces a re-installation of all plugins. This will download the +requested versions of the plugins and install them into the plugin +cache folder. Alternatively one can just use flush-cache to +flush the cache and on next build Lektor will automatically download +the plugins again.

+

Options

    +
  • --help: print this help page.
  • +
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/cli/plugins/remove/index.html b/docs/cli/plugins/remove/index.html new file mode 100644 index 00000000..6e53e9fd --- /dev/null +++ b/docs/cli/plugins/remove/index.html @@ -0,0 +1,268 @@ + + + + + + + + + + remove | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

remove

+ + + +
    + + + +
+ +

lektor plugins remove NAME

+

This command can remove a plugion to the project again. The name +of the plugin is the only argument to the function.

+

Options

    +
  • --help: print this help page.
  • +
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/cli/project-info/index.html b/docs/cli/project-info/index.html new file mode 100644 index 00000000..a4a1fdc4 --- /dev/null +++ b/docs/cli/project-info/index.html @@ -0,0 +1,258 @@ + + + + + + + + + + project-info | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

project-info

+ + + +
    + + + +
+ +

lektor project-info

+

Prints out information about the project. This is particular +useful for script usage or for discovering information about a +Lektor project that is not immediately obvious (like the paths +to the default output folder).

+

Options

    +
  • --json: Prints out the data as json.
  • +
  • --name: Print the project name
  • +
  • --project-file: Print the path to the project file.
  • +
  • --tree: Print the path to the tree.
  • +
  • --output-path: Print the path to the default output path.
  • +
  • --help: print this help page.
  • +
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/cli/quickstart/index.html b/docs/cli/quickstart/index.html new file mode 100644 index 00000000..954227c8 --- /dev/null +++ b/docs/cli/quickstart/index.html @@ -0,0 +1,252 @@ + + + + + + + + + + quickstart | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

quickstart

+ + + +
    + + + +
+ +

lektor quickstart

+

Starts a new empty project with a minimum boilerplate.

+

Options

    +
  • --name TEXT: The name of the project.
  • +
  • --path PATH: Output directory
  • +
  • --help: print this help page.
  • +
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/cli/server/index.html b/docs/cli/server/index.html new file mode 100644 index 00000000..bb03770f --- /dev/null +++ b/docs/cli/server/index.html @@ -0,0 +1,264 @@ + + + + + + + + + + server | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

server

+ + + +
    + + + +
+ +

lektor server

+

The server command will launch a local server for development.

+

Lektor's developemnt server will automatically build all files into +pages similar to how the build command with the --watch switch +works, but also at the same time serve up the website on a local +HTTP server.

+

Options

    +
  • -h, --host TEXT: The network interface to bind to. The default is the +loopback device, but by setting it to 0.0.0.0 it becomes available on +all network interfaces.
  • +
  • -p, --port INTEGER: The port to bind to.
  • +
  • -O, --output-path PATH: The dev server will build into the same folder +as the build command by default.
  • +
  • -v, --verbose: Increases the verbosity of the logging.
  • +
  • -f, --build-flag TEXT: Defines an arbitrary build flag. These can be +used by plugins to customize the build process. More information can be +found in the documentation of affected plugins.
  • +
  • --help: print this help page.
  • +
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/content/alts/index.html b/docs/content/alts/index.html new file mode 100644 index 00000000..07d5775f --- /dev/null +++ b/docs/content/alts/index.html @@ -0,0 +1,370 @@ + + + + + + + + + + Alternatives | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

Alternatives

+ + + +
    + + + +
+ +

One particularly useful feature of Lektor is the ability to define alternatives +to a content file. This allows you to translate your website into many +different languages or to customize content specifically for some languages +or regions.

+

Alternatives are a fully functional feature in Lektor but very +underdocumented and lacking in parts. The result of this is that it might not +be working exactly as you expect in parts. In particular one of the limiting +factors is that you need to have at least one alternative at the URL root or +the system will refuse to build the website.

Enabling Alternatives

To enable alternatives you need to extend your Project File. For each alternative a new +section has to be added. It's important that one of the alternatives is +marked as "primary" which informs the system which of the alternatives is +the reference.

+
[alternatives.en]
+name = English
+primary = yes
+locale = en_US
+
+[alternatives.fr]
+name = French
+url_prefix = /fr/
+locale = fr
+
+

The locale key is used to define the locale that Lektor assumes for the +alternative. This is for instance used for date formatting.

+

Content Files of Alternatives

Once alternatives are enabled your website will be built multiple times. Once +for each alternative. By default nothing will change as no content files +exist for the non primary alternatives. In the example of above if you +navigate to /fr/ you will see the same index page as if you would have +navigated to /.

+

However you can now start translating your content. Each alternative has +a content file named contents+ALT.lr where ALT is the short code of your +alternative (for instance fr for French). Once a file for an alternative +exists it's loaded instead of the default contents.lr file.

+

What's Loaded

To make this a bit more concrete: let's go with the example we configured +above. There are two alternatives: English (en) and French (fr) and +English is configured as the primary.

+

In that case depending on which files exist and which alternative is +targeted, different files will be used. This table visualizes this:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
contents.lrcontents+fr.lrcontents+en.lrTargetFile Used
encontents.lr
frcontents.lr
encontents.lr
frcontents+fr.lr
encontents+en.lr
frcontents+fr.lr
enmissing
frcontents+fr.lr
encontents+en.lr
frmissing
+

Alternatives and Paths

Alternatives have a special behavior with regards to paths. The alternative +code does not exist in the path! This can be confusing at first, but has the +advantage that they automatically work in most places as the paths are the +same for different alternatives. For more information see +Alternatives and Paths.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/content/attachments/index.html b/docs/content/attachments/index.html new file mode 100644 index 00000000..dce47b5c --- /dev/null +++ b/docs/content/attachments/index.html @@ -0,0 +1,300 @@ + + + + + + + + + + Attachments | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

Attachments

+ + + +
    + + + +
+ +

Each page in Lektor can have attachments appended. These files are stored +directly in the page folder and become available publicly.

+

Attachment Types

For the most part Lektor does not care much about what types your attachments +are but it will specially handle some. In particular image formats supported +by browsers have special support for automatic thumbnailing and accessing +basic image data.

+

The following file formats are specially handled:

+ + + + + + + + + + + + + + + + + + + + +
TypeExtensions
Image.jpg .jpeg .gif .png
Video.avi, .mpg, .mpeg, .wmv, .ogv
Audio.mp3, .wav, .ogg
+

Metadata

Attachments can also be given metadata. For this you need to create a lektor +content file with the same name as the attachment but with .lr added as +extra extension:

+ + + + + + + + + + + + + + + + +
FileMetadata file
sunset.jpegsunset.jpeg.lr
code.pycode.py.lr
+

Attachments can be given a default model or +a model can be explicitly given in the metadata content file with the _model field.

+

Here is a basic example:

+
_model: image
+---
+description: A beautiful sunset.
+---
+photographer: Mr. Peter John Doe
+---
+copyright: 2015 by Mr. Peter John Doe
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/content/databags/index.html b/docs/content/databags/index.html new file mode 100644 index 00000000..10f05ada --- /dev/null +++ b/docs/content/databags/index.html @@ -0,0 +1,282 @@ + + + + + + + + + + Data Bags | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

Data Bags

+ + + +
    + + + +
+ +

The Data Bags are a quick way to store structured +information that templates can access. It's just a convenient way to access +data from INI or JSON files. This is useful for instance to build a navigation +menu or similar things.

+

Creating Bags

To create a data bag just place a .ini or .json file in the databags/ +folder. The files there are accessible by their name sans the file extension. +All ordering in the source files is retained. So for instance this could +be the main-nav.ini data file for a basic navigation:

+
/downloads = Download
+/docs = Documentation
+/blog = Blog
+
+

And the template could access it like this:

+
<ul class="nav">
+{% for path, label in bag('main-nav').items() %}
+  <li{% if this.is_child_of(path) %} class="active"{% endif
+    %}><a href="{{ path|url }}">{{ label }}</a>
+  </li>
+{% endfor %}
+</ul>
+
+

Nested Access

Data bags can be structured in more complex ways. For INI files sections +can be used, for JSON files entire object trees can be stored. The +bag function can thus accept +arbitrary dotted path (or multiple args to bag) to navigate to specific items +within the bag. For instance you could use this to look up values that might +change depending on the alternative of a page for instance.

+

In this case the system is used to translate buttons. Take buttons.ini +as an example:

+
[en]
+download = Download
+
+[de]
+download = Herunterladen
+
+[ru]
+download = Скачать
+
+

And in a template it could be used like this:

+
<h2>{{ bag('buttons', this.alt, 'download') }}</h2>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/content/flow/flow-admin.png b/docs/content/flow/flow-admin.png new file mode 100644 index 00000000..2e551429 Binary files /dev/null and b/docs/content/flow/flow-admin.png differ diff --git a/docs/content/flow/index.html b/docs/content/flow/index.html new file mode 100644 index 00000000..357640bf --- /dev/null +++ b/docs/content/flow/index.html @@ -0,0 +1,315 @@ + + + + + + + + + + Flow | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

Flow

+ + + +
    + + + +
+ +

Flow is a system in Lektor that allows you to have higher flexibility when +creating pages. The Flow Type field type +that allows you to store multiple different formats of data within the same +field each with its own template.

+

This allows you to build complex pages made from individual components.

+

How does Flow Work?

When you add a flow field to one of your models you essentially gain the +ability to attach as many blocks as you want into this field. Each block +corresponds to a specific Flow Block Model and +can render a separate template.

+

This is a very powerful feature as it allows you to be very flexible in the +designs you want to achieve for your website. As an example, the +Front Page of this website uses many different blocks to +implement the slideshow, feature list and more.

+

+

Flow Block Models

To use the flow type you need to define some blocks. This works pretty +much the same as with creating Data Models except they +go into the flowblocks folder and have slightly different parameters.

+

For more information about this see Flow Block Models.

+

Block Templating

Flow blocks appear as elements of the flow type. When it's rendered in a +template it will render each block separately one after another and connect +them with newlines. These blocks can also manually be accessed however. +Each flow block renders a template named after itself from the blocks +folder in the template directory. So if you have a flow block model +named text it will render from templates/blocks/text.html.

+

Within a template a flow block has access to all the variables that you would +expect. this points to the current block and record points to the record +the block is contained in.

+

This is a simple example of a typical template of a flow block:

+
<div class="text-block text-block-{{ this.class }}">
+  {{ this.text }}
+</div>
+
+

Some more involved templates might also refer back to the page to do something +with it. Here for instance is a simple flow block for including a thumbnail +of an attached image:

+
{% set img = record.attachments.images.get(this.image) %}
+{% if img %}
+  <div class="thumbnail-block">
+    <img src="{{ img.thumbnail(480)|url }}" alt="">
+  </div>
+{% endif %}
+
+

This also has a safeguard that if the image does not exist nothing is rendered +instead. This is a good idea because someone could delete the attachments but +not update the reference in the block.

+

Flow Templating

The default behavior of rendering an entire flow is to render the templates +of the individual blocks one after another. Sometimes that is not flexible +enough. Because of that you can access the blocks individually. This is +particularly useful for more complex situations where you either deal with +nested flows or where you want to wrap the individual blocks somehow.

+

For instance in this case the blocks are wrapped before rendering:

+
{% for blk in this.demo_flow.blocks %}
+  <div class="block block-{{ blk._flowblock }}">
+    {{ blk }}
+  </div>
+{% endfor %}
+
+

The _flowblock field is always available on a flow block and is the name +of the data model that defines it. This is a good way to also specifically +customize individual blocks in a flow without having to invoke their +templates. You can for instance completely manually render blocks without +using their templates:

+
{% for blk in this.demo_flow.blocks %}
+  {% if blk._flowblock == 'text' %}
+    <p>{{ blk.text }}
+  {% elif blk._flowblock == 'image' %}
+    <img src="{{ blk.image }}" alt="{{ blk.alt }}">
+  {% endif %}
+{% endfor %}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/content/index.html b/docs/content/index.html new file mode 100644 index 00000000..90299f31 --- /dev/null +++ b/docs/content/index.html @@ -0,0 +1,395 @@ + + + + + + + + + + Content | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

Content

+ + + +
    + + + +
+ +

Lektor builds a website by taking all the files in the content/ folder, +processing them according to the rules of your Models +and rendering them by using templates. Don't worry. It's easier than it +sounds.

+

One Folder — One Page

Each page (or each URL) corresponds to a folder below the content/ folder. +There can be as many folders as you want and they can be arbitrarily nested. +Within each folder there needs to be at least one file, the content file: +contents.lr. Into that file, your data goes.

+

All the other files in a folder are considered attachments of the page.

+

Here is an example structure from a website:

+
content/
+  contents.lr
+  portfolio/
+    contents.lr
+    project-a/
+      contents.lr
+      thumbnail.jpg
+    project-b/
+      contents.lr
+      thumbnail.jpg
+  about/
+    contents.lr
+
+

One Page — One URL

Out of each contents.lr file, Lektor builds exactly one final page on +exactly one URL. So if you have content/portfolio/project-a/contents.lr +the rendered end result will be at /portfolio/project-a/.

+

Page, Model and Template

Each page is associated with a model and a template. Each page needs to have +a model that defines which fields exist. The template by default matches the +model name but it can be overridden on a per-page basis.

+

So how is the model selected? Either explicitly in the contents.lr file +with the _model key or by configuration and convention. Lektor will +select the default model based on trying things in this order:

+
    +
  1. configured model in contents file
  2. +
  3. model configured from a parent model for all children
  4. +
  5. model matching the page ID
  6. +
  7. the model named page
  8. +
+

The template is always the name of the model with .html as extension. It +can be overridden in the content file with the _template field.

+

Content File Format

So now it's time to talk about the content file. The content file is just a +UTF-8 encoded text file with the .lr extension. It can be edited with any +text editor that supports UTF-8 as character encoding. This file consists of +multiple data fields according to the model. The format is very simple:

+
_model: page
+---
+title: The Page Title
+---
+body:
+
+The page body goes here
+
+

Fields are separated by three dashes --- and follow the format key: value. +For values with multiple lines it's recommended to insert two newlines after +the key. The format of each field is specific to how the model is configured.

+

Some fields are plain text, others can be markdown syntax and more. These +fields become available for rendering in the template automatically.

+

If you want to use --- itself in the document text, just add another +dash. This means ---- will render as --- and ----- will render as +---- etc.

Fields prefixed with an underscore are so-called system fields. They are +provided by Lektor and customize behavior within Lektor. For a list of +available fields see System Fields.

+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/content/paths/index.html b/docs/content/paths/index.html new file mode 100644 index 00000000..d86ec01a --- /dev/null +++ b/docs/content/paths/index.html @@ -0,0 +1,362 @@ + + + + + + + + + + Paths | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

Paths

+ + + +
    + + + +
+ +

This refers mostly to Lektor 2.0. If you are using an older version of +Lektor the virtual path feature is not implemented yet and a lot of this just +does not apply.

Lektor attempts to map the paths from the content folder as closely as possible +to the final URLs (at least in the default configuration). There are various +ways in which this can be customized (see URLs and Slugs) and +there are situations in which Lektor needs to render out content that does not +actually directly correspond to a path on the file system.

+

Here we try to explain how the path system in Lektor works and what it means.

+

What is a Path

A path in Lektor is a string that uniquely identifies a Source Object. For the most part these directly point to +content.lr files or attachments therein. These paths always use forward +slashes, no matter on which platform Lektor runs. So for instance if you +have a file named projects/my-project/contents.lr then the path for this +record will be /projects/my-project. Thereby it does not matter if the +slug or final URL was changed, the path is always the same.

+

Lektor uses paths to refer to records by default in all cases. This means that +if you use the url filter for instance +it will operate on paths and not URLs!

+

But what about sources that do not directly correspond to something on the +file system? This is where virtual paths come in. Virtual paths are +separated from physical paths with an at (@) sign. Virtual paths are always +attached to a record and point to things that are not actually coming from the +content folder but something else.

+

Virtual paths are for instance used to refer to paginated pages or to some +resources that plugins add.

+

Virtual Paths

Virtual paths are added behind physical paths and are separated by an at +sign (@). The only virtual path that is supported by Lektor out of the box +is the special numeric virtual path which can be used to refer to specific +pages for a pagination. For instance /blog@1 refers to the first page of +the blog page, /blog@2 to the second etc. There are however plugins that +add virtual paths to refer to their own resources. For instance a plugin can +register /blog@feed to refer to a RSS/Atom feed for the blog.

+

Relative Paths

Now that we talked a bit about paths, we should probably cover how relative +paths work. Relative paths work similar to how you expect them to work on +most operating systems but they can operate on the virtual as well as the +physical path. There is also some special behavior with regards to the numeric +virtual path for pagination.

+

For the most part . refers to the same page and .. refers to the page one +level up. If you use a path that just contains of a virtual path, then it's +attached to the current page to replace the active virtual path.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CurrentRelativeResult
/blog../
/blog./blog
/blog/post../blog
/blog@2/blog@2
/blog@2@1/blog@1
/blog@feedrecent/blog@feed/recent
/blog@feed../blog@feed
+

However! The numeric path is special with regards because it's considered to +belong to the current page:

+ + + + + + + + + + + + + + + + + + + +
CurrentRelativeResult
/blog@2./blog@2
/blog@2../
+

Alternatives and Paths

If you have used Lektor a bit you might be wondering how Alternatives work with paths. The answer might be surprising but it's +basically that they don't really work with paths. Alternatives are +implemented on a level higher than paths. If you have a page that exists +in both German and English alternative then they will have the same path. +The alternative code is supplied separately.

+

This is done so that you can later start introducing alternatives to sites +that were never aware of them without having to go everywhere and start +passing alternative information around. While there are indeed some places +where you might have to perform some changes (especially if you perform +manual queries in the templates) for the most part adding alternatives to an +existing site later is a trivial matter.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/content/system-fields/index.html b/docs/content/system-fields/index.html new file mode 100644 index 00000000..dbfb514e --- /dev/null +++ b/docs/content/system-fields/index.html @@ -0,0 +1,279 @@ + + + + + + + + + + System Fields | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

System Fields

+ + + +
    + + + +
+ +

In addition to the fields that are defined through the Data Model there are a lot of fields that come directly from Lektor. +They can be easily recognized because they are prefixed by a leading underscore +(_).

+

These fields influence how Lektor treats pages and attachment. Here we will +just go over the most important ones but for a full list you can have a look +at the API Documentation.

+

_hidden

This field is a boolean value and controls if a page is hidden or not. If a +page is hidden all of its children will automatically also be hidden. A page +that is hidden will not be processed by Lektor's build system. This means such +pages can be discovered through the query API but they are not rendered +themselves. This is useful for situations where you want to have information +stored but not rendered. This is for instance used to implement Single-Page +websites.

+

To read more read the field documentation.

+

_discoverable

This fields in many ways is similar to _hidden but instead makes a page +be only hidden from queries. In particular this means that it will still be +processed and built, but that it becomes harder for code to reference it. +Pages that are not set to discoverable can only be found through queries if +they are explicitly included.

+

This field was added in Lektor 2.0. In earlier versions this feature is +unavailable.

To read more read the field documentation.

+

_model

This key sets the Data Model that is used for the record. +If not set this defaults to one of different choices depending on configuration +or name. Parent models can pre-define the model for children, which is then used if +this key is not set. If not set this will be picked up by an algorithm. +See Default Model Selection for more information.

+

To learn more read the field documentation.

+

_slug

This field can override the default URL slug. For more information about this +feature see URLs and Slugs.

+

_template

This field can be used to override the default template selection which is +just the model name with the .html extension.

+

To learn more read the field documentation.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/content/urls/index.html b/docs/content/urls/index.html new file mode 100644 index 00000000..b73a88de --- /dev/null +++ b/docs/content/urls/index.html @@ -0,0 +1,325 @@ + + + + + + + + + + URLs and Slugs | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+ + +
+ + +

URLs and Slugs

+ + + +
    + + + +
+ +

Lektor's URLs in general mirror what happens on the file system as much as +possible. There are however various cases in which this behavior can be +changed.

+

A URL Is Composed of Slugs

Each page in Lektor is associated with a string called a slug. The full +URL of a page is its own slug concatenated with the slug of each its parents.

+

The default slug is the ID of the page. So the page +content/foo/bar/contents.lr has the default slug bar, its parent has the +default slug foo, and its default URL would be /foo/bar/.

+

Slug Customization

Slugs can be customized. They can even contain slashes (see below). There are +three systems that control what the slug looks like:

+

Folder Name

The name of the folder that contains the contents.lr file is the ID of the +page and thus the default slug (unless changed by the model — more about that +later). This means that you could for instance just rename the folder to +get a different slug. This is the recommended way for the majority of pages +to adjust the slug.

+

The _slug System Field

The second option is to use the _slug system field. This field is available +for all models automatically and overrides the slug explicitly. This is +particularly useful to force a slug that could not be represented on the file +system (for instance because it should contain a slash) or because you want +to change the slug for a different Alternative. As +an example a page translated to German might want to translate the slug as well.

+

Implied Slug Configuration

The last part is a system that controls the implied slugs. In particular it +means that the model of the parent page can override the default slug for all +of the children below it. This for instance can be used to automatically add +the date of a blog post into the slug. For more information about this +feature see Children & Pagination.

+

Slugs Containing Slashes

Slugs can indeed contain slashes. It's perfectly valid for a page to have +2015/5/demo as slug, and it will still be incorporated into URLs as described +above. What's not possible is for a page to pretend that it belongs to a +different parent. The parent paths are always added to it. So once a page +has a parent page /foo its URL path will always begin with the URL path of +the page foo.

+

Extensions and File Types

The default behavior for a page is to build into a hidden index.html file. +This means that if you have a page called foo/bar/contents.lr it will +build into a file named foo/bar/index.html. Web servers typically look for +an index.html file in a folder which is why you can just access /foo/bar/ +and the page will render.

+

If however the last path component contains a period (.) then the last path +component is assumed to be a filename directly. This means that if you set +the slug of a page to 404.html for instance, the page will indeed render +into 404.html and not 404/index.html.

+

However you need to be careful with this as web servers pick the “mimetype” +of a file based on the extension. So if you name a file foo.html it will +behave very differently compared to a file named foo.txt. So do not name +your files in ways that would be incompatible with what the web server +renders. This however also allows you to generate files that are not +HTML. For instance you could render into a .xml file if that is what +you want.

+

This feature is called “Dotted Slugs” and there are some specifics with +regards to how these are handled.

+

Content Below Dotted Slugs

One specific behavior of a path component that contains a dotted slug is that +content below that path need to move to a different location. Imagine for +instance you named the page 404.html but that page has an attachment. As +404.html is now a file it's impossible for a folder with the same name to +exist. This means that the attachments have to be stored elsewhere. The +convention for this in Lektor is to prefix the path with an underscore. So +if 404.html has an attachment named foo.jpeg it will move into +_404.html/foo.jpeg.

+

External and Absolute URLs

Lektor by default will prefer relative URLs. This makes it possible to easily +host a website below a certain folder without having to do anything special to +make this work. However there are some features which will require the use of +an absolute or fully canonical (external) URL. For instance sitemaps or Atom +feeds do not work with relative URLs. In this case the absolute URL path has +to be configured.

+

You can pick the default for URL generation in the project configuration. +For more information read about the Project Configuration.

+

The default of relative, a relative URL style, means that you can deploy a +website to a sub folder without any configuration, however most likely custom +404 pages will fail to find the needed assets. Fully canonical URLs are not +recommended as default style.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/deployment/ftp/index.html b/docs/deployment/ftp/index.html new file mode 100644 index 00000000..7c556204 --- /dev/null +++ b/docs/deployment/ftp/index.html @@ -0,0 +1,278 @@ + + + + + + + + + + FTP | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

FTP

+ + + +
    + + + +
+ +
    +
  • ftp://username:password@server:port/path?passive=yes|no
  • +
  • ftps://username:password@server:port/path?passive=yes|no
  • +
+

FTP is a very old but well supported protocol. Lektor can publish through it +but to speed up the operation it has to make certain concessions. In +particular it needs to maintain a “listing file” to remember the state of +the files as FTP does not support any form of file comparisons. This means +that you cannot use Lektor in addition to another system to publish files +to your FTP server. It's an either/or thing.

+

If you have alternatives to using FTP it's recommended to use those. FTP is +a very simple transport format, very slow, underspecified, largely insecure +and not very portable.

+

The system supports FTP (ftp://) and FTP over TLS (ftps://). Passive mode +can be enabled/disabled with the optional ?passive parameter. It defaults +to true.

+

Example

[servers.production]
+target = ftps://myuser:mypassword@ftp.example.com/var/www/example
+
+

Credentials

FTP is considered a largely insecure protocol for Lektor. As such if you +want to use it you should keep your project file safe as credentials will +be most likely embedded there. Alternatively you can set the credentials +via the command line with the --username and --password option (or via the +environment variables LEKTOR_DEPLOY_USERNAME and LEKTOR_DEPLOY_PASSWORD) +though this will mean that most likely deploys via the admin interface +will fail as the values will not be available there.

+

Implementation

If you want to know how the FTP sync process works, here is how the system +figures out what to sync and what not. When it synchronizes it maintains +a “listing file” in .lektor/listing. This file contains the checksums of +all uploaded artifacts. If that file desynchronizes with the actual files +that were uploaded it can be deleted and Lektor will sync up everything. +The file is modified through append operations and at the end of the sync +duplicate entries in that file are resolved.

+

Using Other Tools

The FTP support in Lektor is quite rudimentary and in some situations you +might want to use a different tool like filezilla to do your synchronizations +instead. In that case you just need to point your FTP client to the build +folder. To find out where this is, just run this command:

+
$ lektor project-info --output-path
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/deployment/ghpages/index.html b/docs/deployment/ghpages/index.html new file mode 100644 index 00000000..840b4511 --- /dev/null +++ b/docs/deployment/ghpages/index.html @@ -0,0 +1,286 @@ + + + + + + + + + + GitHub Pages | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

GitHub Pages

+ + + +
    + + + +
+ +
    +
  • ghpages://username/repository
  • +
  • ghpages+https://username/repository
  • +
+

A popular way to host websites for Open Source projects is the GitHub pages. +It's a free service provided by GitHub which allows +to host completely static websites through GitHub.

+

The way this is implemented in Lektor currently is that Lektor will force-push +a website into a repository of choice. There are two ways to push it up: +ghpages (which uses SSH) or ghpages+https (which uses HTTPS). The latter +can also accept username:password@ in the URL to hold the credentials in +addition to accepting username and password from the command line or +environment variables.

+

Example:

+
[servers.ghpages]
+target = ghpages://your-user/your-repository
+
+

Credentials

This deployment method has two implementations: ghpages (also known as +ghpages+ssh) which uses SSH and ghpages+https which uses HTTPS. They +use different methods for credentials. For the SSH transport the same +rules apply as for the rsync deployment method. The HTTPS +transport on the other hand accepts --username and --password which +override the values in the URL.

+

If you have 2-factor authentication set up and you're using HTTPS, instead of your normal password, you will need to use a personal access token.

Behavior

The way this deployment support works is that it commits a new commit into a +temporary location and pushes it into the gh-pages or master branch +depending on the name of the repository. If you push to username.github.io +then it commits to master, otherwise to gh-pages. This is consistent +with behavior for GitHub Pages.

+

CNAME Support

If you want to use a custom domain with GitHub pages (also known as a +CNAME), provide the intended +CNAME in the target URL using the ?cname parameter:

+
[servers.production]
+target = ghpages://your-user/your-repository?cname=www.example.com
+
+

Note that this will overwrite whatever custom domain you may have set on +GitHub with every deployment.

+

For more information about how CNAMEs work with GitHub you can read about +the feature in the GitHub help center: +Adding a CNAME file to your repository.

+

404 Pages

Per convention the file named 404.html is used as placeholder if a page +cannot be found. You can create such a page by creating a 404.html/contents.lr +file.

+

Automatic Deployments

If you want to use ghpages it's desirable to have this build automatically. +This is easy to accomplish with the help of Travis-CI. For more information +see Deploying with Travis-CI.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/deployment/glpages/index.html b/docs/deployment/glpages/index.html new file mode 100644 index 00000000..e7f1802e --- /dev/null +++ b/docs/deployment/glpages/index.html @@ -0,0 +1,289 @@ + + + + + + + + + + GitLab Pages | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

GitLab Pages

+ + + +
    + + + +
+ +

GitLab supports Lektor on their GitLab +Pages infrastructure. Effectively +GitLab can build your website out of any repository on GitLab and hosts it +up on either a subdomain or a custom domain (including SSL).

+

Because this is all supported by the side of GitLab there is nothing you +need to configure in Lektor itself other than adding a GitLab config file.

+

There is also an example project on GitLab with a README you can clone: +pages/lektor

+

Create a Repository

What you need to do to start is to create a new repository for the project +on gitlab. There are two types of GitLab pages: user and project pages. +User pages are hosted at <username>.gitlab.io and project pages at +<username>.gitlab.io/<project>. There can only be one user page and the +repository for it needs to be named <username>.gitlab.io.

+

The branch does not matter. GitLab scans all branches for a file named +.gitlab-ci.yml which contains a configuration for gitlab pages.

+

Configuration

To enable support for Lektor you need to create a .gitlab-ci.yml config +next to your .lektorproject file with the following contents:

+
image: python:latest
+
+pages:
+  script:
+    - pip install lektor
+    - lektor build --output-path public
+  artifacts:
+    paths:
+      - public
+  only:
+    - master
+
+

It's important that the output path is set to public as this is what +will be served up. In case you want to use a different branch than master +just name the branch differently and adjust the only entry.

+

Whenever you commit to the repository now, GitLab will automatically start +a job on the public infrastructure and deploy your website.

+

CNAME Support

If you want to use a CNAME with +GitLab pages you can configure it in the GitLab settings:

+ +

SSL/TLS Support

If you have an SSL certificate and a custom domain, you can upload your private +key and certificate to GitLab and SSL will become available on your custom +domain as well.

+ +

404 Pages

Per convention the file named 404.html is used as placeholder if a page +cannot be found. You can create such a page by creating a 404.html/contents.lr +file.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/deployment/index.html b/docs/deployment/index.html new file mode 100644 index 00000000..abe8c4f3 --- /dev/null +++ b/docs/deployment/index.html @@ -0,0 +1,376 @@ + + + + + + + + + + Deployment | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

Deployment

+ + + +
    + + + +
+ +

A website is only a website if other people can look at it. While you are +developing locally that's not really all that helpful. So how do you get +your changes up to your favorite web host? This is where lektor deploy comes in.

+

Deploying in Two Steps:

Deploying a website in Lektor is a two step process:

+
    +
  1. build
  2. +
  3. deploy
  4. +
+

Keep this in mind. A deploy will not implicitly build! This means that if +you deploy without building first you might send up a completely wrong +version! Also more importantly: never deploy unless the build finished +successfully.

+

The Build Pipeline

So let's cover the building first. When you use the Lektor server locally, +Lektor constantly builds out your website into static HTML files behind the +scenes into the default build folder. This folder is in an operating system +specific location. If you want to know where that folder is, you can use this +command:

+
$ lektor project-info --output-path
+
+

Additionally you can manually provide a different path if you kick off a +manual build:

+
$ lektor build --output-path my-folder
+
+

Generally we strongly recommend to use the default build folder when deploying +from your own machine because it will be faster since the build can reuse +what the development server already did. If you want to deploy from a build +server it might make more sense to provide absolute paths.

+

Lektor Assisted Deployments

Currently Lektor can deploy via rsync and ftp automatically. To enable +this functionality you need to configure this in the config file. For each +potential deployment target add a [servers.NAME] section. The supported +keys are name for an optional human readable name of the server, enabled to +enable or disable it (defaults to true) and target which is the URL to +publish to. Additionally one of the servers can have default set to yes +to set it as default. Here is an example:

+
[servers.production]
+name = Production
+enabled = yes
+default = yes
+target = rsync://server/path/to/folder
+
+

To trigger a deploy you can use the deploy command:

+
$ lektor deploy production
+
+

Or because it's the default server, you can just do this:

+
$ lektor deploy
+
+

This deploys the latest state of what was built from the default build +folder. It does not build itself! So to do both in one go, do something like +this:

+
$ lektor build && lektor deploy
+
+

If you want to provide a different build folder, provide it explicitly with +--output-path to both build and deploy. This can also be set with +the LEKTOR_OUTPUT_PATH environment variable, or provided in +the project file.

+

Note on credentials: For FTP and other systems it is possible to embed +the credentials directly in the URL. If you do this, please ensure that +you keep your project file secure as loss of the project file can mean that +people get access to your server. Alternatively you can also provide username +and password through the command line or environment variables.

The following targets are supported for the target field natively:

+ +

In addition, there are third-party plugins available for additional deploy targets.

+

Manual Deployments

If you want to manually deploy something through the favorite tool of yours +you can do that easily as well. For instance if you want to deploy to S3 +with s3cmd you could do this:

+
$ lektor build && s3cmd sync "$(lektor project-info --output-path)"/* "s3://my-bucket/some/path"
+
+

Assisted deployments are also supported directly from the admin UI. There is a +publish button that can be used to send the changes up.

+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/deployment/rsync/index.html b/docs/deployment/rsync/index.html new file mode 100644 index 00000000..1d7db00d --- /dev/null +++ b/docs/deployment/rsync/index.html @@ -0,0 +1,281 @@ + + + + + + + + + + rsync | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

rsync

+ + + +
    + + + +
+ +

rsync://username@server/path/to/folder

+

This deploys via SSH and rsync to a remote server. This is the recommended +way to deploy if the system supports it as it is a very fast and reliable +way. It uses the system's SSH config so for authentication just configure +SSH as you would normally do. The username part is optional and defaults +to the current user that is signed into the machine or whatever is picked up +as default from the .ssh/config.

+

Example

[servers.production]
+target = rsync://deploy@example.com/var/www/example.com
+
+

Credentials

The rsync deploy method supports both username and password parameter +though it's recommended to use .ssh/config and an SSH agent to secure +the deployment. The --password parameter is not supported! Instead you +need to use --key-file (LEKTOR_DEPLOY_KEY_FILE) or --key +(LEKTOR_DEPLOY_KEY). The --key-file is the path to an OpenSSH private +key.

+

If you are using --key you can directly copy paste the contents of a key +into a string. This is useful if you want to use it as an environment +variable. The format for the string is KEY_TYPE:BASE64 where KEY_TYPE +is the type of the key (RSA, EC, etc.) and BASE64 is the base64 encoded +private key without newlines or whitespace. To find out which type your +key is look at the first line of the key marker. For instance BEGIN EC +PRIVATE KEY indicates an EC key. If no key type is defined RSA is +assumed.

+

Deletion Support

New in version 3.2.

To keep two directories truly in sync when deploying with rsync, +it's necessary to explicitly tell rsync to remove files or directories +on target that don't exist on source anymore. This can be done using the +?delete URL parameter:

+
[servers.production]
+target = rsync://server/path/to/folder?delete
+
+

If the parameter is provided Lektor will issue a rsync --delete-delay, +which performs deletions after all other transfers ended, and only in case +there were no failures.

+

Note that the ?delete option will remove any file or directory +on target that does not exist on source. This means that if you have files +in the target tree that are not managed by lektor, they will get removed.

Exclusion Support

You can exclude items from being synced by using one or more exclude +parameters. This is also useful in combination with delete to prevent +removal of files in the target tree that are not managed by lektor:

+
[servers.production]
+target = rsync://server/path/to/folder?delete&exclude=target_item_1&exclude=target_item_2
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/deployment/travisci/index.html b/docs/deployment/travisci/index.html new file mode 100644 index 00000000..c99fc975 --- /dev/null +++ b/docs/deployment/travisci/index.html @@ -0,0 +1,348 @@ + + + + + + + + + + Travis-CI | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

Travis-CI

+ + + +
    + + + +
+ +

For certain websites it can be interesting to use +Travis-CI to automatically deploy the latest version +of a website from a github repository. This is particularly useful when +coupled with the GitHub Pages deployment method which is +what we're going to cover in this guide. But you can easily adjust it to +any other method.

+

This assumes you already signed up for Travis-CI. If you have not, just +head to travis-ci.org and sign up with your +GitHub account.

+

This guide is also available as a 7 minute screencast.

+

Travis Config

Once you have signed up for Travis-CI you need to add a .travis.yml config +file into your repository. You can copy paste this over:

+
language: python
+python: 3.6
+install: "pip install Lektor"
+script: "lektor build"
+deploy:
+  provider: script
+  script: "lektor deploy ghpages"
+
+

Because Travis already comes with all dependencies we need other than +Lektor itself we just need to pip install Lektor and we're ready to go. For +the build step we invoke lektor build, and for the deploy step we invoke +lektor deploy ghpages to ship it to the ghpages server. We still need +to configure that.

+

Project Server Config

For the above example the best way to configure the server for the deployment +in the project file would be to use ghpages+https like this:

+
[servers.ghpages]
+target = ghpages+https://username/repository
+
+

You need to add this to your .lektorproject file.

+

Whenever Travis builds it will automatically throw the end result into the +gh-pages branch and the website updates. We do however still need to +configure the access credentials. We will get to that.

+

Enabling Travis

So now that we have all that configured we need to tell travis to build the +repository. For that just head to your Travis-CI Profile and enable the repository. If it does not +show up yet, you can force a sync with the click of a button.

+

Access Credentials

So how do you safely provide your credentials? Lektor accepts username and +password for the ghpages+https transport via the LEKTOR_DEPLOY_USERNAME +and LEKTOR_DEPLOY_PASSWORD environment variables. These can be set in the +Travis-CI settings of your repository on travis-ci.org in secret so they are +not stored anywhere else and will not show up in the build output. However one +thing you need to be careful with is that they still give access to your entire +account!

+

To solve this problem we recommend two things:

+
    +
  1. Create a personal access token +and use that instead. Just provide the token instead of your password on +sign-in. This makes it easily possible to just revoke that token if +something goes wrong. Note that you only need the repo scope for this +to work. This also works if you have 2FA activated on an account.
  2. +
  3. Create a deployment (machine) user. +This allows you to use a user that is exclusively used for just the +purpose of updating the website.
  4. +
+

Once you have done that travis will start deploying the website on every +commit.

+

When copy/pasting username and password into travis please ensure that +you do not copy any leading or trailing whitespace with it. This will not +just break the build but also reveal the password in the process. For +more information see travis-ci#4139.

Committer Information

By default the commits to the gh-pages branch will be authored by a user +named “Lektor Bot”. If you want to override this you can export the +GIT_COMMITTER_NAME and GIT_COMMITTER_EMAIL environment variables and +set them to something else. This is best done in the travis settings.

+

Private Repositories

If you are using private repositories you will need the commercial version of +travis. It has the advantage that you can also set up SSH keys on there which +means that authentication becomes easier. For more information see Private +Dependencies in +the Travis CI documentation.

+

Speeding up Builds with Caching

In the default setting Travis will have to rebuild everything because between +builds it does not cache the build results. You can change this by enabling +caching. Adjust your .travis.yml file to look like this:

+
language: python
+python: 3.6
+cache:
+  directories:
+    - $HOME/.cache/pip
+    - $HOME/.cache/lektor/builds
+install: "pip install Lektor"
+script: "lektor build"
+deploy:
+  provider: script
+  script: "lektor deploy ghpages"
+
+

Restricting Branches

If you plan on having different branches and contributors you should disable +the deployment to the master branch only. You can do this with the following +config:

+
language: python
+python: 3.6
+cache:
+  directories:
+    - $HOME/.cache/pip
+    - $HOME/.cache/lektor/builds
+install: "pip install Lektor"
+script: "lektor build"
+deploy:
+  provider: script
+  script: "lektor deploy ghpages"
+  on:
+    branch: master
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/guides/blog/index.html b/docs/guides/blog/index.html new file mode 100644 index 00000000..2cd1b301 --- /dev/null +++ b/docs/guides/blog/index.html @@ -0,0 +1,382 @@ + + + + + + + + + + Blog | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

Blog

+ + + +
    + + + +
+ +

Blogging is what spawned many content management systems and static site +generators. We're living in a world where many people like to share what's +on their minds and the best way to do that turns out to be pages ordered by +the date of publication. That's basically what a blog is. Here we will +build our own blog with Lektor.

+

The Models

For a blog we want two models. The model for the blog itself and the model +for the blog-post. The idea is that we have a folder called blog which +uses the blog model which contains all the blog posts. Each of the blog +posts will use the blog-post model.

+

blog.ini

This is the model for the blog itself. It instructs Lektor that all of the +pages below it will be blog posts, how many blog posts we want to show per +page and what the order is. We also set it to hidden and protected which +will make it unavailable in the admin (hidden) for new pages and make it +impossible to delete (protected). This means we need to manually create the +one page later which will use this.

+
[model]
+name = Blog
+label = Blog
+hidden = yes
+protected = yes
+
+[children]
+model = blog-post
+order_by = -pub_date, title
+
+[pagination]
+enabled = yes
+per_page = 10
+
+

blog-post.ini

Each blog post has a title, publication date, author and body. The publication +date and title are also used for sorting if you look into the blog.ini. +Lastly we set up the label of the page to be the title of the blog post. We +can also set it to hidden as the model is automatically selected in the +admin whenever a page is created in the blog.

+
[model]
+name = Blog Post
+label = {{ this.title }}
+hidden = yes
+
+[fields.title]
+label = Title
+type = string
+size = large
+
+[fields.pub_date]
+label = Publication date
+type = date
+width = 1/2
+
+[fields.author]
+label = Author
+type = string
+width = 1/2
+
+[fields.body]
+label = Body
+type = markdown
+
+

The Templates

Now that we have the models set up, we want to create the templates.

+

blog.html

Let's start with the blog overview page. This template is used for our blog +model. In this example we just want to show the titles of the post on the +overview page with the author and date and a controller for the pagination. +Because pagination is enabled we can iterate over this.pagination.items +instead of this.children which will return only the items for the intended +page.

+
{% extends "layout.html" %}
+{% from "macros/pagination.html" import render_pagination %}
+{% block title %}My Blog{% endblock %}
+{% block body %}
+  <h1>My Blog</h1>
+
+  <ul class="blog-index">
+  {% for post in this.pagination.items %}
+    <li>
+      <a href="{{ post|url }}">{{ post.title }}</a> —
+      by {{ post.author }}
+      on {{ post.pub_date|dateformat }}
+    </li>
+  {% endfor %}
+  </ul>
+
+  {% if this.pagination.pages > 1 %}
+    {{ render_pagination(this.pagination) }}
+  {% endif %}
+{% endblock %}
+
+

For the pagination macro have a look at the pagination guide which covers that part.

+

blog-post.html

Now we just need a template for our blog post. This (blog-post.html) will +do:

+
{% extends "layout.html" %}
+{% block title %}{{ this.title }} | My Blog{% endblock %}
+{% block body %}
+  <h1>{{ this.title }}
+  <p class="meta">
+    by {{ this.author }}
+    on {{ this.pub_date|dateformat('full') }}
+  <div class="body">{{ this.body }}</div>
+{% endblock %}
+
+

Initializing The Blog

Now that we have models and templates we just need to designate a part of the +website as blog. For that create a new folder in your content/ folder +with the name of your blog. For instance just content/blog and put a +contents.lr file with this content in:

+
_model: blog
+
+

Now you can head to the admin UI to create new blog posts.

+

Changing the URL Structure

With the above settings the blog will live at blog/ and the posts at +blog/<post-slug>. But what if you want to put the date of the blog post +into the URL? That's thankfully very easy. All you need to do is to set up +a new URL format for the children. Just edit blog.ini and add this to +the [children] section:

+
slug_format = {{ (this.pub_date|dateformat('YYYY/M/') if this.pub_date) ~ this._id }}
+
+

What this does is that it will prepend the year (YYYY) and month (M) to +the ID of the page if the publication date is configured. Otherwise it will +just use the ID of the page. With this change our blog post will move from +for instance blog/hello/ to blog/2015/12/hello/.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/guides/categories/index.html b/docs/guides/categories/index.html new file mode 100644 index 00000000..17da2a00 --- /dev/null +++ b/docs/guides/categories/index.html @@ -0,0 +1,425 @@ + + + + + + + + + + Categories | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+ + +
+ + +

Categories

+ + + +
    + + + +
+ +

Because Lektor is based on the idea of mirroring the tree structure from the +file system to the final website it sometimes might not be quite clear how +one could achieve any form of filtering (for instance categories). However +this is actually very easily achieved through the concept of “child +replacement”. This will give you a quick introduction to how this feature +can be used to implement categories.

+

Basic Setup

In this case we assume you have a bunch of projects that can exist in +different categories and it should be possible to see which projects belong +to which category.

+

The Models

So we will end up with four models: projects.ini, project.ini, +project-categories.ini and project-category.ini. Here is how they look:

+

projects.ini

[model]
+name = Projects
+label = Projects
+hidden = yes
+protected = yes
+
+[children]
+model = project
+order_by = -date, name
+
+

project.ini

[model]
+name = Project
+label = {{ this.name }}
+hidden = yes
+
+[fields.name]
+label = Name
+type = string
+
+[fields.date]
+label = Date
+type = date
+
+[fields.description]
+label = Description
+type = markdown
+
+[fields.categories]
+label = Categories
+type = checkboxes
+source = site.query('/project-categories')
+
+

The above models should be mostly clear. What is probably not entirely clear +is the source parameter for the categories. Essentially we instruct the +admin panel to fill the selection for the checkboxes from the child pages +below the project-categories folder. This is where we will maintain the +categories.

+

project-categories.ini

[model]
+name = Project Categories
+label = Project Categories
+hidden = yes
+protected = yes
+
+[children]
+model = project-category
+order_by = name
+
+

project-category.ini

[model]
+name = Project Category
+label = {{ this.name }}
+hidden = yes
+
+[children]
+replaced_with = site.query('/projects').filter(F.categories.contains(this))
+
+[fields.name]
+label = Name
+type = string
+
+

So this is where the magic lives. the replaced_with key in the [children] +section tells Lektor to ignore the child pages that would normally exist below +the path but to substitute them with another query. In this case we replace +them with all the projects where the category (this) is in the checked +set of categories (F.categories).

+

Initializing The Folders

Now that we have the models, we need to initialize the folders. This is +necessary because most models are hidden which means they cannot be selected +from the admin interface. We need the following things:

+

projects/contents.lr

_model: projects
+
+

project-categories/contents.lr

_model: project-categories
+---
+_slug: projects/categories
+
+

Here we also tell the system that we want to move the page from +project-categories/ to projects/categories/ which looks nicer. This +means a category named Foo will then end up as projects/categories/foo/.

+

Creating Categories

Now we can head to the admin panel to create some categories. Each category +that is created will become available for new projects in the category +selection.

+

The Templates

To render out all the pages we probably want to use some macros to reuse +markup that appears on multiple pages.

+

projects.html

{% extends "layout.html" %}
+{% from "macros/projects.html" import
+  render_project_list, render_category_nav %}
+{% block title %}Projects{% endblock %}
+{% block body %}
+  <h1>Projects</h1>
+  {{ render_category_nav(active=none) }}
+  {{ render_project_list(this.children) }}
+{% endblock %}
+
+

project.html

{% extends "layout.html" %}
+{% block title %}{{ this.name }}{% endblock %}
+{% block body %}
+  <h1>{{ this.name }}</h1>
+  <div class="description">{{ this.description }}</div>
+{% endblock %}
+
+

project-categories.html

{% extends "layout.html" %}
+{% from "macros/projects.html" import render_category_nav %}
+{% block title %}Project Categories{% endblock %}
+{% block body %}
+  <h1>Project Categories</h1>
+  {{ render_category_nav(active=none) }}
+{% endblock %}
+
+

project-category.html

{% extends "layout.html" %}
+{% from "macros/projects.html" import render_category_nav,
+   render_project_list %}
+{% block title %}Project Category {{ this.name }}{% endblock %}
+{% block body %}
+  <h1>Project Category {{ this.name }}</h1>
+  {{ render_category_nav(active=this._id) }}
+  {{ render_project_list(this.children) }}
+{% endblock %}
+
+

macros/projects.html

{% macro render_category_nav(active=none) %}
+  <ul>
+  {% for category in site.query('/project-categories') %}
+    <li{% if category._id == active %} class="active"{% endif
+      %}><a href="{{ category|url }}">{{ category.name }}</a></li>
+  {% endfor %}
+  </ul>
+{% endmacro %}
+
+{% macro render_project_list(projects) %}
+  <ul>
+  {% for project in projects %}
+    <li><a href="{{ project|url }}">{{ project.name }}</a></li>
+  {% endfor %}
+  </ul>
+{% endmacro %}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/guides/disqus/index.html b/docs/guides/disqus/index.html new file mode 100644 index 00000000..d32a4ca3 --- /dev/null +++ b/docs/guides/disqus/index.html @@ -0,0 +1,280 @@ + + + + + + + + + + Disqus Comments | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

Disqus Comments

+ + + +
    + + + +
+ +

The disqus-comments plugin adds support for Disqus comments to Lektor and +with its help you can have comments on your pages in no time. Once the plugin +is enabled a render_disqus_comments function is available for templates which +can render a disqus comment box. All you need to do for this is to create your +own Disqus community at Disqus Engage.

+

Once you have created your community there you will be given a "short name" +which can then be used with this plugin.

+

Enabling the Plugin

First you need to enable the plugin. The following command will do that +for you:

+
$ lektor plugins add disqus-comments
+
+

Configuring the Plugin

The plugin has a config file that is needed to inform it about your +website. Just create a file named disqus-comments.ini into your +configs/ folder and configure the shortname key with the name of +your disqus community:

+
shortname = YOUR_SHORTNAME
+
+

In Templates

Now you can add a discussion box to any of your templates by just using +the render_disqus_comments function. Just calling it is enough to +get the comment box:

+
<div class="comments">{{ render_disqus_comments() }}</div>
+
+

Optionally the function accepts two arguments: identifier and +url to override the defaults. For more information have a look at +the disqus widget documentation.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/guides/error-pages/index.html b/docs/guides/error-pages/index.html new file mode 100644 index 00000000..31fd6ce5 --- /dev/null +++ b/docs/guides/error-pages/index.html @@ -0,0 +1,306 @@ + + + + + + + + + + Error Pages | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

Error Pages

+ + + +
    + + + +
+ +

Because Lektor renders out static pages the question comes up what happens if a +page cannot be found. This is typically achieved by a special page that a +server will then use as a stand-in for a page that otherwise cannot be found.

+

In Lektor as a convention this page should be called 404.html. While in +reality the name of this page largely depends on how you deploy your pages we +are sticking with the generally accepted location of calling it 404.html. +This will work on GitHub Pages and some other environments where this cannot +be otherwise configured and most web servers can be configured to use this file +for URLs that are not found.

+

In versions of Lektor before 2.0 custom 404 pages will not be honored by the +development server. To test those you will need to explicitly navigate to +/404.html.

URLs on 404 Pages

If you are using 404 pages then these pages can appear at any URL. This means +that relative URLs will not work. If you want to use custom error pages you +will have to set the url_style to absolute as otherwise URLs on an error +page will not work. Just add this to your project file:

+
[project]
+url_style = absolute
+
+

For more information about this you can read the Project File Documentation.

+

Creating an Error Page

You can easily add a 404 page by creating a 404.html/contents.lr +file. If you do not care much about the contents and structure of the file +you can just point it to an empty model (none) and manually select a +404.html template like this:

+
_model: none
+---
+_template: 404.html
+
+

Then just create a 404.html template with the intended contents.

+

Server Configuration

If you are deploying such pages to your own servers you will need to ensure +that the error pages are activated. Depending on the server used this will +work slightly differently.

+

Apache

Making custom error pages work is easiest with Apache. If .htaccess files +are enabled you can just put a file with that name into your assets folder +and add the following line to it:

+
ErrorDocument 404 /404.html
+
+

Alternatively you can add the above line into a VirtualHost or Directory +section in your main config file.

+

nginx

For nginx you need to enable the error document in your main config file. Just +add it to your server section:

+
error_page 404 /404.html;
+
+

lighttpd

If you are using lighttpd you can configure an error page for 404 this way:

+
server.error-handler-404 = "/404.html"
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/guides/index.html b/docs/guides/index.html new file mode 100644 index 00000000..923849b5 --- /dev/null +++ b/docs/guides/index.html @@ -0,0 +1,362 @@ + + + + + + + + + + Guides | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

Guides

+ + + +
    + + + +
+ +

Because Lektor is quite a generic system, sometimes it might not be quite +obvious what the best course of action is. This part of the documentation +contains some guides that should help you find inspiration for solving certain +problems.

+ + + + + + + + + + +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/guides/page-order/index.html b/docs/guides/page-order/index.html new file mode 100644 index 00000000..ca1c8638 --- /dev/null +++ b/docs/guides/page-order/index.html @@ -0,0 +1,283 @@ + + + + + + + + + + Page Order | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

Page Order

+ + + +
    + + + +
+ +

Pages can generally have an order defined. This order comes from the +configuration of children in the parent model or can be explicitly provided. +This page guides you through all the different options you have.

+

Default Configuration

The most common way to get order into your pages is the configuration for +children. This way an order can be defined that is used by default for any +query involving the children of a page. So what can you order by? You can +order by any field you want. For instance to order by the name of a page +you can do this:

+
[children]
+model = project
+order_by = name
+
+

This will automatically order the .children query by the name of a project. +You can define more than one ordering. For instance you could order blog +posts by dates in decreasing order and secondarily by the blog title:

+
[children]
+model = blog-post
+order_by = -pub_date, title
+
+

A minus sign as prefix reverses the order.

+

Specific Order

But what to do if you want to order something specifically? In that case you +can use the sort_key type and configure +that:

+
[children]
+model = doc-page
+order_by = sort_key
+
+

Currently you need to explicitly give numbers in this field but future versions +of Lektor will provide support for automatically reordering them in the admin +panel.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/guides/pagination/index.html b/docs/guides/pagination/index.html new file mode 100644 index 00000000..b5b99f9c --- /dev/null +++ b/docs/guides/pagination/index.html @@ -0,0 +1,302 @@ + + + + + + + + + + Pagination | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

Pagination

+ + + +
    + + + +
+ +

When you have too many items to show on one page you might want to use +Lektor's built-in pagination support. It allows a page to show only a +subset of the child records per page.

+

Configuring Pagination

First you need to enable the pagination in the model. Primarily you need +to enable the pagination and set how many items show up on a page. Just +add this to the parent model:

+
[pagination]
+enabled = yes
+per_page = 10
+
+

Selecting the Children

Now that you have the pagination configured you need to iterate only over +the children of an active page in your template rather than the children of the +entire record. This can be done by changing this.children to +this.pagination.items:

+
{% for child in this.pagination.items %}
+  ...
+{% endfor %}
+
+

Rendering a Pagination

Lastly we need to render the pagination somehow. This is up to you. The +handy pagination object has a few +very useful attributes that can be used for rendering. It's recommended +to make a macros/pagination.html that looks something like this so that +you can render the same pagination everywhere:

+
{% macro render_pagination(pagination) %}
+  <div class="pagination">
+    {% if pagination.has_prev %}
+      <a href="{{ pagination.prev|url }}">&laquo; Previous</a>
+    {% else %}
+      <span class="disabled">&laquo; Previous</span>
+    {% endif %}
+    | <strong>{{ pagination.page }}</strong> |
+    {% if pagination.has_next %}
+      <a href="{{ pagination.next|url }}">Next &raquo;</a>
+    {% else %}
+      <span class="disabled">Next &raquo;</span>
+    {% endif %}
+  </div>
+{% endmacro %}
+
+

Using the Macro

Now that you have that set up, you can use the macro like this:

+
{% from "macros/pagination.html" import render_pagination %}
+{% if this.pagination.pages > 1 %}
+  {{ render_pagination(this.pagination) }}
+{% endif %}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/guides/portfolio/index.html b/docs/guides/portfolio/index.html new file mode 100644 index 00000000..bbae3d83 --- /dev/null +++ b/docs/guides/portfolio/index.html @@ -0,0 +1,392 @@ + + + + + + + + + + Portfolio Sites | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

Portfolio Sites

+ + + +
    + + + +
+ +

Because Lektor lets you customize your data model entirely it's the perfect +tool for building portfolio websites. No matter what it is you're building, +you can structure the data exactly like you want. In this example we will +assume we build a website for someone who wants to showcase their art projects.

+

The Models

The way we want to go about this is that we have a site where all the +projects show up and then a detail page for each project in particular.

+

projects.ini

First we set up the project overview page. This model instructs Lektor that +all of the pages below it will be of type project. We also set it to +hidden and protected which will make it unavailable in the admin (hidden) +for new pages and make it impossible to delete (protected). This means we +need to manually create the one page later which will use this.

+

Because we only have a single page for the projects overview we give it a +static label manually (label = Projects).

+
[model]
+name = Projects
+label = Projects
+hidden = yes
+protected = yes
+
+[children]
+model = project
+order_by = -date, name
+
+

project.ini

Next up is the model for the project. This is completely up to you, we will go +with some things here that might appear on such a portfolio page. In addition +we will do something with the attachments of this page, but more about that +later. For now we just order them by their filename (_id):

+
[model]
+name = Project
+label = {{ this.name }}
+hidden = yes
+
+[attachments]
+order_by = _id
+
+[fields.name]
+label = Name
+type = string
+size = large
+
+[fields.date]
+label = Date
+type = date
+width = 1/4
+
+[fields.type]
+label = Project type
+type = string
+width = 1/4
+
+[fields.website]
+label = Website
+type = url
+width = 1/2
+
+[fields.description]
+label = Description
+type = markdown
+
+

Templates

So now that we have models, we should probably go over what we can do with the +attachments. Because each page in Lektor can have attachments added we can +automatically reference those in our templates. Here is what we're going to +do: we will take all the attached images, order them by their filename and then +render thumbnails for them in the detail page. Additionally we want to show +one of the images on the overview page if it's available.

+

projects.html

So here we just render out all projects in the order defined in our +models and if there is an image attached, we pick the first one and make +a thumbnail.

+
{% extends "layout.html" %}
+{% block title %}Projects{% endblock %}
+{% block body %}
+  <h1>Projects</h1>
+  <div class="projects">
+  {% for project in this.children %}
+    <div class="project">
+      {% set image = project.attachments.images.first() %}
+      {% if image %}
+        <img src="{{ image.thumbnail(320)|url }}" alt="">
+      {% endif %}
+      <h2><a href="{{ project|url }}">{{ project.name }}</a>
+        <em>({{ project.date.year }})</em></h2>
+      <p><strong>{{ project.type }}</strong></p>
+    </div>
+  {% endfor %}
+  </div>
+{% endblock %}
+
+

project.html

For the detail page we show all information we know about:

+
{% extends "layout.html" %}
+{% block title %}{{ this.name }} ({{ this.date.year }}){% endblock %}
+{% block body %}
+  <h1>{{ this.name }}</h1>
+  <dl>
+    <dt>Date
+    <dd>{{ this.date|dateformat }}
+    {% if this.website %}
+    <dt>Website
+    <dd><a href="{{ this.website }}">{{ this.website.host }}</a>
+    {% endif %}
+    <dt>Project type
+    <dd>{{ this.type }}
+  </dl>
+  <h2>Description</h2>
+  <div class="description">{{ this.description }}</div>
+  {% set images = this.attachments.images.all() %}
+  {% if images %}
+    <h2>Images</h2>
+    {% for image in images %}
+      <div class="image">
+        <img src="{{ image.thumbnail(640)|url }}" alt="">
+        {% if image.exif %}
+        <p class=meta>
+          {{ image.exif.camera }}
+          {% if image.exif.created_at %}
+            ({{ image.exif.created_at|dateformat }})
+          {% endif %}
+        {% endif %}
+      </div>
+    {% endfor %}
+  {% endif %}
+{% endblock %}
+
+

Some notes on what's maybe not entirely obvious:

+
    +
  • a url field does not just give access to the stored URL but also provides +some properties such as .host to just get the host of the website.
  • +
  • we can use the |dateformat filter to format out dates nicely
  • +
  • by calling .all() on our images we get the images back as a list where we +can then check if any images exist with if images.
  • +
  • we can access embedded EXIF information by using the .exif property.
  • +
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/guides/redirects/index.html b/docs/guides/redirects/index.html new file mode 100644 index 00000000..e658e3fa --- /dev/null +++ b/docs/guides/redirects/index.html @@ -0,0 +1,279 @@ + + + + + + + + + + Redirects | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

Redirects

+ + + +
    + + + +
+ +

Setting up a flexible redirect system to make HTML redirects in Lektor is easy. A better setup would likely be on the server level, for instance in nginx, or configured on your CDN. The redirect will be more performant on the server level. Though this is not the best kind of redirect, it is pretty robust and will work in most situations. This example is flexible and can handle multiple redirects for your site.

+

Models and Templates

Set up the models to have a simple field that can hold the value of the target path. This is the path the page will be redirected to.

+

models/redirect.ini

[model]
+name = Redirect
+
+[fields.target]
+label = Redirect Target
+type = string
+description = Target is of type 'string' to allow relative paths. Converted to url in the template.
+
+

The template contains the minimal amount of html needed to initiate a redirect, along with a query for the target path.

+

templates/redirect.html

<meta http-equiv="refresh" content="0; URL='{{ this.target|url }}'" />
+
+

Contents

The contents.lr files for each redirect can be created in the admin, but you will probably want to edit them by hand to make them non-discoverable. Setting them to be non-discoverable will mean that they don't show up in other template queries, which means you won't end up with other pages making references to the page that is nothing but a redirect.

+

content/page-to-redirect/contents.lr

_model: redirect
+---
+target: /new/path
+---
+_discoverable: no
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/guides/single-page/index.html b/docs/guides/single-page/index.html new file mode 100644 index 00000000..fee8e931 --- /dev/null +++ b/docs/guides/single-page/index.html @@ -0,0 +1,360 @@ + + + + + + + + + + Single-Page | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

Single-Page

+ + + +
    + + + +
+ +

Lektor builds a page out of every source file. However that does not mean +that you cannot have multiple pages combined into a single one. You have +probably already seen that when doing something with the children of a page +in templates. But you can do this in much more elaborate ways.

+

You could for instance generate a huge page out of individual pages to +achieve a page where you can scroll to all parts.

+

In this example we will implement a project documentation where all +documentation pages are rendered into a long page.

+

The Models

First we need to define the models. We will need three here:

+
    +
  • doc-pages.ini: this is a dummy model that we will use to hide away the +parts of our big page.
  • +
  • doc-page.ini: this is the model for our documentation pages.
  • +
  • index.ini: this is the model we just use to combine everything together.
  • +
+

We will just sort all the documentation pages by the page ID so it's possible +to just order the pages by prefixing the page with a number +(0001-installation, 0002-quickstart etc.)

+

index.ini

[model]
+name = Documentation
+label = {{ this.title }}
+hidden = yes
+protected = yes
+
+[fields.title]
+type = string
+
+

doc-pages.ini

[model]
+name = Documentation Pages
+label = Documentation Pages
+hidden = yes
+protected = yes
+
+[children]
+model = doc-page
+order_by = _id
+
+

doc-page.ini

[model]
+name = Documentation Page
+label = {{ this.title }}
+hidden = yes
+
+[fields.title]
+type = string
+
+[fields.body]
+type = markdown
+
+

Initializing the Contents

Now that we have the models we need to set up the initial pages. All our +models are hidden which means that we cannot use the admin panel to setup +the initial pages. So we need to set up the structure outselves. The +following pages and contents we will need:

+

contents.lr

_model: index
+---
+title: My Documentation
+
+

doc/contents.lr

_model: doc-pages
+---
+_hidden: yes
+
+

This will set up our index model and our doc-pages model for the doc/ +folder. The latter is also set to _hidden which will make Lektor prevent +the generation of those files: they are invisible. So we need to find other +ways to render them.

+

Templates

For now we only need a single template: index.html, the one that will be +used by the only page that actually renders. Within that template we now +need to query for all the other pages we have below doc/:

+
{% extends "layout.html" %}
+{% block title %}{{ this.title }}{% endblock %}
+{% block body %}
+  {% set pages = site.query('/doc').include_undiscoverable(true).all() %}
+  <header>
+    <h1>{{ this.title }}</h1>
+    <nav>
+      <ul>
+        {% for page in pages %}
+        <li><a href="#{{ page._id }}">{{ page.title }}</a></li>
+        {% endfor %}
+      </ul>
+    </nav>
+  </header>
+  {% for page in pages %}
+    <div class="section" id="{{ page._id }}">
+      <h1>{{ page.title }}</h1>
+      {{ page.body }}
+    </div>
+  {% endfor %}
+{% endblock %}
+
+

Other Things To Do

Now every time you add or change a page below doc/ it will start rebuilding +the overview page. Obviously you can further complicate the setup by doing +something with attachments, supporting different models etc. The +possibilities are endless.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/guides/sitemap/index.html b/docs/guides/sitemap/index.html new file mode 100644 index 00000000..484ead1f --- /dev/null +++ b/docs/guides/sitemap/index.html @@ -0,0 +1,305 @@ + + + + + + + + + + Sitemap | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

Sitemap

+ + + +
    + + + +
+ +

If you want to have a sitemap.xml file for search engines this is something +you can very easily create yourself. All you need is a contents file +and a custom template.

+

Contents File

First we need to create a contents file. Since sitemap.xml always goes +into the same location we create a folder called sitemap.xml inside our +content folder and add a contents.lr file with the following data:

+
_template: sitemap.xml
+---
+_model: none
+
+

This instructs Lektor to use the template sitemap.xml for this page. We +also give it the empty none model for good measure.

+

Starting with Lektor 2.0 you can also add _discoverable: no as a field +into the file to hide it from .children. This is useful for such special +pages which should be excluded from navigation or automatic link generation.

Template File

The template loaded will be templates/sitemap.xml. In this file we just +iterate over all pages of the site recursively. This also automatically +skips hidden pages so those will not be generated out.

+
<?xml version="1.0" encoding="UTF-8"?>
+<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
+  {%- for page in [site.root] if page != this recursive %}
+  <url><loc>{{ page|url(external=true) }}</loc></url>
+  {{- loop(page.children|sort(attribute='path')) }}
+  {%- endfor %}
+</urlset>
+
+

Sorting the page using |sort(attribute='path') is not mandatory, but can be +useful if you prefer to have stable builds, for instance if you use git to +version the generated page and would like a clean history or a meaningful diff +from the last build.

+

Note that because sitemaps need to have external URLs (with scheme and +everything) you will need to configure the url of the site before the +template starts working. For more information see Project File

+

Human Readable Sitemap

But what if you want a beautiful sitemap as a tree for human reading? This is +not any harder. Instead of making a sitemap.xml/contents.lr file just +create a sitemap/contents.lr file instead and use a template like +sitemap.html. Then use something like this:

+
{% extends "layout.html" %}
+{% block title %}Sitemap{% endblock %}
+{% block body %}
+<ul class="sitemap">
+  {% for page in [site.root] if page.record_label recursive %}
+  <li><a href="{{ page|url }}">{{ page.record_label }}</a>
+    {% if page.children %}
+      <ul>{{ loop(page.children|sort(attribute='path')) }}</ul>
+    {% endif %}
+  </li>
+  {% endfor %}
+</ul>
+{% endblock %}
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/guides/webpack/index.html b/docs/guides/webpack/index.html new file mode 100644 index 00000000..5b6bb081 --- /dev/null +++ b/docs/guides/webpack/index.html @@ -0,0 +1,390 @@ + + + + + + + + + + Webpack | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

Webpack

+ + + +
    + + + +
+ +

Websites are exploding in complexity and even static websites are no exception +to this. In particular systems like bootstrap and friends no longer just come +in CSS files but they come with their own build setup to ship JavaScript files, +they use Less or Sass to build the stylesheets and much more.

+

Right now there is a fight between different systems to figure out which way +the journey will go, but one of the best solutions has turned out to be +webpack.

+

Webpack is not natively supported by Lektor but there is an official Webpack +Support Plugin which +can be used to make Lektor and Webpack friends.

+

Enabling the Plugin

First you need to enable the plugin. The following command will do that +for you:

+
$ lektor plugins add webpack-support
+
+

Webpack Setup

Now you need to configure webpack. The plugin expects a webpack project in the +webpack/ folder. Within you will need a package.json as well as a +webpack.config.js

+

package.json

This file instructs npm which packages we will need.

+

npm-init is a command-line tool to +interactively create a package.json file.

+
$ npm init
+
+

This will ask you a bunch of questions (invoke with --yes to use default +values) and then generate a package.json file for you.

+

It should look similar to the following example. Please do not just +copy-paste this! Instead run the tool, so that your package.json meets +the latest format specification.

+
{
+  "name": "lektor-example",
+  "version": "0.1.0",
+  "description": "",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "author": "",
+  "license": "MIT"
+}
+
+

Now we can npm install all the things we want:

+
$ npm install --save-dev webpack babel-core node-sass babel-loader sass-loader css-loader url-loader style-loader file-loader extract-text-webpack-plugin
+
+

This will install webpack itself together with babel and sass as well as +a bunch of loaders we need for getting all that configured. Because we +created a package.json before and we used --save-dev the dependencies +will be remembered in the package.json file.

+

webpack.config.js

Next up is the webpack config file. Here we will go with a very basic +setup that's good enough to cover most things you will encounter. The +idea is to build the files from webpack/scss and webpack/js into +assets/static/gen so that we can use it even if we do not have webpack +installed for as long as someone else ran it before.

+

In this example we will configure the following things:

+
    +
  • all .scss files will be processed with Sass
  • +
  • all .js files will be processed with Babel to convert ES6 into ES5
  • +
  • JS and CSS files will be minified
  • +
  • all built files will go to assets/static/gen
  • +
  • there will be a gen/app.js and a gen/styles.css file to include
  • +
+
var webpack = require('webpack');
+var path = require('path');
+var ExtractTextPlugin = require('extract-text-webpack-plugin');
+
+module.exports = {
+  entry: {
+    'app': './js/main.js',
+    'styles': './scss/main.scss'
+  },
+  output: {
+    path: path.dirname(__dirname) + '/assets/static/gen',
+    filename: '[name].js'
+  },
+  devtool: '#cheap-module-source-map',
+  resolve: {
+    modules: ['node_modules'],
+    extensions: ['.js']
+  },
+  module: {
+    rules: [
+      { test: /\.js$/, exclude: /node_modules/,
+        loader: 'babel-loader' },
+      { test: /\.scss$/,
+        loader: ExtractTextPlugin.extract({
+          fallback: 'style-loader',
+          use: 'css-loader!sass-loader' } ) },
+      { test: /\.css$/,
+        loader: ExtractTextPlugin.extract({
+          fallback: 'style-loader',
+          use: 'css-loader' } ) },
+      { test: /\.(woff2?|ttf|eot|svg|png|jpe?g|gif)$/,
+        loader: 'file' }
+    ]
+  },
+  plugins: [
+    new ExtractTextPlugin({
+      filename: 'styles.css',
+      allChunks: true
+    }),
+    new webpack.optimize.UglifyJsPlugin()
+  ]
+};
+
+

Creating the App

Now we can start building our app. We configured at least two files +in webpack: js/main.js and scss/main.scss. Those are the entry +points we need to have. You can create them as empty files in +webpack/js/main.js and webpack/scss/main.scss.

+

Running the Server

Now you're ready to go. When you run lektor server webpack will not +run, instead you need to now run it with the webpack flag which +will enable the webpack build:

+
$ lektor server -f webpack
+
+

Webpack automatically builds your files into assets/static/gen and this is +where Lektor will then pick up the files. This is done so that you can ship +the webpack generated assets to others that do not have webpack installed which +simplifies using a Lektor website that uses webpack.

+

Manual Builds

To manually trigger a build that also invokes webpack you can also pass +the webpack flag there:

+
$ lektor build -f webpack
+
+

Including The Files

Now you need to include the files in your template. This will do it:

+
<link rel="stylesheet" href="{{
+  '/static/gen/styles.css'|asseturl }}">
+<script type=text/javascript src="{{
+  '/static/gen/app.js'|asseturl }}" charset="utf-8"></script>
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 00000000..64628f74 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,365 @@ + + + + + + + + + + Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

Documentation

+ + + +
    + + + +
+ +

Welcome to the Lektor documentation center. Here you can find everything +about how to use Lektor from both a developer's as well as an end user's +point of view. New to Lektor? Then read about what makes Lektor +special.

+

The documentation is a work in progress and there will be areas that are +lacking. If you have any feedback or you want to help out with the +documentation project you can head over to the +GitHub Repository of this website.

+ + + + + + + + + + +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/installation/index.html b/docs/installation/index.html new file mode 100644 index 00000000..2f989e31 --- /dev/null +++ b/docs/installation/index.html @@ -0,0 +1,282 @@ + + + + + + + + + + Installation | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

Installation

+ + + +
    + + + +
+ +

Lektor comes in two flavors: as a command line executable and as a +desktop application. The desktop version also contains the command +line executable, but it also bundles together all dependencies of Lektor +in an easy to use package which heavily simplifies installation.

+

Desktop Application

Info: Support for the Mac Desktop Application is paused as of version 3.1. See note.

Currently the desktop application is only available for OS X and can be +downloaded from the Lektor website. It comes as a downloadable +disk image that you can mount which contains one application by the name of +Lektor.app. Just drag it into your Applications folder and you are good to +go.

+

If you also want access to the command line tools just launch Lektor.app +and then click in the menu bar on Lektor ➤ Install Shell Command.

+

Command Line Application

If you do not want to install the desktop app then you can just install the command +line executable. This runs on most operating systems (OSX, Linux and Windows) but +the installation is a bit more involved.

+

You need to make sure you have the following software installed on your computer:

+
    +
  • Python 3 is recommended (but 2.7 is also supported) +On Ubuntu python3-dev, libssl-dev and libffi-dev are also required +sudo apt-get install python3-dev libssl-dev libffi-dev
  • +
  • ImageMagick (brew install imagemagick can get you this on OS X and sudo apt-get install imagemagick +on Ubuntu the imagemagick package needs to be installed. +On Windows do choco install imagemagick, which requires chocolatey, +or download from here).
  • +
+

Once you have those installed and have made sure that they are on your PATH, you can +get Lektor installed with our installation script:

+
# curl -sf https://www.getlektor.com/installer.py | python3
+
+

This will attempt to install lektor in your user's HOME. If you want a system-wide installation, try this instead:

+
$ curl -sf https://www.getlektor.com/installer.py | sudo python3
+
+

If you would like to install Lektor without being prompted, set LEKTOR_SILENT before running the prior command.

+

For Windows, make sure that Python is in your PATH and run in Powershell:

+
PS C:\> (new-object net.webclient).DownloadString('https://www.getlektor.com/installer.py') | python
+
+

or you can use the command prompt instead:

+
C:\> @powershell -NoProfile -Command "(new-object net.webclient).DownloadString('https://www.getlektor.com/installer.py') | python"
+
+

pip

Alternatively you can manually install the command line version with +virtualenv if you know how that works. Note that this method is heavily +discouraged for anything other than advanced use cases such as build servers.

+
$ virtualenv venv
+$ . venv/bin/activate
+$ pip install Lektor
+
+

When we say this installation type is discouraged we mean it. The reason +is that it encourages uses of Lektor which are entirely unsupported by us. +Lektor actively manages virtualenvs for plugin installations in very specific +ways and this might or might not work in your setup. We support pip +installations for deployment environments and local development only.

Development Version

If you want to install the development version of Lektor you can do so. It's +the same as with installing the command line application but instead of +using PyPI you install directly from git and you need to have npm installed +to build the admin UI:

+
$ git clone https://github.com/lektor/lektor
+$ cd lektor
+$ make build-js
+$ virtualenv venv
+$ . venv/bin/activate
+$ pip install --editable .
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/models/attachments/index.html b/docs/models/attachments/index.html new file mode 100644 index 00000000..245badaf --- /dev/null +++ b/docs/models/attachments/index.html @@ -0,0 +1,235 @@ + + + + + + + + + + Attachments | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

Attachments

+ + + +
    + + + +
+ +

Each source can also have other files attached. Anything that is not +the main content file in a folder is considered to be an attachment. +There are a few settings to control these in the [attachments] section:

+
    +
  • enabled: if set to no then attachments are disabled. If they do +exist in the folder they are silently ignored.
  • +
  • model: an optional default model that is used for all attachments.
  • +
  • order_by: controls the ordering of attachments, similar to how this +works for child pages.
  • +
  • hidden: if this is set it can override the hidden flag for all +attachments at once. The default as of Lektor 2 is that attachments are +not hidden by default.
  • +
+

The hidden flag was added in Lektor 2.0 and the default was changed so +that attachments are not hidden by default, even if the parent is.

+ + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/models/children/index.html b/docs/models/children/index.html new file mode 100644 index 00000000..60638f0e --- /dev/null +++ b/docs/models/children/index.html @@ -0,0 +1,305 @@ + + + + + + + + + + Children & Pagination | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

Children & Pagination

+ + + +
    + + + +
+ +

By default each model can have child pages. This is what enables the +hierarchical structure of the Lektor database. Children are configured +together with a model that encloses it. This is typically called the +“collection model”. For instance you can have a collection model called +pages which is the parent to a few page children.

+

Child Configuration

Most configuration related to child pages goes into [children]. It +configures how children of the model should be handled. In particular it +controls if a page can have children to begin with, if the children can be of +any format or have to match specific models and more.

+

Here are the most important options below [children]:

+
    +
  • enabled: this can enable or disable children. The default is that a +page can have children.
  • +
  • slug_format: this key controls the URL key for children. By default +the URL key is the ID of the page. However in some cases you might +want to change that. For instance blog-posts might want to pull in +parts of the date into the URL. This is a template expression.
  • +
  • model: if this is set to a string, then all children are automatically +forced to the same model and the UI will not give a way to select a +model when creating a new child page. This allows specific parts of +the website to use the correct models automatically. For instance you +can force all pages below /projects to use the project model.
  • +
  • order_by: a comma separated list of fields that indicate the default +sort order. If a field is prefixed with a minus sign, the order is +inversed.
  • +
  • replaced_with: this allows a page to simulate that it has children +when it really has not. This can be a query expression and the result +is then used as the children of the model. This for instance can be +used to implement categories with filtering.
  • +
  • hidden: if this is set it can override the parent's hidden flag for +all children. This is particularly useful if you want to have a folder +for error pages or other special pages where the parent itself should not +be rendered but all children are. The default is not set.
  • +
+

The hidden flag was added in Lektor 2.0

Child Slug Behavior

Slugs are the URL paths or more correctly: parts of it. The URL paths +always are the concatenation from the parent's page URL path plus the +children's slug. If not configured the default slug of children is the +page's _id. A slug can contain slashes to navigate into folders. This +also allows pages to overlap into other pages. For instance if you have +a model called categories which is used by a folder named categories/, +that folder could set the _slug to blog/categories and then the URL +for categories would be blog/categories/example instead of +categories/example.

+

The default slug can be changed with the slug_format parameter in the +[children] section which can be a template expression. For instance a +common way to format slugs would be to include some date components. What's +important about this is that the slug expression must not fail even if fields +are empty! This is necessary because new pages will start out with the +fields not being filled in.

+

This for instance includes a date in the URL if set:

+
slug_format = {{ (this.date|dateformat('YYYY/M/') if this.date) ~ this._id }}
+
+

Pagination

In general a source document renders into a single page. The exception to +that rule are pages with children which show the children on the rendered +page and have pagination enabled. In that case it becomes possible to +slide the range of children into smaller pieces and render those slides +instead.

+

Pagination is controlled from the [pagination] section. The following +keys are available:

+
    +
  • enabled: if set to yes pagination becomes enabled. It's off by +default.
  • +
  • per_page: this controls how many children are shown per page. If +pagination is enabled and this is not set, an implicit default of 20 +is assumed.
  • +
  • items: if this is set to a query then the pagination's items will be +overridden by it. This can be used to make the pagination work over a +subset of items.
  • +
+

If pagination is enabled then the pagination attribute of a record becomes available. For +more information have a look at the pagination guide.

+

The items property was added in Lektor 2.0

+ + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/models/flow/index.html b/docs/models/flow/index.html new file mode 100644 index 00000000..eb6ae6d3 --- /dev/null +++ b/docs/models/flow/index.html @@ -0,0 +1,272 @@ + + + + + + + + + + Flow Block Models | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

Flow Block Models

+ + + +
    + + + +
+ +

To use Flow you need to define flow block models. +If you are not familiar with Flow yet, you should read the Introduction +Documentation to Flow first.

+

Defining Models

Flow block models work pretty much exactly the same as Regular Models. The differences are mostly minor and of cosmetic nature. They +are stored in the flowblocks/ folder and are ini files just like models.

+

Instead of using [model] as section, the section is called [block].

+

Here a very basic flow block model flowblocks/text.ini:

+
[block]
+name = Text Block
+button_label = Text
+
+[fields.text]
+label = Text
+type = markdown
+
+[fields.class]
+label = Class
+type = select
+choices = default, centered
+choice_labels = Default, Centered
+default = default
+
+

This should be self explanatory. One thing that is different about blocks +compared to regular models is that they support the button_label attribute +which can be used to customize the label of the button that adds blocks to +a flow.

+

Templates

Now that we have a model for our flow block, we need to create a template +for it. Templates for blocks are stored in the blocks subdirectory of the +templates folder. +The name for the block template is automatically derived from the config file +that keeps the flow block definition (templates/blocks/NAME.html): +In our case the expected template is templates/blocks/text.html, +as our flow block is defined in a file called text.ini.

+

Here is a suitable template for this:

+
<div class="text-block text-block-{{ this.class }}">
+  {{ this.text }}
+</div>
+
+

If you need to access the page the flow is used by, you can use the record +template variable.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/models/index.html b/docs/models/index.html new file mode 100644 index 00000000..86696211 --- /dev/null +++ b/docs/models/index.html @@ -0,0 +1,356 @@ + + + + + + + + + + Data Modelling | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

Data Modelling

+ + + +
    + + + +
+ +

What makes Lektor so powerful is the ability to model your data and to then use +this data to generate the final results. Getting this part right will make it +easier later to generate beautiful looking HTML.

+

Models

Models are the blueprints for your pages. They define which fields exist and +what goes into them. Models are stored in the models folder in your project +and are basic UTF-8 encoded INI files. Models can have any name but if no +model has been explicitly selected, a default model will be selected. For +most situations this will be the model with the name page. Detailed +information can be found under Default Model Selection.

+

Here is an example of a very basic model (models/page.ini):

+
[model]
+name = Page
+label = {{ this.title }}
+
+[fields.title]
+label = Title
+type = string
+size = large
+
+[fields.body]
+label = Body
+type = markdown
+
+

In this particular case, we have a model with the id page (as defined by the +filename) and a name Page which will appear like that in the UI. Pages that +use this model will use the template expression {{ this.title }} to be +displayed in the UI. In this case, it uses the title of the page.

+

There are two fields defined: a title and a body. The former is just an +unformatted string which is shown larger in the UI (size = large) and the +latter uses markdown for rendering. This will give it a text area in the admin +panel.

+

Fields

Fields for models are ordered in the UI in the order they appear in the model. +Most options in the field are specific to the type that is selected, but some +are the same for all of them.

+

Fields not only define the behavior of the data (for instance strings and +integers are sorted differently) but also how it's shown in the UI and what +can be done with it in general.

+

The following options are used for all types:

+
    +
  • label: the label for the field. This is shown in the UI in larger letters
  • +
  • description: an optional string that provides some description for the +field that is shown in the UI to give a bit more explanation.
  • +
  • addon_label: an optional string that is supported by all types that are +rendered as an input field. This string is shown as an UI label on the +right side of the input field to give it more context. For instance, it can +be used to clarify units of a field (pixel, percent etc.).
  • +
  • width: defines the width of the input in the admin as a fraction. For +instance 1/4 sets it to a quarter of the width, 1/2 to a half etc.
  • +
  • size can be set to normal, small or large to affect the size a +field is rendered in the admin UI.
  • +
  • type: defines the type of the field. Depending on the type more options +can become available.
  • +
+

There are many different field types that are available and they are documented +extensively in the types documentation.

+

Model Options

Models have the following options that can customize the model itself:

+
    +
  • name: the name of the model itself. Usually a more capitalized form of +the filename which is the ID of the model.
  • +
  • label: a template expression that should be used for pages that use this +model. Typically this expression refers to the title but not always. For +instance blog posts might also want to refer to the date.
  • +
  • hidden: a boolean value that indicates if the model should be hidden from +the UI or not. If set to yes then new pages cannot select this model. +This is very useful for models that are implied through configuration.
  • +
  • protected: if a model is set to protected then all of its instances +cannot be deleted once created.
  • +
  • inherits: if you want to inherit all fields and model option settings from another model then this +can be set to the name of another model.
  • +
+

In addition to that, there are some configuration sections in the model file +that can customize more behavior.

+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/models/selection/index.html b/docs/models/selection/index.html new file mode 100644 index 00000000..fa031769 --- /dev/null +++ b/docs/models/selection/index.html @@ -0,0 +1,237 @@ + + + + + + + + + + Default Model Selection | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

Default Model Selection

+ + + +
    + + + +
+ +

When Lektor encounters a content file it needs to decide which data model to +use for figuring out how to handle the fields. In the ideal case the content +file contains _model field which will point explicitly to a model. However +if a model was not defined it's picked automatically.

+

Lektor will attempt to load a few models and will pick the first that exists. +If no model exists at all then Lektor calls back to the special none model +which is empty other than for system fields.

+
    +
  1. If a model is defined for children by the parent model then it's used. +For more information about this feature see Children & Pagination.
  2. +
  3. The ID of the page is attempted as model name next.
  4. +
  5. If it still does not match anything, it will try the default page +model.
  6. +
  7. If that also does not match, it falls back to the special none model +which is always empty.
  8. +
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/plugins/dev/index.html b/docs/plugins/dev/index.html new file mode 100644 index 00000000..d0007278 --- /dev/null +++ b/docs/plugins/dev/index.html @@ -0,0 +1,355 @@ + + + + + + + + + + Development | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

Development

+ + + +
    + + + +
+ +

If you want to dive into plugin development yourself, this guide will get you +going quickly. Before we can get started you need to have a Lektor project +we can temporarily add the plugin to and you need to have the lektor +command line tool installed.

+

Enable Development Mode

When developing plugins it's very useful to enable Lektor's development +mode before starting the server. This can be achieved by exporting the +LEKTOR_DEV environment variable and setting it to 1:

+
$ export LEKTOR_DEV=1
+$ lektor server
+
+

With that in place, Lektor will automatically restart the development server +when the plugin is changing.

+

Creating A Package

Plugins come in packages. To make one, just create a folder with a sensible +name (typically the name of your plugin minus the lektor- prefix) in your +packages/ folder.

+

You can either do this manually or you can use the lektor dev new-plugin +command (see new-plugin) which will create +this folder structure for you:

+
$ lektor dev new-plugin
+
+

This will guide you through a flow which ends up creating a new plugin +package in the packages folder.

+

Alternatively you can manually create a packages/hello-world/ folder.

+

Once that is done, we need to create a setup.py file which tells Lektor +what your plugin needs to run. This will already be created for you if +you used the wizard.

+
from setuptools import setup
+
+setup(
+    name='lektor-hello-world',
+    version='0.1',
+    py_modules=['lektor_hello_world'],
+    entry_points={
+        'lektor.plugins': [
+            'hello-world = lektor_hello_world:HelloWorldPlugin',
+        ]
+    },
+    install_requires=[]
+)
+
+

So going line by line, these are what the things mean:

+
    +
  • setuptools is a module that helps us install the package with the +Python interpreter that Lektor uses. We only need the setup function +from it for this example.
  • +
  • name is the name of the plugin when it's published to the Python package +index where all Lektor plugins go. As such it should be prefixed with +lektor- to make it not clash with other packages on the index.
  • +
  • version identifies the version. During local development it does not +matter what you write here, but it will play a role once you start +publishing your packages. Users need to reference exact versions of these +plugins when using them.
  • +
  • py_modules: this is a list of modules that your plugin needs to run. +This should always be exactly one module named lektor_XXX where XXX +is your plugin name with underscores instead of dashes as separators. +If you need more than one module you should use a package instead. This is +not covered here, but you can find this in the setuptools documentation.
  • +
  • entry_points: this is meta data that is needed to associate our package +with Lektor. Lektor will load all plugins in the lektor.plugins list. +It can be a list of definitions in the form plugin-name = import_path. +The plugin name is what will show up in the plugin list in Lektor, +the import path should be the dotted import path to the module that contains +the plugin followed by a colon (:) with the class name afterwards.
  • +
  • install_requires: this is a list of dependencies for our plugin. We +leave it empty here as we do not depend on anything in this simple +example.
  • +
+

Creating The Plugin

Now it's time to create our first plugin that does absolutely nothing. We +create a new file with the name lektor_hello_world.py next to our +setup.py and put the following things in:

+
from lektor.pluginsystem import Plugin
+
+class HelloWorldPlugin(Plugin):
+    name = 'Hello World'
+    description = 'This is a demo plugin for testing purposes.'
+
+

If you now start your lektor server with lektor server you should +see some output that indicates that the plugin was loaded. You can also +get a list with lektor plugins list:

+
$ lektor plugins list
+hello-world: Hello World
+  This is a demo plugin for testing purposes.
+  path: /Users/john/demo/packages/hello-world
+  import-name: lektor_hello_world:HelloWorldPlugin
+
+

Hooking Events

Plugins in Lektor are based on the concept of hooking events. There are many +events that can be hooked but we will only cover a very basic one here, +the setup-env event. To respond to it, we need to implement +a function named on_setup_env:

+
import random
+
+MESSAGES = [
+    'Reticulating splines',
+    'Populating slots',
+    'Possessing pawns',
+]
+
+def get_random_message():
+    return random.choice(MESSAGES)
+
+class HelloWorldPlugin(Plugin):
+    name = 'Hello World'
+    description = 'This is a demo plugin for testing purposes.'
+
+    def on_setup_env(self, **extra):
+        self.env.jinja_env.globals.update(
+            get_random_message=get_random_message
+        )
+
+

This will inject a function with the name get_random_message into our +template globals when the environment is initialized. This means that we +can access this function from templates then:

+
<p>Message of the page: {{ get_random_message() }}
+
+

There are many events that can be hooked and they can be found in the +Event Documentation. All events need +to be subscribed with an extra **extra argument to catch down additional +arguments that might be supplied in the future.

+

What Plugins Can Do

To understand what you can do with plugins have a look at the +Plugin API.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/plugins/howto/index.html b/docs/plugins/howto/index.html new file mode 100644 index 00000000..038df356 --- /dev/null +++ b/docs/plugins/howto/index.html @@ -0,0 +1,381 @@ + + + + + + + + + + How To | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

How To

+ + + +
    + + + +
+ +

So you want to build a plugin but it's not quite clear how you would structure +a plugin to accomplish this? This part of the documentation should help you +find answers to those questions.

+

Expose Functionality

Most plugins will provide functionality of sorts. There are two places where +functionality is typically needed: in templates or for other plugins to use. +Plugins can import from each other just like this, but functionality exposed +into templates should follow some basic rules:

+
    +
  • modify jinja_env.globals or jinja_env.filters and do not use +process-template-context unless you absolutely know what you are doing.
  • +
  • expose as few global variables as possible. If you have a lot you want to +provide then consider registering an object with the templates and to +attach multiple attributes on it.
  • +
  • use clear names for template globals. This is a shared space that all +plugins and Lektor itself modify so do not provide a function called +get_script but for instance call it get_my_plugin_script.
  • +
+

A simple example of a plugin that implements Gravatar support:

+
from hashlib import md5
+from werkzeug.urls import url_encode
+from lektor.pluginsystem import Plugin
+
+BASE_URL = 'https://secure.gravatar.com/avatar/'
+
+def get_gravatar(email, **options):
+    fn = md5(email.lower().strip().encode('utf-8')).hexdigest()
+    return '%s/%s?%s' % (BASE_URL, fn, url_encode(options))
+
+class GravatarPlugin(Plugin):
+    name = 'Gravatar'
+    def on_setup_env(self, **extra):
+        self.env.jinja_env.filters['gravatar'] = get_gravatar
+
+

Configure Plugins

Plugins can come with their own config files and it's encouraged that plugins +take advantage of this. Each plugin has exactly one INI file called +<plugin-id>.ini inside the configs folder.

+

To get access to the plugin the get_config function can be used which +returns a dict like object to access the ini file.

+
config = self.get_config()
+value = config.get('section.key', 'default_value')
+
+

This would correspond to this config in configs/my-plugin.ini:

+
[section]
+key = the value
+
+

Dependency Tracking

While a lot of dependencies are tracked automatically, when you develop a +plugin you probably will discover that sometimes you need to track your own +ones. There are different ways in which dependency tracking can work and +depending on the situation you might have to use two different mechanisms.

+
    +
  1. Dependency tracking by association: while a build of a source object +into an artifact is active more dependencies for that artifact can be +registered with the record_dependency +method of the context. It takes a filename that should be recorded as +additional dependency for the current artifact
  2. +
  3. Dependency tracking as artifact source: if you build your own artifact +you need to define the source files that make up the artifact (if you have +such a thing). For instance if you build a thumbnail you will need to +track those source files that are the source images. This can be done +through the sub_artifact +method which declares a new artifact.
  4. +
+

Here is an example of both ways in one plugin:

+
import os
+from flask import json
+from lektor.pluginsystem import Plugin
+
+def dump_exif(image):
+    ctx = get_ctx()
+    path = posixpath.join(image.path, '-exif.json')
+    @ctx.sub_artifact(path, sources=[image.source_filename])
+    def include_file(artifact):
+        ctx.record_dependency(__file__)
+        with artifact.open('wb') as f:
+            json.dump(image.exif.to_dict(), f)
+    return path
+
+class ExifDumpPlugin(Plugin):
+    def setup_env(self, **extra):
+        self.env.jinja_env.globals['dump_exif'] = dump_exif
+
+

This dumps out the EXIF data into a JSON file and returns the artifact name. +The source image is tracked as direct source for the artifact and within the +function we also track the plugin's filename to rebuild if the plugin changes.

+

Adding New Field Types

Let's say you want to add an "asciidoc" +field type so you can write with AsciiDoc markup.

+

First install AsciiDoc so its command-line program is available. Then update blog-post.ini from the blog guide like so:

+
[fields.body]
+label = Body
+type = asciidoc  # Custom type.
+
+

In a blog post's contents.lr, write some AsciiDoc like:

+
body:
+
+== Header 1
+
+Some text.
+
+----
+code here
+----
+
+

You can add your "asciidoc" type to Lektor with a plugin:

+
from subprocess import PIPE, Popen
+
+from lektor.pluginsystem import Plugin
+from lektor.types import Type
+
+
+def asciidoc_to_html(text):
+    # The "-" at the end tells asciidoc to read from stdin.
+    p = Popen(
+        ['asciidoc', '--no-header-footer', 
+         '--backend=html5', '-'],
+        stdin=PIPE, stdout=PIPE, stderr=PIPE)
+
+    out, err = p.communicate(text)
+    if p.returncode != 0:
+        raise RuntimeError('asciidoc: "%s"' % err)
+
+    return out
+
+
+# Wrapper with an __html__ method prevents
+# Lektor from escaping HTML tags.
+class HTML(object):
+    def __init__(self, html):
+        self.html = html
+
+    def __html__(self):
+        return self.html
+
+
+class AsciiDocType(Type):
+    widget = 'multiline-text'
+
+    def value_from_raw(self, raw):
+        return HTML(asciidoc_to_html(raw.value or u''))
+
+
+class AsciiDocPlugin(Plugin):
+    name = u'AsciiDoc'
+    description = u'Adds AsciiDoc field type to Lektor.'
+
+    def on_setup_env(self, **extra):
+        # Derives type name "asciidoc" from class name.
+        self.env.add_type(AsciiDocType)
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/plugins/index.html b/docs/plugins/index.html new file mode 100644 index 00000000..aefd12a2 --- /dev/null +++ b/docs/plugins/index.html @@ -0,0 +1,295 @@ + + + + + + + + + + Plugins | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

Plugins

+ + + +
    + + + +
+ +

Lektor can be extended through the use of plugins. This is something that +can be done on a per-project basis. This gives a quick overview of how +to use plugins and how to build your own.

+

Installing Published Plugins

Lektor can find and install plugins that have been published to PyPI for you. +For completely automated plugin management just open your project file in a +text editor and edit or extend the [packages] section. Just add a line +for each plugin in the form name = version:

+
[packages]
+lektor-cool-plugin = 1.0
+lektor-other-plugin = 1.2
+
+

It's also possible to use the plugins add command +lektor plugin add NAME to automatically add the latest version of a plugin +to the project file.

+

To upgrade a plugin just increase the version number to the release you want +and Lektor will do the rest.

+

Loading Plugins

Plugins can be added to a Lektor project in two different ways:

+
    +
  1. Plugins can be added to the [packages] section of the project. In that +case Lektor will automatically download and enable the plugin next time +you build the project or run the server. This can be accomplished for you +with the automatic install above, or it can be done manually.
  2. +
  3. Plugins can be added to the packages/ folder in your project. Each +plugin has to go into a separate folder. This method is especially useful +for project specific plugins or for plugin development.
  4. +
+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/plugins/list/index.html b/docs/plugins/list/index.html new file mode 100644 index 00000000..4d31b588 --- /dev/null +++ b/docs/plugins/list/index.html @@ -0,0 +1 @@ + diff --git a/docs/plugins/publishing/index.html b/docs/plugins/publishing/index.html new file mode 100644 index 00000000..0b3d6f67 --- /dev/null +++ b/docs/plugins/publishing/index.html @@ -0,0 +1,322 @@ + + + + + + + + + + Publishing | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

Publishing

+ + + +
    + + + +
+ +

Once you are happy with a plugin you can publish it so that other people +can use it. Publishing of plugins happens through the +Python Package Index and can be +automatically done with the help of the lektor shell command.

+

Enhance your setup.py

Before you can go about publishing your plugin there needs to be at least +some information added about it to your setup.py. At least the keys +name, version, author, author_email, url and description need to be +set. Here is an example of doing this, largely taken from what is given by +the CLI command lektor dev new-plugin:

+
import ast
+import io
+import re
+
+from setuptools import setup, find_packages
+
+with io.open('README.md', 'rt', encoding="utf8") as f:
+    readme = f.read()
+
+_description_re = re.compile(r'description\s+=\s+(?P<description>.*)')
+
+with open('lektor_hello_world.py', 'rb') as f:
+    description = str(ast.literal_eval(_description_re.search(
+        f.read().decode('utf-8')).group(1)))
+
+setup(
+    author='Your Name',
+    author_email='your.email@your.domain.invalid',
+    description=description,
+    keywords='Lektor plugin static-site blog',
+    license='MIT',
+    long_description=readme,
+    long_description_content_type='text/markdown',
+    name='lektor-hello-world',
+    packages=find_packages(),
+    py_modules=['lektor_hello_world'],
+    url='http://github.com/youruser/lektor-yourplugin',
+    version='1.0',
+    classifiers=[
+        'Framework :: Lektor',
+        'Environment :: Web Environment',
+        'Environment :: Plugins',
+        'License :: OSI Approved :: MIT License',
+    ],
+    entry_points={
+        'lektor.plugins': [
+            'hello-world = lektor_hello_world:HelloWorldPlugin',
+        ]
+    }
+)
+
+

This is not the most basic setup.py that is strictly necessary, but instead a more full, ideal setup.py that will help your plugin be discovered and and understood most easily. Note that is assumes there is a README.md file, and that name and description are defined in your plugin's .py module file, which is their preferred location for Lektor.

+

Publishing

Once you augmented your setup.py you can go ahead with the publishing. First +you need to make sure you have a PyPI account. If you do not, you can +create one at pypi.python.org.

+

Once you have done that, you can publish the plugin from the command line +with the lektor command:

+
$ cd path/to/your/plugin
+$ lektor dev publish-plugin
+
+

When you use this for the first time it will prompt you for your login +credentials for pypi. Next time it will have remembered them.

+

Listing on this site

Guide

We'd love to see your new plugin listed on our plugins page. To do that, submit a pull request to this repository that adds your plugin as a sub-page of /plugins. To have your plugin page look it's best and be found more easily here and on PyPI, please fill out your setup.py completely (as in the above snippet), including

+
    +
  • author and author_email
  • +
  • classifiers, (optional) such as
      +
    • Framework :: Lektor,
    • +
    • Environment :: Web Environment,
    • +
    • Environment :: Plugins,
    • +
    • License :: OSI Approved :: [X] License (substitute your license),
    • +
    +
  • +
  • keywords (optional),
  • +
  • long_description and long_description_content_type,
  • +
  • project_urls (optional),
  • +
  • url to link to your repository on GitHub
  • +
+

Using Markdown for a long_description is new functionality of PyPI as of March 16, 2018 that requires setuptools>=38.6.0, twine>=1.11.0, and wheel>=0.31.0 if you're using wheels.

The long_description is required to have a page on getlektor.com and PyPI that looks filled out. We process it the same way PyPI does, so if it looks good there it should look good on this site. This means that if you chose to have a Markdown README instead of reStructuredText, you will also need the appropriate long_description_content_type. We pull most of this data from PyPI, so if the plugin's setup.py's changes are not published, neither site will update. We update on build which happens at least daily. We also pull some information from GitHub when the url field is set to the plugin's GitHub project page.

+

When you submit your pull request, be sure to add some tags. Tags are used on this site to help navigation and discovery of plugins. These are not the same as keywords in your setup.py, which are used on PyPI. Specifically, at least include tags for the plugin events that your plugin hooks, such as setup-env. These in particular will help new plugin developers learn how to interact with these hooks by example.

+

Requirements

Please follow the above guide to get your plugin page on this site and looking it's best. To be clear though, for a new plugin to be listed on this site, the following must be done:

+
    +
  1. The plugin must be available on PyPI.
  2. +
  3. The plugin's page name on this site is the name of the package on PyPI.
  4. +
  5. The plugin must be in a category, or else it will not appear anywhere on the plugins page. New categories are allowed if it makes sense for your plugin.
  6. +
  7. The plugin must have a long_description and README.
  8. +
  9. The plugin must have tags. At minimum these should include all plugin events the code uses.
  10. +
  11. name and description must be defined in the plugin's subclass in its source code. This is needed by for lektor plugins list -v to display appropriate information.
  12. +
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/project/file/index.html b/docs/project/file/index.html new file mode 100644 index 00000000..bda5accb --- /dev/null +++ b/docs/project/file/index.html @@ -0,0 +1,418 @@ + + + + + + + + + + Project File | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

Project File

+ + + +
    + + + +
+ +

The project file holds the main configuration of the project and is used to +identify the project for the user interface. The project file is an INI file +(UTF-8 encoded like everything else in Lektor) and the minimal content is the +name of the project:

+
[project]
+name = My Fancy Project
+
+

The name of the file can be arbitrary but must have the .lektorproject +extension or Lektor will not be able to find it. When Lektor looks for a +project it looks upwards from the current folder until it finds a single +file with the .lektorproject extension and that's then the root of the project.

+

It's possible to build a Lektor project in the absence of a Project file, +but this usage is heavily discouraged. It exists primarily for quick +testing situations. But don't be confused if you encounter a Lektor project +that does not come with a corresponding project file.

Config Sections

Within the project file there are various configuration sections. The +following sections currently exist:

+

[project]

This section controls some basics about the project:

+

name

+

This is the human readable name of the project. It's used in various +places where the system wants to show the context of the operations. For +instance the admin panel will display this to indicate which project is +being worked on.

+
+

locale

+

This is the default locale of the website. This defaults to en_US and +can be changed to many others. Most locales of the CLDR project are +supported. This information is for instance used to format dates.

+
+

url

+

This is the full URL of the website. If set this information can be used +to enable the external URL generation parameter. Lektor tries hard to +make websites work in a way where this information is not necessary but +some systems might need it. For instance sitemaps require full URLs and +not having them would be a violation of the specification.

+
+

url_style

+

This controls the style of generated URL references through the +url_to function or filters. The default +value for this is relative. The following values are possible:

+ + + + + + + + + + + + + + + + + + + + +
ValueBehavior
relativeURLs are generated relative to the currently active page.
absoluteURLs are generated absolute (relative to root page)
externalURLs are generated with the fully canonical URL (external).
+

There are advantages and disadvantages to all styles. relative has the +benefit that it works without any configuration no matter where you deploy +to. The downside is that you cannot have a page appear on multiple paths +which for instance breaks custom error pages. absolute is useful for +situations where you have custom error pages and you generally know a bit +about the server you are deploying to. external generally makes not a lot +of sense as default setting but exists for consistency's sake.

+

For individual URLs that are generated with the url_to function it's possible to override the +default URL style.

+
+

path

+

This setting can be used to configure a different path for the project +tree. This requires a bit of explanation:

+

If this is not set (which is the default) then Lektor will find the +content files right next to the project file. However in some situations +you might want to move a project file to a completely different location +for instance because you want to have settings in there that you do not +want to put into version control. In that case you can set the path +in the file to a path (absolute or relative to the project file) which +resolves to the project tree.

+

Note that if this setting is used some functionality in the desktop app +might no longer work (for instance opening .lr files with a double click).

+
+

output_path

+

Configure the build path for your project. By default, Lektor will detect a +proper location depeding on your operation system, only use this setting if +you want to set a custom path. +The path is relative to the project file, absolute paths are allowed but not +portable between distinct filesystems.

+
+

excluded_assets

+

A list of file names or Unix shell-style wildcards, separated by commas. +The wildcard syntax follows fnmatch.

+

By default, filenames beginning with "_" or "." are not copied from the +assets directory to the output directory. Exclude additional files with +the excluded_assets option.

+
+

included_assets

+

A comma-separated list of file names or Unix shell-style wildcards, specifying +files that should be copied from the assets directory to the output +directory even if they begin with "_" or "." (the default exclusion patterns) +or match your custom excluded_assets pattern. The wildcard syntax follows +fnmatch.

+
+

Example:

+
[project]
+name = My Website
+url = https://www.mywebsite.invalid/
+locale = de_DE
+excluded_assets = *.backup, *~
+included_assets = _special_file
+
+

[packages]

This section controls the packages (plugins) that should be installed for +this project. It's a simple key/value list where the key is the plugin +name and the value is the version number.

+

Example:

+
[packages]
+lektor-webpack-support = 0.1
+
+

[servers.*]

This section can be repeated and each instance sets up a server. The * +needs to be replaced with the ID of the server. This ID is used by the +command line tool to select the server to deploy to. For more information +about this see the Deployment Guide

+

name

+

Human readable name for this server (shown in the UI)

+
+

target

+

The target URL for the server. This URL is specific to the deployment +method that is being used. For a list of which URLs are supported refer +to the deployment guides.

+
+

enabled

+

This setting can be used to enable/disable the server. The default is yes.

+
+

default

+

This can be used to set a server to be used by default. If only one server +is configured it's an implicit default.

+
+

Example:

+
[servers.production]
+name = Production
+enabled = yes
+default = yes
+target = rsync://server/path/to/folder
+
+

[alternatives.*]

This configures Alternatives. It is repeated for +each intended alternative. The default behavior is that alternatives are +disabled.

+

name

+

The human readable name for the alternative. The admin interface uses this.

+
+

url_prefix

+

A prefix that is added in front of all URLs to identify this alternative.

+
+

url_suffix

+

A suffix that is added behind all URLs to enable this alternative. This is +currently discouraged compared to the URL prefix as it might not yet work +in all situations properly.

+
+

primary

+

If this is set to true then the alternative is selected as primary. For +more information about this refer to the guide.

+
+

locale

+

This setting can override the global site locale for a specific alternative.

+
+

Example:

+
[alternatives.en]
+name = English
+primary = yes
+locale = en_US
+
+[alternatives.fr]
+name = French
+url_prefix = /fr/
+locale = fr
+
+

[attachment_types]

Lektor does some basic attachment type detection based on file extension. This is what powers the this.attachemnts.images and this.attachments.videos attributes for instance. If the built-in map does not cover your file extension you can extend it or add new attachement types on a project by project basis.

+

Example:

+
[attachment_types]
+; <.file-ext> = <type>
+.gpx = gpx
+.ogv = video
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/project/index.html b/docs/project/index.html new file mode 100644 index 00000000..2f03ff49 --- /dev/null +++ b/docs/project/index.html @@ -0,0 +1,245 @@ + + + + + + + + + + Project | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

Project

+ + + +
    + + + +
+ +

A project in the context of Lektor is a single website. It's typically a +folder that contains all the information necessary to build it. Within that +folder there are templates, models, content files as well as the main project +file which acts as configuration file.

+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/project/structure/index.html b/docs/project/structure/index.html new file mode 100644 index 00000000..230253b2 --- /dev/null +++ b/docs/project/structure/index.html @@ -0,0 +1,303 @@ + + + + + + + + + + Folder Structure | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

Folder Structure

+ + + +
    + + + +
+ +

When you start your first Lektor project it's important to understand how data +is structured on the file system. A Lektor project is a folder on the file +system with a project file and a well defined structure.

+

The most basic layout looks like this:

+
yourproject.lektorproject
+content/
+models/
+templates/
+assets/
+
+

There are a few more folders that play a role and plugins can add even more.

+

Project File

The project file holds the main configuration of the project and is used to +identify the project for the user interface. The name does not matter but +it needs to have the .lektorproject extension. For more information about +that see Project File.

+

Folders

content/

The content folder is named content and contains all the sources that are +built into the final project. Each folder within corresponds to a record +and the data of it is stored in the file by the name contents.lr within +which is a Lektor content file. All other files are considered attachments.

+

Here is a basic example layout to get an idea how this can look like:

+
content/
+  contents.lr
+  projects/
+    contents.lr
+    project-a/
+      contents.lr
+      thumbnail.png
+    project-b/
+      contents.lr
+      thumbnail.png
+    project-c/
+      contents.lr
+      thumbnail.png
+
+

The content folder is explained in detail in Content.

+

models/

This is the bread and butter of what makes Lektor powerful. The models define +exactly how the data from the content folder should be processed. The models +folder contains a list of INI files that each correspond to a single model.

+

For more information about this refer to the Data Modelling +documentation.

+

templates/

Each model corresponds to a template from the templates folder. So if you have a +model named page the file named page.html from the templates folder will then +be used to render it.

+

assets/

Whatever is stored in the assets folder is copied over verbatim to the final +result. So if you put a folder named css in there with all your static CSS +files they will appear as such in the final output.

+

This folder is not just useful for static files that are stylesheets or +scripts, but because it overlays the entire website you can also use it to +store things such as favicon.ico, .htaccess, robots.txt etc.

flowblocks/

The flowblocks folder contains models for blocks that are used by the +Flow System. Flow blocks split a part of a page into +smaller pieces so those could be individually designed. They work similar to models +but are contained within a field of a model.

+

packages/

For local plugin development the packages/ folder can be used. Any plugin +stored in there is automatically activated in the system.

+

configs/

This folder (configs/) contains plugin specific config files. All the +files in there are named <plugin-id>.ini.

+

databags/

Lektor also supports Data Bags which go into a +folder named databags/. These are files with some general information +that can be accessed from templates. For instance you could store menus and +navigations there, API keys and much more. This is generally just information +you want to access from different places and maybe not keep in templates directly.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/quickstart/admin.png b/docs/quickstart/admin.png new file mode 100644 index 00000000..728c06ab Binary files /dev/null and b/docs/quickstart/admin.png differ diff --git a/docs/quickstart/index.html b/docs/quickstart/index.html new file mode 100644 index 00000000..92a00f2a --- /dev/null +++ b/docs/quickstart/index.html @@ -0,0 +1,284 @@ + + + + + + + + + + Quickstart | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

Quickstart

+ + + +
    + + + +
+ +

The best way to get started with Lektor is to use the quickstart command to +let Lektor generate a basic project layout for you. This requires the use of +the command line client which is the recommended way to do development until +the website is ready for end user management.

+

If you do not have the lektor command line executable +available yet just consult the Installation section of +the documentation.

+

Creating a New Project

To create a new project open a terminal and navigate to the preferred location +of your project. Then execute the quickstart command to create a new project:

+
$ lektor quickstart
+
+

This will ask you a few questions and then create a new Lektor project with +some basic configuration for you.

+

Screencast

If you want a video walkthrough you can have a look at the screencast which +explains the quickstart project a bit:

+

Running your Project

Now that you have a project you can run it. As a developer the easiest way to +do that is to use the server which runs the project on your local machine +as if it was a dynamic website.

+

All you have to do is to enter your project directory and run it:

+
$ cd yourproject
+$ lektor server
+
+

This will automatically start the server and you can navigate to +localhost:5000 to open the project.

+

You can keep the server running, it will automatically rebuild your files as +they change.

+

Accessing the Admin

While the development server is running you can use the built-in admin +interface. It can be accessed by clicking on the pencil symbol on a page +or by manually navigating to /admin/.

+

screenshot of the admin

+

Building

When you want to build the website for distribution you can make Lektor build +everything into static files. In fact, that's already happening in the +background while the development server is running. If you want to trigger +a build you can use the build command. By default it builds into a lektor +cache directory.

+
$ lektor build
+
+

You can also explicitly provide a path if you are not satisfied with the +default directory. To see where this directory is you can use the +project-info command:

+
$ lektor project-info --output-path
+/Users/john/.../build-cache/6fdaeecab78d6aa99f86f586ab15da06
+
+

All your generated files will end up in that folder for easy publishing.

+

Next Steps

Now that you have done that, you might be interested in diving deeper into +Lektor. These might be good next steps:

+ +

This website is built on Lektor as well. You can find the sources of it +on GitHub and you can click +at any point on the source symbol () on the bottom +to see the source for the current page.

+ + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/search/index.html b/docs/search/index.html new file mode 100644 index 00000000..5327326c --- /dev/null +++ b/docs/search/index.html @@ -0,0 +1,199 @@ + + + + + + + + + + Search | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

Search

+ + + +
    + + + +
+ +

Not sure where to find something? Here you can search the Lektor +documentation:

+ + + + + + + + +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/templates/imageops/index.html b/docs/templates/imageops/index.html new file mode 100644 index 00000000..c6268371 --- /dev/null +++ b/docs/templates/imageops/index.html @@ -0,0 +1,287 @@ + + + + + + + + + + Image Operations | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

Image Operations

+ + + +
    + + + +
+ +

Images are separate files and as such just embedded into HTML files. However +very often you want to perform modifications on these images that require +interacting with those files directly. This can be conveniently done directly +from the template code through the image APIs that Lektor provides.

+

Accessing Images

To work with images one needs to get access to the image objects first. Images +are returned from the attachments of a page. If you want to make sure you +only operate with actual images the .images attribute can be used to filter +the query. For instance this iterates over all attached images of a page:

+
{% for image in this.attachments.images %}
+  <div class="image"><img src="{{ image|url }}"></div>
+{% endfor %}
+
+


+To access images from a different content folder, you would use:

+
{% for image in site.get('/myfolder').attachments.images %}
+  <div class="image"><img src="{{ image|url }}"></div>
+{% endfor %}
+
+


+To retrieve only a specific image or attachment with a certain name you would use

+
{% set my_image = site.get('/myfolder').attachments.get('imagenameexample.jpg') %}
+  <div class="image"><img src="{{ my_image|url }}"></div>
+
+

Accessing Image Data

One of the more common operations is to access the direct image data. This +is resolution and file format. The width, height and format parameters +are provided for this. In some cases this is very useful to generate CSS code +that needs to know about the original resolution. For instance this achieves a +retina rendered background:

+
<div style="
+  background: url({{ image|url }});
+  background-size: {{ image.width / 2 }}px {{ image.height / 2 }}px
+"></div>
+
+

Accessing EXIF Data

Lektor can also give you access to a lot of the EXIF information that is stored +in the images. Not all EXIF information is available but the most common +values are. For the full list of attributes see EXIF data.

+

Here an example that shows the camera information:

+
<div class="image">
+  <img src="{{ image|url }}" alt="">
+  <p><strong>Camera:</strong> {{ image.exif.camera }}
+</div>
+
+

Generating Thumbnails

While browsers are reasonably good at downscaling images themselves, you +still need to transmit the entire image. When you want smaller images it +often makes sense to generate thumbnails automatically. In Lektor each +image provides the thumbnail method.

+

It accepts the width and height of the target image. If either of these is not +provided, it will be computed automatically. The return value can be converted +into a URL with the |url filter:

+
<img src="{{ image.thumbnail(320)|url }}">
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/templates/index.html b/docs/templates/index.html new file mode 100644 index 00000000..849c57e6 --- /dev/null +++ b/docs/templates/index.html @@ -0,0 +1,379 @@ + + + + + + + + + + Templates | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

Templates

+ + + +
    + + + +
+ +

Lektor uses the Jinja2 templating language for +generating HTML out of your pages. You do not need to understand Jinja2 to +be able to generate beautiful websites but if you want to dive deep into the +powers of the templating language then you can learn more about it by +reading the Jinja2 Documentation.

+

Templates are a very powerful component in Lektor. A lot of documentation +about the features of it can be found in the Jinja2 Documentation as well as the Lektor Template API +Documentation.

Template Folder and Naming

All templates are stored within the templates/ folder. Templates typically +carry a .html extension. The default naming convention which is used in +Lektor is that the template name matches the model name.

+

So if you have a model called page there would be a template named +page.html. Pages can however manually force a different template to be +rendered.

+

Template Context

When a template is rendered it's rendered in the context of a few variables. +Which ones are available often depends on the situation the template is +evaluated in but the following are always available:

+ + + + + + + + + + + + + + + + + + + + + + + + +
VariableDescription
thisThe current Record that is being rendered.
siteThe database Pad that can be used to query the site.
altA string that identifies the Alternative of the page.
configGives access to the Lektor project configuration.
+

The First Template

So let's dive in making our first template. In case you went through the +Quickstart you should already have an example model +to work with called page, otherwise just add one with the format shown +in the Data Modelling Documentation.

+

With that we can create a page template named templates/page.html:

+
{% extends "layout.html" %}
+{% block title %}{{ this.title }}{% endblock %}
+{% block body %}
+  <h2>{{ this.title }}</h2>
+  {{ this.body }}
+{% endblock %}
+
+

If you are unfamiliar with Jinja this template might look very confusing, but +worry not. We will go through it step by step.

+
    +
  • {% starts a Jinja section and %} ends it
  • +
  • extends is a tag that instructs Jinja to extend another template. In +this case we extend our layout template. We will create this next.
  • +
  • block creates or updates a block from the layout template. In this case +we have two blocks: one for the title of the page and another one for +the body.
  • +
  • {{ prints a variable and }} is the end of the print part. We do not +need to worry about escaping here as Jinja2 does that automatically for +us.
  • +
+

Layout Templates

So we have this page template now, but what about this layout? Jinja2 +supports template inheritance where one template can inherit code from +another. In this case we configured our page template to inherit from +layout.html. Let's create it:

+
<!doctype html>
+<meta charset="utf-8">
+<title>{% block title %}Welcome{% endblock %} — My Website</title>
+<body>
+  <header>
+    <h1>My Website</h1>
+    <nav>
+      Navigation can go here.
+    </nav>
+  </header>
+  <div class="page">
+    {% block body %}{% endblock %}
+  </div>
+</body>
+
+

I hope you can see how the blocks work together now when template inheritance +is involved.

+

Everything about Templates

Templates are the bread and butter of creating expressive websites with +Lektor. As such this is one of the most complex topics in the documentation +and split into smaller parts. Feel free to experiment around to see what +you can do with it.

+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/templates/navigation/index.html b/docs/templates/navigation/index.html new file mode 100644 index 00000000..e99e67ca --- /dev/null +++ b/docs/templates/navigation/index.html @@ -0,0 +1,293 @@ + + + + + + + + + + Navigation | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

Navigation

+ + + +
    + + + +
+ +

Websites are all about hyperlinks and being able to explore more. As such +it's important to be able to provide a good navigation experience for your +users. Templating in Lektor makes it very easy to make automatic navigation +that keeps up to date with your pages. Most of this involves generating +links with the help of the URL Filter.

+

Basic Semi-Automatic Navigation

The most basic form of navigation is a semi automatic one. It's one of the +most flexible ones while still being easy to maintain. It requires knowledge +of which pages to show and what the link title should be:

+
<nav>
+  <ul class="nav navbar-nav">
+    <li{% if this._path == '/' %} class="active"{% endif
+      %}><a href="{{ '/'|url }}">Welcome</a></li>
+    {% for href, title in [
+      ['/blog', 'Blog'],
+      ['/projects', 'Projects'],
+      ['/about', 'About']
+    ] %}
+      <li{% if this.is_child_of(href) %} class="active"{% endif
+        %}><a href="{{ href|url }}">{{ title }}</a></li>
+    {% endfor %}
+  </ul>
+</nav>
+
+

In this case we use a list of pages (href and title) to automatically +generate some list items and we ask the current page (this) if it is +a child of the given path. Based on that information we automatically +add a class to the link.

+

The index page requires a bit of special casing as we do not want it to +be active if any of its children are active. So we just check if the +path of the current page is actually the path of the index page.

+

Fully Automatic Navigation

Sometimes all we want is to show navigation links for all sub-pages of +a page. This is easy to accomplish as well:

+
<nav>
+  <ul class="nav">
+    {% for project in site.get('/projects').children %}
+      <li{% if this == project %} class="active"{% endif
+        %}><a href="{{ project|url }}">{{ project.name }}</a></li>
+    {% endfor %}
+  </ul>
+</nav>
+
+

Recursive Tree Navigation

In some situations you want to show a tree like navigation. This is for +instance something that comes up when building site maps. In that situation +the recursive Jinja loop system really comes in handy.

+
<ul class="tree-nav">
+  {% set root = site.get('/') %}
+  {% for child in root.children recursive %}
+    <li{% if this._path == child._path %} class="active"{% endif
+        %}><a href="{{ child|url }}">{{ child.title }}</a>
+      {% if this.is_child_of(child) %}
+      <ul>{{ loop(child.children) }}</ul>
+      {% endif %}
+    </li>
+  {% endfor %}
+</ul>
+
+

This above template recursively renders out a part of the tree based +navigation around the current active page. For a concrete example for this: +this is how the navigation of this documentation is rendered.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/templates/urls/index.html b/docs/templates/urls/index.html new file mode 100644 index 00000000..333744c0 --- /dev/null +++ b/docs/templates/urls/index.html @@ -0,0 +1,284 @@ + + + + + + + + + + URLs and Links | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

URLs and Links

+ + + +
    + + + +
+ +

Linking to other pages in templates is achieved through the |url and +|asseturl filters. These two filters will ensure that the links that are +generated are automatically relative to the current page so they will work +correctly anywhere you host the page. They also deal with URL paths +that have been changed through configuration.

+

url Filter

The url filter is the most useful +filter for URL generation and it comes in two flavors. It takes one optional +argument which is the alt if it should differ from the current one (see +Alternatives). The filter can be applied to either +a string or a Record object.

+

Basic Navigation

This is an example of how to just link to some specific pages that exist. +Because the path starts with a slash it will be treated as absolute path:

+
<ul class="nav">
+  <li><a href="{{ '/'|url }}">Index</a></li>
+  <li><a href="{{ '/about'|url }}">About</a></li>
+</ul>
+
+

Relative Linking

If you want to link relative to the current page, just leave out the +slash:

+
<a href="{{ 'project-a'|url }}">Go To Project A</a>
+
+

If you want to link to a page in a different alternative you can use the +optional alt parameter. For instance you can link to the current page +in another alternative (. indicates the current page):

+
<a href="{{ '.'|url(alt='ru') }}">Русский</a>
+
+

Because the URL filter can also accept entire record objects you can easily +link to all children of a page:

+
<ul class="nav">
+{% for page in this.children %}
+  <li><a href="{{ page|url }}">{{ page.title }}</a></li>
+{% endfor %}
+</ul>
+
+

asseturl Filter

A second filter that is available is the asseturl filter. It works similar to +|url but can only link to assets from the assets/ folder. However unlike +|url it will append a dummy query string with a hash of the source asset. +This ensures that when the asset changes it will be newly cached.

+

Example:

+
<link rel="stylesheet" href="{{ '/static/styles.css'|asseturl }}">
+
+

The end result will look something like this:

+
<link rel="stylesheet" href="static/styles.css?h=deadbeef">
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/templates/videoops/index.html b/docs/templates/videoops/index.html new file mode 100644 index 00000000..c0ccfa4c --- /dev/null +++ b/docs/templates/videoops/index.html @@ -0,0 +1,308 @@ + + + + + + + + + + Video Operations | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

Video Operations

+ + + +
    + + + +
  • New in Lektor Version 3.2
  • + +
+ +

Just like images, videos are separate files that are embedded into HTML files. Since they are media files, it's often desirable to read metadata or manipulate them in some way.

+

Video metadata access is powered by FFmpeg. In order to use it FFmpeg must be installed on your system and detected by Lektor. If Lektor is unable to find FFmpeg you will see the error message Unable to locate ffmpeg or ffprobe executable. Is it installed? in your console output if you try to use functionality that requires it.

Accessing videos

{% for video in this.attachments.videos %}
+  <div class="video"><video src="{{ video|url }}"></div>
+{% endfor %}
+
+

Just like images you can also access them using site.get('/myfolder').attachments.videos or site.get('/myfolder').attachments.get('examplevideo.mp4'). Note that not all formats are detected as videos (see attachments). If your format is not in the list you may still be able to get it detected as a video by adding it to your Lektor project file.

+

Accessing metadata

Video objects are sub-classes of Attachments but with a few extra properties.

+ + + + + + + + + + + + + + + + + + + + +
AttributeDescription
widthVideo height in pixels
heightVideo height in pixels
durationVideo length as a datetime.timedelta instance
+

Example:

+
{% set video = this.attachments.videos.first() %}
+<video src="{{ video|url }}">
+<dl>
+  <dt>Width:</dt>
+  <dd>{{ video.width }} px</dd>
+  <dt>Height:</dt>
+  <dd>{{ video.height }} px</dd>
+  <dt>Duration:</dt>
+  <dd>{{ video.duration.total_seconds() }} s</dd>
+</dl>
+
+

Generating thumbnails

The main difference between video and image attachments is how thumbnails are handled. Since a video basically is a long sequence of images you must first choose where in the video the thumbnail should be generated. This is done using the `.frame() method. There are multiple ways of calling it:

+ + + + + + + + + + + + + + + + + + + + +
MethodDescription
frame()Use a frame from the middle of the video (default)
frame(seek: float)Fraction between 0.0 and 1.0 of the video duration from where to extract the frame. The value 0.5 means that the middle of the video will be used. It can be seen as a shorthand for video.frame(video.duration * seek).
frame(seek: datetime.timedelta)Use a frame at the given seek distance from the beginning of the video. This is useful when you want to seek a fix time into a video.
+

Calling this method will return a VideoFrame instance, which is not usable by itself. It does however just like an image have a thumbnail method.

+

Example:

+
{% set video = this.attachments.videos.first() %}
+<img src="{{ video.frame().thumbnail(300, 200, mode="crop")|url }}">
+<img src="{{ video.frame(0.1).thumbnail(300, 200, mode="crop")|url }}">
+
+

Note that unlike images it is not possible to get an URL to a video frame directly:

+
{% set video = this.attachments.videos.first() %}
+<img src="{{ video.frame()|url }}"> <!-- This is not valid -->
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/themes/creating/index.html b/docs/themes/creating/index.html new file mode 100644 index 00000000..18a9db8f --- /dev/null +++ b/docs/themes/creating/index.html @@ -0,0 +1,301 @@ + + + + + + + + + + Creating a Theme | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

Creating a Theme

+ + + +
    + + + +
+ +

Not implemented yet.

You could create a basic empty theme with the following command:

+
$ lektor dev new-theme
+
+

Theme Components:

A theme could provide templates, assets, and models (also flowblocks):

+
demo-theme
+├── assets
+├── models
+├── templates
+└── flowblocks
+
+

The theme_settings Variable

A theme_settings section in .lektorproject file could be used to +parametrize themes:

+
[theme_settings]
+name = "Lektor"
+github_url = "https://github.com/lektor"
+
+

And those settings will be accessed in templates through the config env +variable:

+
{{ config.theme_settings.<variable_name> }}
+
+

Example:

+
<a href="{{ config.theme_settings.github_url }}">Github</a>
+
+

will output:

+
<a href="https://github.com/lektor/lektor">Github</a>
+
+

The theme.ini File

Themes could provide a theme.ini file, that is optional, but it's required if +you want to add your theme to the lektor community themes.

+

Example:

+
[theme]
+name = Demo theme
+license = MIT
+licenselink = https://github.com/lektor/lektor-demo-theme/blob/master/LICENSE.md
+description = Simple, minimal theme for Lektor
+homepage = https://github.com/lektor/lektor-demo-theme
+tags = simple, minimal, demo
+features = blog
+lektor_minimum_required_version = 3.1
+
+[author]
+name = lektor
+homepage = http://getlektor.com/
+
+[original]
+author =
+homepage =
+repo =
+
+[packages]
+lektor-disqus-comments = 0.2
+
+

The [original] section is only required if you are porting an existing theme.

+

Not implemented yet

The lektor_minimum_required_version is used by Lektor to check the +compatibility when installing a theme.

+

Releasing a Theme

Not implemented yet

You could add a theme to Lektor community theme, open a pull request against +lektor themes adding it as a git +submodule.

+

You should also include an images/ folder with a screenshot and a thumbnail:

+
demo-theme
+└──  images
+    ├── thumbnail.png
+    └── screenshot.png
+
+

Themes added to this lektor-themes repository, will automatically be added to the +lektor website.

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/themes/customizing/index.html b/docs/themes/customizing/index.html new file mode 100644 index 00000000..19a5e1ef --- /dev/null +++ b/docs/themes/customizing/index.html @@ -0,0 +1,228 @@ + + + + + + + + + + Customizing a Theme | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

Customizing a Theme

+ + + +
    + + + +
+ +

You could personalize a theme by overriding files, for example if a theme +provides a blog model in:

+
/themes/<theme>/models/blog.ini
+
+

You could override it by creating a blog model:

+
/models/blog.ini
+
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/themes/index.html b/docs/themes/index.html new file mode 100644 index 00000000..d9f06204 --- /dev/null +++ b/docs/themes/index.html @@ -0,0 +1,283 @@ + + + + + + + + + + Themes | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

Themes

+ + + +
    + + + +
+ +

Lektor theme support is new. It should be considered +unstable and could change in the future.

New in Lektor Version 3.1: Themes did not exist in earlier Lektor versions.

Lektor provides a themes system to easily implement, reuse, and distribute themes. +This allows you to use assets, templates, models, and / or flowblocks built into the theme. +Themes are created by the Lektor community.

+

Lektor themes work like an extension of the project, allowing you to easily adopt features of the theme such as styles, models, or templates. In all, themes can provide:

+
    +
  • templates
  • +
  • models
  • +
  • flowblocks
  • +
  • assets
  • +
+

Themes can provide all of these as defaults which can be overridden or extended by your project. For instance, if a theme provides a root page.html template, you can create other templates that {% extends "page.html" %}, or you could override the theme's page.html by providing your own in your project's normal templates/ directory.

+ + + + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/themes/installing/index.html b/docs/themes/installing/index.html new file mode 100644 index 00000000..25a73732 --- /dev/null +++ b/docs/themes/installing/index.html @@ -0,0 +1,273 @@ + + + + + + + + + + Installing a Theme | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+

This Page

+ +
+ +
+ +
+ + +

Installing a Theme

+ + + +
    + + + +
+ +

For installing a theme you just need to copy it to the themes/ folder. Create the themes/ folder if it does not already exist.

+
project
+├── assets
+├── models
+├── content
+...
+└── themes
+    └── lektor-theme-nix
+
+

Themes are normally distributed by public Git repositories, so you could install a theme by +cloning the repo:

+
cd themes
+git clone URL_TO_THEME_REPO
+
+

For example, for installing lektor-theme-nix:

+
cd themes
+git clone https://github.com/rlaverde/lektor-theme-nix.git
+
+

If you download several themes, setting themes variable will allow you to only load +a particular theme.

+

Not implemented yet.

You could add the themes variable to the .lektorproject file and Lektor will +search in the community themes and automatically install it.

+
[project]
+themes = lektor-theme-nix
+
+

Installing Multiple Themes

Lektor also supports installing several themes. Copy them to the themes/ +folder, and set the themes variable to indicate the precedence (optional).

+
project
+├── assets
+├── models
+├── content
+...
+└── themes
+    ├── lektor-theme-other-theme/
+    └── lektor-theme-nix/
+
+
[project]
+themes = lektor-theme-nix, lektor-theme-other-theme
+
+

This will make lektor-theme-nix, because it's listed first, have a higher precedence. +Files present in multiple themes will be loaded from right to left, so that the first (left-most) +theme is preferred over the theme(s) to its right.

+

If you don't set the themes variable, all themes will be loaded, but the order +isn't preserved.

+ + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/themes/packages/index.html b/docs/themes/packages/index.html new file mode 100644 index 00000000..2e24c80a --- /dev/null +++ b/docs/themes/packages/index.html @@ -0,0 +1,234 @@ + + + + + + + + + + Installing Plugins with a Theme. | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + +
+ +
+ + +

Installing Plugins with a Theme.

+ + + +
    + + + +
+ +

Not implemented yet.

Themes could depend on plugins, and they will be loaded along +the theme.

+
    +
  1. You could use the [packages] section of the theme.ini to install +released packages:

    +
    [packages]
    +lektor-disqus-comments = 0.2
    +
    +
  2. +
  3. Plugins can be added to the packages/ folder in the theme. Each plugin has +to go into a separate folder.

    +
  4. +
+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/what/admin.png b/docs/what/admin.png new file mode 100644 index 00000000..80b4d73b Binary files /dev/null and b/docs/what/admin.png differ diff --git a/docs/what/git.png b/docs/what/git.png new file mode 100644 index 00000000..bba89057 Binary files /dev/null and b/docs/what/git.png differ diff --git a/docs/what/index.html b/docs/what/index.html new file mode 100644 index 00000000..b2cc0877 --- /dev/null +++ b/docs/what/index.html @@ -0,0 +1,271 @@ + + + + + + + + + + What is Lektor | Documentation | Lektor Static Content Management System + + + + +
+ +
+ +
+
+ + + + + +
+ +
+ + +

What is Lektor

+ + + +
    + + + +
+ +

When it comes to creating websites, there is a ludicrous number of tools available. +They range from full-blown content management solutions like Drupal to +desktop solutions like Google Web Designer to Cloud Hosted Website solutions +like WIX to more programmer focused approaches like Jekyll which generate +websites out of templates and markdown files.

+

Lektor is different from any of these.

+

Lektor is Static

Lektor learned from the huge range of static file generators like Jekyll, +Pelican, Hugo, Middleman and many more about the value of generating a +completely static website. This means that unlike WordPress or similar +solutions it does not run on a server, but your local computer (or a build +server), and generates static HTML that can be uploaded to any web server or +content distribution platform like S3 with CloudFront.

+

Why go static? Because the vast, vast majority of websites will be read many +more times than they will be updated. This is crucial because dynamic content +does not come for free. It needs server resources and because program code is +running there it needs to be kept up to date for to ensure there are no security +problems that are left unpatched. Also when a website gets a sudden spike of +traffic a static website will stay up for longer on the same server than a +dynamic one that needs to execute code.

+

Sure, there are some things you cannot do on a static website, but those are not +things you would use Lektor for. For small dynamic sections, JavaScript +paired up with other services is a good solution.

+

+

Lektor is a CMS

Lektor takes from content management systems like WordPress and provides a +flexible browser-based admin interface from which you can edit your website's +contents. Unlike traditional CMS solutions, however, it runs entirely on your +own computer.

+

This means you can give a Lektor website to people that have no understanding +of programming and they can still modify the content and update the website.

+

+

Lektor is a Framework

Lastly, Lektor learns from experience in writing web frameworks. Lektor +is much more than a website generator because it is based on a very flexible +internal flat file database which can be used to model any website content. +Unlike static blog generators which are based on some markdown content and +“front matter” metadata Lektor's content is 100% configurable.

+

If you have ever used a web framework like Django or Ruby on Rails you might +feel right at home in how you can model and query your data.

+

+

Collaborate and Synchronize

Lektor acknowledges that there are web developers and content editors and that +their interests and preferences are very different. This is reflected heavily +in the design of Lektor and if you make your first Lektor project you can see +why. A web developer would go in and setup the theme and structure of a +Lektor project and content creators can then fill in the content of the site.

+

The collaboration can be based on version control systems like git or just +basic solutions like Dropbox. It's intentionally built so that collaboration +can work via the most basic systems like Dropbox or just network shares.

+

When you go live, you can synchronize up your changes into a remote server +just as easily.

+

+ + + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+ +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/docs/what/static.png b/docs/what/static.png new file mode 100644 index 00000000..76f09dc2 Binary files /dev/null and b/docs/what/static.png differ diff --git a/docs/what/templates.png b/docs/what/templates.png new file mode 100644 index 00000000..35e748d4 Binary files /dev/null and b/docs/what/templates.png differ diff --git a/downloads/header.jpg b/downloads/header.jpg new file mode 100644 index 00000000..7473911f Binary files /dev/null and b/downloads/header.jpg differ diff --git a/downloads/index.html b/downloads/index.html new file mode 100644 index 00000000..da7685c6 --- /dev/null +++ b/downloads/index.html @@ -0,0 +1,159 @@ + + + + + + + + + + Downloads | Lektor Static Content Management System + + + + +
+ + + + + + +
+ +
+
+
+ +

Downloads

+ +
+
+
+ + + + + +
+
+
+
+

Lektor is an Open Source Project and freely available to +download. It's currently still under heavy development and not all platforms +are equally well supported.

+

Command Line Interface

If you are on Linux or Mac you can install the command line version of +Lektor by copy/pasting a command into your terminal.

+

Scared about copy/pasting this into a terminal? We will not do anything +before asking you for confirmation and you can download the script +upfront to see what it's doing.

Mac/Linux

This will install Lektor in your HOME. Running it with sudo will result in +a system installation instead.

+
curl -sf https://www.getlektor.com/installer.py | python3
+
+

You might need additional dependencies for this installation. For more +information see Installation.

+

Windows

If you are on Windows copy/paste this command into Powershell:

+
(new-object net.webclient).DownloadString('https://www.getlektor.com/installer.py') | python
+
+

or alternatively use this in command prompt:

+
@powershell -NoProfile -Command "(new-object net.webclient).DownloadString('https://www.getlektor.com/installer.py') | python"
+
+

Desktop Application

Lektor supported an installable version of Lektor on OSX. The current build process for these installers is old and in need of refactoring. Temporarily until this is resolved, as of version 3.1, this installer is no longer supported.

+ +
+
+
+
+ + + + + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/edit-post.png b/edit-post.png new file mode 100644 index 00000000..d92532fb Binary files /dev/null and b/edit-post.png differ diff --git a/filesystem.png b/filesystem.png new file mode 100644 index 00000000..3219ca08 Binary files /dev/null and b/filesystem.png differ diff --git a/header.jpg b/header.jpg new file mode 100644 index 00000000..482516a6 Binary files /dev/null and b/header.jpg differ diff --git a/index.html b/index.html new file mode 100644 index 00000000..4d58832a --- /dev/null +++ b/index.html @@ -0,0 +1,305 @@ + + + + + + + + + + Welcome | Lektor Static Content Management System + + + + +
+ + + + + + +
+
+
+
+ +

+ A flexible and powerful static content management system for building + complex and beautiful websites out of flat files — for people who do + not want to make a compromise between a CMS and a static blog engine. +

+ Getting your ideas implemented is as easy as frying an egg. +

+ +
+
+
curl -sf https://www.getlektor.com/installer.py | sudo python3
+
+
+
+ + + + + +
+
+
+
+
+ +
+
+
+
+
+ + + + + +
+
+
+
+

Full of Features

    +
  • Deploy Anywhere Because Lektor +builds out 100% static HTML you can deploy them to any host (including S3, +GitHub Pages, any web host, etc.).
  • +
  • Cross Platform It runs on +Linux, OSX and Windows.
  • +
  • 100% File Based All +source data is well structured and can be tracked in a version control +system or cloud storage like Dropbox.
  • +
  • Flat-File Database All +source data is stored in a flat-file tree database and can be freely +queried. The layout of that data is completely configurable.
  • +
  • Customizable Admin Lektor +comes fully equipped with a flexible and beautiful admin interface so you can +edit your pages without having to touch the raw sources.
  • +
  • Dependency Tracking +The build process intelligently tracks page dependencies such that it only +rebuilds pages that have changed.
  • +
  • Image Tools Create +thumbnails and give convenient access to EXIF data.
  • +
  • Plugin System Lektor +supports loading plugins that can customize a wide range of functionality.
  • +
  • Python API The build +system is written in Python and provides a documented API to extend it and +integrate into other apps.
  • +
  • Multilingual We can +speak multiple languages and allow you to easily create localized websites.
  • +
+ +
+
+
+
+ + + + + +
+
+
+ +
+
+
+ + + + + +
+
+
+
+

Open Source

Lektor at its core is a three clause BSD licensed Open Source +project written in Python and Node.js.

+ +
+
+
+
+ + + + + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/installer.py b/installer.py new file mode 100644 index 00000000..541281b0 --- /dev/null +++ b/installer.py @@ -0,0 +1,393 @@ +#!/usr/bin/env python + +from __future__ import print_function +import math +import os +import shutil +import sys +import tempfile +from subprocess import call + +try: + from shutil import which +except ImportError: + from distutils.spawn import find_executable as which + +try: + from urllib.request import urlretrieve +except ImportError: + from urllib import urlretrieve + +IS_WIN = sys.platform == "win32" + +if IS_WIN: + try: + import winreg + except ImportError: + import _winreg as winreg + from ctypes import windll, wintypes + + +VIRTUALENV_URL = "https://bootstrap.pypa.io/virtualenv.pyz" + +# this difference is for backwards-compatibility with the previous installer +APP_NAME = "lektor" if not IS_WIN else "lektor-cli" + +# where to search for a writable bin directory on *nix. +# this order makes sure we try a system install first. +POSIX_BIN_DIRS = [ + "/usr/local/bin", "/opt/local/bin", + "{home}/.bin", "{home}/.local/bin", +] + +SILENT = ( + os.environ.get("LEKTOR_SILENT", "").lower() + not in ("", "0", "off", "false") +) + +if not os.isatty(sys.stdin.fileno()): + # the script is being piped, we need to reset stdin + sys.stdin = open("CON:" if IS_WIN else "/dev/tty") + +if sys.version_info.major == 2: + input = raw_input + + +def get_confirmation(): + if SILENT: + return + + while True: + user_input = input("Continue? [Yn] ").lower().strip() + + if user_input in ("", "y"): + print() + return + + if user_input == "n": + print() + print("Aborted!") + sys.exit() + + +def fail(message): + print("Error: %s" % message, file=sys.stderr) + sys.exit(1) + + +def multiprint(*lines, **kwargs): + for line in lines: + print(line, **kwargs) + + +def rm_recursive(*paths): + def _error(path): + multiprint( + "Problem deleting {}".format(path), + "Please try and delete {} manually".format(path), + "Aborted!", + file=sys.stderr, + ) + sys.exit(1) + + def _rm(path): + if os.path.isdir(path): + shutil.rmtree(path) + else: + os.remove(path) + + for path in paths: + if not os.path.lexists(path): + continue + try: + _rm(path) + except: + _error(path) + + +class Progress(object): + "A context manager to be used as a urlretrieve reporthook." + + def __init__(self): + self.started = False + + def progress(self, count, bsize, total): + size = count * bsize + + if size > total: + progress = 100 + else: + progress = math.floor(100 * size / total) + + out = sys.stdout + if self.started: + out.write("\b" * 4) + + out.write("{:3d}%".format(progress)) + out.flush() + + self.started = True + + def finish(self): + sys.stdout.write("\n") + + def __enter__(self): + return self.progress + + def __exit__(self, exc_type, exc_value, traceback): + self.finish() + + +class FetchTemp(object): + """ + Fetches the given URL into a temporary file. + To be used as a context manager. + """ + + def __init__(self, url): + self.url = url + + fname = os.path.basename(url) + root, ext = os.path.splitext(fname) + self.filename = tempfile.mktemp(prefix=root + "-", suffix=ext) + + def fetch(self): + with self.Progress() as hook: + urlretrieve(self.url, self.filename, reporthook=hook) + + def cleanup(self): + os.remove(self.filename) + + def __enter__(self): + self.fetch() + + return self.filename + + def __exit__(self, exc_type, exc_value, traceback): + self.cleanup() + + +def create_virtualenv(target_dir): + """ + Tries to create a virtualenv by using the built-in `venv` module, + or using the `virtualenv` executable if present, or falling back + to downloading the official zipapp. + """ + + def use_venv(): + try: + import venv + except ImportError: + return + + # on Debian and Ubuntu systems Python is missing `ensurepip`, + # prompting the user to install `python3-venv` instead. + # + # we could handle this, but we'll just let the command fail + # and have the users install the package themselves. + + return call([sys.executable, "-m", "venv", target_dir]) + + def use_virtualenv(): + venv_exec = which("virtualenv") + if not venv_exec: + return + + return call([venv_exec, "-p", sys.executable, target_dir]) + + def use_zipapp(): + print("Downloading virtualenv: ", end="") + with FetchTemp(VIRTUALENV_URL) as zipapp: + return call([sys.executable, zipapp, target_dir]) + + print("Installing virtual environment...") + for func in use_venv, use_virtualenv, use_zipapp: + retval = func() + if retval is None: + # command did not run + continue + if retval == 0: + # command successful + return + # else... + sys.exit(1) + + +def get_pip(lib_dir): + return ( + os.path.join(lib_dir, "Scripts", "pip.exe") if IS_WIN + else os.path.join(lib_dir, "bin", "pip") + ) + + +def install_lektor(lib_dir): + create_virtualenv(lib_dir) + + pip = get_pip(lib_dir) + + args = [pip, "install"] + if IS_WIN: + # avoid fail due to PEP 517 on windows + args.append("--prefer-binary") + args.extend(["--upgrade", "Lektor"]) + + return call(args) + + +def posix_find_bin_dir(): + home = os.environ["HOME"] + preferred = [d.format(home=home) for d in POSIX_BIN_DIRS] + + # look for writable directories in the user's $PATH + # (that are not sbin) + dirs = [ + item + for item in os.environ["PATH"].split(":") + if not item.endswith("/sbin") and os.access(item, os.W_OK) + ] + + if not dirs: + fail( + "None of the items in $PATH are writable. Run with " + "sudo or add a $PATH item that you have access to." + ) + + # ... and prioritize them according to our preferences + def _sorter(path): + try: + return preferred.index(path) + except ValueError: + return float("inf") + + dirs.sort(key=_sorter) + return dirs[0] + + +def posix_find_lib_dir(bin_dir): + # the chosen lib_dir depends on the bin_dir found: + home = os.environ["HOME"] + + if bin_dir.startswith(home): + # this is a local install + return os.path.join(home, ".local", "lib", APP_NAME) + + # else, it's a system install + parent = os.path.dirname(bin_dir) + return os.path.join(parent, "lib", APP_NAME) + + +def windows_create_link(lib_dir, target_dir): + exe = os.path.join(lib_dir, "Scripts", "lektor.exe") + link = os.path.join(target_dir, "lektor.cmd") + + with open(link, "w") as link_file: + link_file.write("@echo off\n") + link_file.write('"{}" %*'.format(exe)) + + +def windows_add_to_path(location): + HWND_BROADCAST = 0xFFFF + WM_SETTINGCHANGE = 0x1A + + key = winreg.OpenKey( + winreg.HKEY_CURRENT_USER, "Environment", 0, winreg.KEY_ALL_ACCESS + ) + + try: + value, _ = winreg.QueryValueEx(key, "Path") + except WindowsError: + value = "" + + paths = [path for path in value.split(";") if path != ""] + + if location not in paths: + paths.append(location) + value = ";".join(paths) + winreg.SetValueEx( + key, "Path", 0, winreg.REG_EXPAND_SZ, value + ) + + SendMessage = windll.user32.SendMessageW + SendMessage.argtypes = ( + wintypes.HWND, wintypes.UINT, wintypes.WPARAM, wintypes.LPVOID + ) + SendMessage.restype = wintypes.LPARAM + SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, "Environment") + + # also add the path to the environment, + # so it's available in the current console + os.environ['Path'] += ";%s" % location + + key.Close() + + +def posix_install(): + bin_dir = posix_find_bin_dir() + lib_dir = posix_find_lib_dir(bin_dir) + symlink_path = os.path.join(bin_dir, APP_NAME) + + multiprint( + "Installing at:", + " bin: %s" % bin_dir, + " app: %s" % lib_dir, + "", + ) + + if os.path.exists(lib_dir) or os.path.lexists(symlink_path): + multiprint( + "An existing installation was detected. This will be removed!", + "", + ) + + get_confirmation() + rm_recursive(lib_dir, symlink_path) + install_lektor(lib_dir) + + os.symlink(os.path.join(lib_dir, "bin", "lektor"), symlink_path) + + +def windows_install(): + install_dir = os.path.join(os.environ["LocalAppData"], APP_NAME) + lib_dir = os.path.join(install_dir, "lib") + + multiprint( + "Installing at:", + " %s" % install_dir, + "", + ) + + if os.path.exists(install_dir): + multiprint( + "An existing installation was detected. This will be removed!", + "", + ) + + get_confirmation() + rm_recursive(install_dir) + install_lektor(lib_dir) + + windows_create_link(lib_dir, install_dir) + windows_add_to_path(install_dir) + + +def install(): + multiprint( + "", + "Welcome to Lektor", + "This script will install Lektor on your computer.", + "", + ) + + if IS_WIN: + windows_install() + else: + posix_install() + + multiprint( + "", + "All done!", + ) + + +if __name__ == "__main__": + install() diff --git a/license/header.jpg b/license/header.jpg new file mode 100644 index 00000000..53c687e9 Binary files /dev/null and b/license/header.jpg differ diff --git a/license/index.html b/license/index.html new file mode 100644 index 00000000..c005353b --- /dev/null +++ b/license/index.html @@ -0,0 +1,197 @@ + + + + + + + + + + License & Copyright | Lektor Static Content Management System + + + + +
+ + + + + + +
+ +
+
+
+ +

License & Copyright

+ +
+
+
+ + + + + +
+
+
+
+

Lektor is a BSD-licensed Open Source project. Independently of that the +text content of the website (including documentation here) is CC0 and +different rules apply for the assets. For more information see below.

+

Lektor License

Copyright (c) 2015 by the Armin Ronacher.

+

Some rights reserved.

+

Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met:

+
    +
  • Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer.

    +
  • +
  • Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following +disclaimer in the documentation and/or other materials provided +with the distribution.

    +
  • +
  • The names of the contributors may not be used to endorse or +promote products derived from this software without specific +prior written permission.

    +
  • +
+

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+

Website License

The text content and templates (excluding images and design) of this website +is licensed under the CC0 license. For information about the license text +see CC0 Legal Text.

+

Note that this does not apply to images and design.

+

Photographs on Website

For the pictures for this website (not including the pictures used in the +documentation or blog posts):

+

Copyright (c) 2016 Christian Cueni +(christiancueni.com). All rights reserved.

+

Lektor Logo License

The Lektor “egg with feet” Logo is available under the “Lektor Logo License”. +You can use the logo to promote Lektor like you want.

+

License details:

+

Copyright (c) 2016 Armin Ronacher

+

Some rights reserved.

+

This logo or a modified version may be used by anyone to refer to the Lektor +project, but does not indicate endorsement by the project.

+

Redistribution and use in source (the SVG files) and binary forms (rendered PNG +files etc.) of the image, with or without modification, are permitted provided +that the following conditions are met:

+
    +
  • Redistributions of source code must retain the above copyright notice and +this list of conditions.
  • +
  • The names of the contributors to the Lektor software (see license) may not be +used to endorse or promote products derived from this software without +specific prior written permission.
  • +
+ +
+
+
+
+ + + + + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/logo.png b/logo.png new file mode 100644 index 00000000..fea6b8ca Binary files /dev/null and b/logo.png differ diff --git a/plugins/categories/build/index.html b/plugins/categories/build/index.html new file mode 100644 index 00000000..df994067 --- /dev/null +++ b/plugins/categories/build/index.html @@ -0,0 +1,264 @@ + + + + + + + + + + Build | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Build

+ + + +
+
+
+ + +
+
+
+ + + + + +
+
+
+
+

These plugins primarily deal with Lektor's build process, adding build tools or processes.

+ +
+
+
+
+ + + + + +
    + + + + + + + +
  • * webpack-support: Super simple Lektor plugin that runs a webpack watcher
  • + + + --- + + + + + + + + + + +
  • git-timestamp: Lektor type to deduce page modification time from git
  • + + + + + + + + +
  • gulp: A simple Lektor plugin for gulp
  • + + + + + + + + +
  • htmlmin: HTML minifier for Lektor. Based on htmlmin.
  • + + + + + + + + +
  • i18n: Use GetText .PO files to translate your site content.
  • + + + + + + + + +
  • limit-dependencies: Lektor plugin to limit dependencies created by queries
  • + + + + + + + + +
  • make: Run make lektor for custom build systems.
  • + + + + + + + + +
  • minify: Minify build artifacts during the Lektor build process
  • + + + + + + + + +
  • npm-support: Adds support for using npm/yarn to build assets in Lektor using tools such as Parcel, webpack, etc.
  • + + + + + + + + +
  • scss: Lektor plugin to compile css out of sass - based on libsass
  • + + + + + + + + +
  • scsscompile: SASS compiler for Lektor, thats based on libsass.
  • + + + + + + + + +
  • webpack-html-helper: Observes the assets directory for html files and copies them into the templates folder.
  • + + +
+ + +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/categories/content/index.html b/plugins/categories/content/index.html new file mode 100644 index 00000000..7f99a899 --- /dev/null +++ b/plugins/categories/content/index.html @@ -0,0 +1,306 @@ + + + + + + + + + + Content | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Content

+ + + +
+
+
+ + +
+
+
+ + + + + +
+
+
+
+

These plugins primarily deal with adding or modifying available content in Lektor, adding content types, or modifying how content behaves.

+ +
+
+
+
+ + + + + +
    + + + + + + + +
  • * markdown-admonition: Adds basic admonition tag support to Markdown.
  • + + + + + + + + + + + +
  • * markdown-header-anchors: Lektor plugin that adds anchors and table of contents to markdown headers.
  • + + + + + + + + + + + +
  • * markdown-highlighter: Lektor plugin that adds syntax highlighting for markdown blocks with Pygments.
  • + + + --- + + + + + + + + + + +
  • asciidoc: Adds AsciiDoc field type to Lektor.
  • + + + + + + + + +
  • asciidoctor: Adds AsciiDoc field type to Lektor.
  • + + + + + + + + +
  • bibtex-support: Bibtex file support to easily include publication lists.
  • + + + + + + + + +
  • citation: This Plugin should extend lektor with APA-styled citations using bibtex files. It was based on the known lektor-bibtex-support plugin by arunpersaud.
  • + + + + + + + + +
  • expression-type: Add jinja-evaluated types to Lektor
  • + + + + + + + + +
  • index-pages: Lektor plugin to generate blog-like index pages
  • + + + + + + + + +
  • jinja-content: Render content fields with Jinja2.
  • + + + + + + + + +
  • nofollow: Easily create nofollow links in Markdown.
  • + + + + + + + + +
  • polymorphic-type: Add polymorphic field type to Lektor
  • + + + + + + + + +
  • pythonmarkdown: Add pythonmarkdownn field type to Lektor to make use of python-markdown as a renderer.
  • + + + + + + + + +
  • read-full-post: Allows blog listing posts to be shortened with a link to the full post.
  • + + + + + + + + +
  • rst: Adds reStructuredText support to Lektor.
  • + + + + + + + + +
  • tags: Lektor plugin to add tags.
  • + + +
+ + +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/categories/deploy/index.html b/plugins/categories/deploy/index.html new file mode 100644 index 00000000..5f46176f --- /dev/null +++ b/plugins/categories/deploy/index.html @@ -0,0 +1,187 @@ + + + + + + + + + + Deploy | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Deploy

+ + + +
+
+
+ + +
+
+
+ + + + + +
+
+
+
+

These plugins primarily deal with Lektor's deployment abilities. They may add a deployment service or location.

+ +
+
+
+
+ + + + + +
    + + + + + + + +
  • netlify: Allows you to publish your lektor website to netlify easily.
  • + + + + + + + + +
  • qiniu: Publish to Qiniu Cloud buckets and refresh the CDN cache.
  • + + + + + + + + +
  • s3: Publish to S3 buckets and Cloudfront.
  • + + + + + + + + +
  • surge: Lektor plugin to publish your site to surge.sh
  • + + +
+ + +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/categories/index.html b/plugins/categories/index.html new file mode 100644 index 00000000..ce573a27 --- /dev/null +++ b/plugins/categories/index.html @@ -0,0 +1,164 @@ + + + + + + + + + + Plugin Categories | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Plugin Categories

+ + + +
+
+
+ + +
+
+
+ + + + + +
+
+
+
+ +
+
+
+
+ + + + + + +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/categories/templates/index.html b/plugins/categories/templates/index.html new file mode 100644 index 00000000..9b40bffa --- /dev/null +++ b/plugins/categories/templates/index.html @@ -0,0 +1,309 @@ + + + + + + + + + + Templates | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Templates

+ + + +
+
+
+ + +
+
+
+ + + + + +
+
+
+
+

These plugins primarily deal with Lektor's Templates. They may add or modify context, api, filters, globals, modify images, change navigation, or many other functionalities available to templates.

+ +
+
+
+
+ + + + + +
    + + + + + + + +
  • * disqus-comments: Embed Disqus comments into your website.
  • + + + --- + + + + + + + + + + +
  • atom: Lektor plugin that generates Atom feeds.
  • + + + + + + + + +
  • creative-commons: Lektor plugin to add Creative Commons license to your pages
  • + + + + + + + + +
  • github-repos: Fetches your GitHub repos for display in Lektor templates
  • + + + + + + + + +
  • google-analytics: Adds support for Google analytics to Lektor CMS
  • + + + + + + + + +
  • google-search: Lektor plugin to add google seach to a website
  • + + + + + + + + +
  • image-resize: Generate JPG and WEBP Images and Thumbnails in predefined sizes.
  • + + + + + + + + +
  • markdown-excerpt: Adds filter for Markdown body excerpt.
  • + + + + + + + + +
  • natural-language: Adds NLTK based template filters.
  • + + + + + + + + +
  • root-relative-path: Root relative path plugin for Lektor
  • + + + + + + + + +
  • shortcodes: Allows you to use shortcodes (something like tags) in your model fields.
  • + + + + + + + + +
  • slugify: Lektor plugin that adds a slugify Jinja filter.
  • + + + + + + + + +
  • strip-html-tags: Strip HTML tags, effectively turning HTML into plain text.
  • + + + + + + + + +
  • tawk: Embed Tawk Live Chat into your website.
  • + + + + + + + + +
  • thumbnail-generator: This plugin automatically generates thumbnails for any images in your Lektor content. The difference between this plugin and the `thumbnail` filter is that this is geared towards content, i.e. you don't need to have any references to the images in your templates at all.
  • + + + + + + + + +
  • webdav: Lektor plugin to get a list of files from a WebDAV server
  • + + + + + + + + +
  • yandex-metrica: Adds support for Yandex Metrica to Lektor CMS
  • + + +
+ + +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/header.jpg b/plugins/header.jpg new file mode 100644 index 00000000..1038d704 Binary files /dev/null and b/plugins/header.jpg differ diff --git a/plugins/index.html b/plugins/index.html new file mode 100644 index 00000000..6991047b --- /dev/null +++ b/plugins/index.html @@ -0,0 +1,654 @@ + + + + + + + + + + Lektor Loves Plugins | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Lektor Loves Plugins

+ + + +
+
+
+ + +
+
+
+ + + + + +
+
+
+
+

Lektor is a young project but it has a growing list of both official and community supported plugins. Official plugins are maintained by Lektor and kept in good shape together with the rest of the project. Community plugins are moderated and updated regularly, but they might not keep pace with development on Lektor. They are maintained by the community. Install them with lektor plugins add NAME.

+

If you want to make or publish your own plugin, or see our docs.

+

(*) Asterisks denote official plugins.

+ +
+
+
+
+ + + + + +

Build

+
+ +
    + + + + + + + +
  • * webpack-support: Super simple Lektor plugin that runs a webpack watcher
  • + + + --- + + + + + + + + + + +
  • git-timestamp: Lektor type to deduce page modification time from git
  • + + + + + + + + +
  • gulp: A simple Lektor plugin for gulp
  • + + + + + + + + +
  • htmlmin: HTML minifier for Lektor. Based on htmlmin.
  • + + + + + + + + +
  • i18n: Use GetText .PO files to translate your site content.
  • + + + + + + + + +
  • limit-dependencies: Lektor plugin to limit dependencies created by queries
  • + + + + + + + + +
  • make: Run make lektor for custom build systems.
  • + + + + + + + + +
  • minify: Minify build artifacts during the Lektor build process
  • + + + + + + + + +
  • npm-support: Adds support for using npm/yarn to build assets in Lektor using tools such as Parcel, webpack, etc.
  • + + + + + + + + +
  • scss: Lektor plugin to compile css out of sass - based on libsass
  • + + + + + + + + +
  • scsscompile: SASS compiler for Lektor, thats based on libsass.
  • + + + + + + + + +
  • webpack-html-helper: Observes the assets directory for html files and copies them into the templates folder.
  • + + +
+ +
+ +

Content

+
+ +
    + + + + + + + +
  • * markdown-admonition: Adds basic admonition tag support to Markdown.
  • + + + + + + + + + + + +
  • * markdown-header-anchors: Lektor plugin that adds anchors and table of contents to markdown headers.
  • + + + + + + + + + + + +
  • * markdown-highlighter: Lektor plugin that adds syntax highlighting for markdown blocks with Pygments.
  • + + + --- + + + + + + + + + + +
  • asciidoc: Adds AsciiDoc field type to Lektor.
  • + + + + + + + + +
  • asciidoctor: Adds AsciiDoc field type to Lektor.
  • + + + + + + + + +
  • bibtex-support: Bibtex file support to easily include publication lists.
  • + + + + + + + + +
  • citation: This Plugin should extend lektor with APA-styled citations using bibtex files. It was based on the known lektor-bibtex-support plugin by arunpersaud.
  • + + + + + + + + +
  • expression-type: Add jinja-evaluated types to Lektor
  • + + + + + + + + +
  • index-pages: Lektor plugin to generate blog-like index pages
  • + + + + + + + + +
  • jinja-content: Render content fields with Jinja2.
  • + + + + + + + + +
  • nofollow: Easily create nofollow links in Markdown.
  • + + + + + + + + +
  • polymorphic-type: Add polymorphic field type to Lektor
  • + + + + + + + + +
  • pythonmarkdown: Add pythonmarkdownn field type to Lektor to make use of python-markdown as a renderer.
  • + + + + + + + + +
  • read-full-post: Allows blog listing posts to be shortened with a link to the full post.
  • + + + + + + + + +
  • rst: Adds reStructuredText support to Lektor.
  • + + + + + + + + +
  • tags: Lektor plugin to add tags.
  • + + +
+ +
+ +

Deploy

+
+ +
    + + + + + + + +
  • netlify: Allows you to publish your lektor website to netlify easily.
  • + + + + + + + + +
  • qiniu: Publish to Qiniu Cloud buckets and refresh the CDN cache.
  • + + + + + + + + +
  • s3: Publish to S3 buckets and Cloudfront.
  • + + + + + + + + +
  • surge: Lektor plugin to publish your site to surge.sh
  • + + +
+ +
+ +

Templates

+
+ +
    + + + + + + + +
  • * disqus-comments: Embed Disqus comments into your website.
  • + + + --- + + + + + + + + + + +
  • atom: Lektor plugin that generates Atom feeds.
  • + + + + + + + + +
  • creative-commons: Lektor plugin to add Creative Commons license to your pages
  • + + + + + + + + +
  • github-repos: Fetches your GitHub repos for display in Lektor templates
  • + + + + + + + + +
  • google-analytics: Adds support for Google analytics to Lektor CMS
  • + + + + + + + + +
  • google-search: Lektor plugin to add google seach to a website
  • + + + + + + + + +
  • image-resize: Generate JPG and WEBP Images and Thumbnails in predefined sizes.
  • + + + + + + + + +
  • markdown-excerpt: Adds filter for Markdown body excerpt.
  • + + + + + + + + +
  • natural-language: Adds NLTK based template filters.
  • + + + + + + + + +
  • root-relative-path: Root relative path plugin for Lektor
  • + + + + + + + + +
  • shortcodes: Allows you to use shortcodes (something like tags) in your model fields.
  • + + + + + + + + +
  • slugify: Lektor plugin that adds a slugify Jinja filter.
  • + + + + + + + + +
  • strip-html-tags: Strip HTML tags, effectively turning HTML into plain text.
  • + + + + + + + + +
  • tawk: Embed Tawk Live Chat into your website.
  • + + + + + + + + +
  • thumbnail-generator: This plugin automatically generates thumbnails for any images in your Lektor content. The difference between this plugin and the `thumbnail` filter is that this is geared towards content, i.e. you don't need to have any references to the images in your templates at all.
  • + + + + + + + + +
  • webdav: Lektor plugin to get a list of files from a WebDAV server
  • + + + + + + + + +
  • yandex-metrica: Adds support for Yandex Metrica to Lektor CMS
  • + + +
+ +
+ + +

Tags

+

+ Plugins are also tagged with keywords and topics. + Their tags are listed on their page and are navigable. + You can view a list of all of the tags here. +

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-asciidoc/index.html b/plugins/lektor-asciidoc/index.html new file mode 100644 index 00000000..4cf1d398 --- /dev/null +++ b/plugins/lektor-asciidoc/index.html @@ -0,0 +1,221 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-asciidoc 0.3

+
+
+ + +
+
+
+

Adds AsciiDoc field type to Lektor.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.3

+

Author: + + A. Jesse Jiryu Davis + +

+ + +
+

Tags

+
+ + + + AsciiDoc, + + + field type, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

Lektor AsciiDoc Plugin

+

A Lektor plugin to add an AsciiDoc field type.

+

Installation

+

Add lektor-asciidoc to your project from command line:

+
lektor plugins add lektor-asciidoc
+
+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-asciidoctor/index.html b/plugins/lektor-asciidoctor/index.html new file mode 100644 index 00000000..b4ad9f65 --- /dev/null +++ b/plugins/lektor-asciidoctor/index.html @@ -0,0 +1,223 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-asciidoctor 0.1

+
+
+ + +
+
+
+

Adds AsciiDoc field type to Lektor.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.1

+

Author: + + Andres Perez C. + +

+ + +
+

Tags

+
+ + + + AsciiDoc, + + + field type, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

Lektor AsciiDoc Plugin

+

A Lektor plugin to add an AsciiDoc field type. This is a fork of the plugin lektor_asciidoc published by @nixjdm.This version, now called lektor asciidoctor requires ruby and asciidoctor which is the origin of the for as agreed in this pull request.

+

Requirements

+

Go to ruby-lang.org and asciidoctor.orgfor installation instructions of both.

+

Installation

+

Add lektor-asciidoc to your project from command line:

+
lektor plugins add lektor-asciidoctor
+
+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-atom/index.html b/plugins/lektor-atom/index.html new file mode 100644 index 00000000..42fb198a --- /dev/null +++ b/plugins/lektor-atom/index.html @@ -0,0 +1,357 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-atom 0.4.0

+
+
+ + +
+
+
+

Lektor plugin that generates Atom feeds.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.4.0

+

Author: + + A. Jesse Jiryu Davis + +

+ + +
+

Tags

+
+ + + + Atom, + + + RSS, + + + setup-env, + + and + virtual paths + + +

View all tags.

+
+ +
+

Project Description

+ +

Lektor Atom Plugin

+

Linux tests +Code Style: Black +Join the chat at https://gitter.im/lektor/lektor

+

Builds one or more Atom XML feeds for your Lektor-based site.

+

Inspired by the atom-feed-support plugin Armin Ronacher wrote for the Lektor official blog.

+

Installation

+

Add lektor-atom to your project from command line:

+
lektor plugins add lektor-atom
+
+

See the Lektor documentation for more instructions on installing plugins.

+

Configuration

+

Here is a basic configuration:

+
[feed]
+name = My Site's Blog
+source_path = /blog
+url_path = /feed.xml
+
+

For each feed you want to publish, add a section to configs/atom.ini. For example, a blog with a feed of all recent posts, and a feed of recent posts about coffee:

+
[blog]
+name = My Blog
+source_path = /
+url_path = /feed.xml
+items = site.query('/').filter(F.type == 'post')
+item_model = blog-post
+
+[coffee]
+name = My Blog: Articles About Coffee
+source_path = /
+url_path = /category/coffee/feed.xml
+items = site.query('/blog').filter(F.categories.contains('coffee'))
+item_model = blog-post
+
+

The section names, like blog and coffee, are just used as internal identifiers.

+

Options

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDefaultDescription
source_path/Where in the content directory to find items' parent source
nameconfig section nameFeed name
filenamefeed.xmlName of generated Atom feed file
url_pathsource_path + filenameFeed's URL on your site
blog_author_fieldauthorName of source's author field
blog_summary_fieldsummaryName of source's summary field
itemssource_path's childrenA query expression: e.g. site.query('/').filter(F.type == 'post')
limit50How many recent items to include
item_title_fieldtitleName of items' title field
item_body_fieldbodyName of items' content body field
item_author_fieldauthorName of items' author field
item_date_fieldpub_dateName of items' publication date field
item_modelNoneFilters items on name of items' model
+

Customizing the plugin for your models

+

Use the field options to tell lektor-atom how to read your items. For example, if your site's model is:

+
[model]
+name = Blog
+
+[fields.writer]
+type = string
+
+[fields.short_description]
+type = string
+
+

Then add to atom.ini:

+
[main]
+blog_author_field = writer
+blog_summary_field = short_description
+
+

See tests/demo-project/configs/atom.ini for a complete example.

+

Filtering items

+

By default, lektor-atom gets the source at source_path and includes all its children in the feed. If you set item_model, lektor-atom includes only the children with that data model.

+

Set items to any query expression to override the default. If items_model is also specified, lektor-atom applies it as a filter to items.

+

Use In Templates

+

You can link to a specific feed in your template. If your atom.ini contains a feed like this:

+
[main]
+source_path = /blog
+
+

Link to the feed in a template like this:

+
{{ '/blog@atom/main'|url }}
+
+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-bibtex-support/index.html b/plugins/lektor-bibtex-support/index.html new file mode 100644 index 00000000..8472ad6c --- /dev/null +++ b/plugins/lektor-bibtex-support/index.html @@ -0,0 +1,262 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-bibtex-support 0.1.1

+
+
+ + +
+
+
+

Bibtex file support to easily include publication lists.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.1.1

+

Author: + + Arun Persaud + +

+ + +
+

Tags

+
+ + + + Jinja globals, + + + LaTeX, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

Lektor Bibtex Plugin

+

The plugin allows adding a list of publications generated from bibtex files to a page.

+

Enabling the plugin

+

To enable the plugin add this to your project file:

+
[packages]
+lektor-bibtex-support = 0.1
+
+

Configuring

+

Create a file configs/bibtex-support.ini with a section called Bibtex. Define a variable files that +is a white space separated list of bibtex files. Put these files into the assets directory of your project.

+
[Bibtex]
+files = A.bib B.bib
+
+

Optionally you can also create a template file that should leave in the template directory to render the bibtex entries. If you skip this entry a default template will be used that sorts the entries by year.

+

Usage

+

You can add the the publication anywhere in your jinja template by calling

+
{{ list_publications(name=name, tag=tag, year=year, labels=labels, fname=fname)|safe }}
+
+

The arguments are optional and can be used for filtering.

+

By name: the name has to show up in the author list to be included

+

by year: only publications from this year

+

labels: white space separated list of bibtex labels (the name of each entry in the bibtex file)

+

fname: white space separated list files to search (by default all files will be searched)

+

Javascript

+

For the default template, you can also add the following javascript to show some entries if you have a long list (relies on jquery):

+
$(document).ready(function()
+	   {
+	      $(".BIBTeX").hide();
+	      $(".BIBTeXtoggle").click( function () {
+		  $(this).parent().children(".BIBTeX").toggle(300);
+		  return false;
+		});
+	      $(".BIBYear").hide();
+	      $(".BIBYear:first").show();
+	      $(".BIBYearheader").click( function () {
+		  $(this).parent().children(".BIBYear").toggle(300);
+		  return false;
+		});
+	      $(".bibshowall").click( function () {
+		  $(".BIBYear").show();
+		});
+	      $(".bibhideall").click( function () {
+		  $(".BIBYear").hide();
+		  $(".BIBYear:first").show();
+		});
+           });
+
+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-citation/index.html b/plugins/lektor-citation/index.html new file mode 100644 index 00000000..b9d7682e --- /dev/null +++ b/plugins/lektor-citation/index.html @@ -0,0 +1,291 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-citation 0.21

+
+
+ + +
+
+
+

This Plugin should extend lektor with APA-styled citations using bibtex files. It was based on the known lektor-bibtex-support plugin by arunpersaud.

+

+
+ + +
+
+

Project links

+ + + + +
+

Meta

+
+

Version: 0.21

+

Author: + + Homer S + +

+ + +
+

Tags

+
+ + + + bibliography, + + + citation, + + + content, + + + Jinja globals, + + + LaTeX, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

lektor-citation

+

An APA-styled citation plugin for the lektor static content management system (https://getlektor.com).

+

Preparations

+

Install the plugin by

+
lektor plugin add lektor-citation
+
+

or by copying this repository into the packages-folder of your lektor-project.

+

Create an citation.ini in its configs-folder:

+
[Bibtex]
+file = Literature.bib
+
+[default]
+priority = url
+link = /for-example/link-to-your/biblioprahy
+
+

And put a Literature.bib BibTex-file into the project's assets-folder respectively.

+

Jinja_env

+

Bibliography

+

To get a formated output of your whole BibTex library you can either

+
    +
  1. Use method citation_short_output in the template of your literature page. It creates an unordered list of entries.
  2. +
+
  <ul id="literatur">
+  {% for entry in citation_entries() %}
+  {{ citation_short_output(entry)|decode|safe }}
+  {% endfor %}
+
+</ul>
+
+
    +
  1. Use method citation_full_output instead. This creates a more complete html-output for every entry.
  2. +
+
  {% for entry in citation_entries() %}
+  {{ citation_full_output(entry)|decode|safe }}
+  {% endfor %}
+
+

produces

+
<h2>{title}</h2><h3>{authors} ({pubYear})</h3>
+<p>{note}</p>
+<dl class="literature">
+<dt class="edition"></dt>
+<dd>{edition}</dd>
+<dt class="editors"></dt>
+<dd>{editors}</dd>
+<dt class="pages"></dt>
+<dd>{pages}</dd>
+<dt class="issbn"></dt>
+<dd>{issbn}</dd>
+<dt class="publisher"></dt>
+<dd>{publisher}</dd>
+</dl>
+
+
    +
  1. You may also use the citation_entry method in combination with pybtex*s Entry-class. For example:
  2. +
+
<ul>
+  {% for entry in citation_entries() %}
+<li>{{ citation_entry(entry).fields['title'] |decode }}</li>
+  {% endfor %}
+  </ul>
+
+

This creates an unordered list of all the titles of your bibtex file. +Of course you can also use citation_entry without a loop and put any id of your bibtex entries into it as parameter.

+

Alternatively to the pybtex methods you can use the following jinja_env globals:

+
citation_authors_short(entry)
+citation_authors_full(entry)
+citation_editors_short(entry)
+citation_editors_full(entry)
+citation_pubYear(entry)
+citation_edition(entry)
+citation_publisher(entry)
+citation_title(entry)
+citation_url(entry)
+citation_issbn(entry)
+citation_pages(entry)
+citation_note(entry)
+
+

In-text Cites

+

To cite a certain entry in your texts you can use the jinja_env globals:

+
citation_full_cite(id, link="")
+citation_full_citeNP(id, link="")
+
+

Both methods create a complete hyperlink inside your text for the entry with id. You may give it any url to the link parameter to e.g. link it to your bibliography page. The NP in the second stands for No Parantheses. So you'll receive e.g.

+
AuthorI & AuthorII (2019)
+
+

or

+
(AuthorI & AuthorII, 2019)
+
+

link parameter

+

Which url is used for your citation's link depends on what you set in the citation.ini file.

+
    +
  • If you set priority in the default section to url the link is set to the value of the url field of the entry.
  • +
  • If there's no value in it the default-link you may set with link in the same section is used.
  • +
  • If you set the link parameter of the function it overwrites the former options.
  • +
+

Thanks to the lektor-jinja-content plugin which is a dependency of this plugin you might also use the globals inside your markdown or html contents, too.

+ + + + +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-creative-commons/index.html b/plugins/lektor-creative-commons/index.html new file mode 100644 index 00000000..5bf6409c --- /dev/null +++ b/plugins/lektor-creative-commons/index.html @@ -0,0 +1,263 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-creative-commons 0.6.0

+
+
+ + +
+
+
+

Lektor plugin to add Creative Commons license to your pages

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.6.0

+

Author: + + Humberto Rocha + +

+ + +
+

Tags

+
+ + + + Creative Commons, + + + i18n, + + + Jinja globals, + + + Licensing, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

Lektor Creative Commons

+

License: MIT +Current version at PyPI +Downloads per month on PyPI

+

Lektor plugin to add Creative Commons license to your pages

+

Usage

+

On your templates use:

+
<div class="license">{{ render_cc_license(type, size, template, caller) }}</div>
+
+
    +
  • type is a string with the license type (e.g.: 'by', 'by-sa', 'by-nc-sa').
  • +
  • size is an optional parameter with the size 'normal' or 'compact'. It defaults to 'normal'.
  • +
  • template is an optional parameter with the template 'full', 'image-only' or 'text-only'. It defaults to 'full'.
  • +
  • locale is an optional parameter that overrides the locale at function calling time.
  • +
  • caller is an optional parameter that you can pass an callable to mount your own template. This argument is usually omitted. See the example of how to use it with the Jinja call feature.
  • +
+

Examples

+

Simply rendering the license of your choice:

+
<div class="license">{{ render_cc_license('by-sa') }}</div>
+
+

Using Jinja2 call block to inject your own template:

+
{% call(license, license_url, icon_path) render_cc_license('by-sa', size='normal') %}
+  <a class="nav-item" rel="license" target="_blank" href="{{ license_url }}">
+    <img alt="{{ license }}" style="border-width:0" src="{{ icon_path }}" />
+  </a>
+{% endcall %} 
+
+

There are more variables, you can check which with

+
{% call() render_cc_license('by-sa', size='normal') %}
+  {{ kwargs }}
+{% endcall %} 
+
+

Notice that using the call block it injects its content as caller parameter to the render_cc_license function that skips the need of choosing a template and renders your own.

+

Internationalization support

+

This plugin has support to internationalization, and changes it language based on .lektorproject file. +The Current supported locales are:

+
    +
  • en
  • +
  • pt_BR
  • +
  • de
  • +
+

Any other locale will default to en (English).

+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-disqus-comments/index.html b/plugins/lektor-disqus-comments/index.html new file mode 100644 index 00000000..ab65da9d --- /dev/null +++ b/plugins/lektor-disqus-comments/index.html @@ -0,0 +1,251 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-disqus-comments 0.4.1

+
+
+ + +
+
+
+

Embed Disqus comments into your website.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.4.1

+

Author: + + Armin Ronacher + +

+ + +
+

Tags

+
+ + + + blog, + + + comments, + + + Disqus, + + + official, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

lektor-disqus-comments

+

This plugin adds support for Disqus comments to Lektor. Once the plugin is +enabled a render_disqus_comments function which can render a disqus comment +box.

+

Enabling the Plugin

+

To enable the plugin add this to your project file:

+
$ lektor plugins add lektor-disqus-comments
+
+

Configuring the Plugin

+

The plugin has a config file that is needed to inform it about your +website. Just create a file named disqus-comments.ini into your +configs/ folder and configure the shortname key with the name of +your disqus community:

+
shortname = YOUR_SHORTNAME
+
+

In Templates

+

Now you can add a discussion box to any of your templates by just using +the render_disqus_comments function. Just calling it is enough to +get the comment box:

+
<div class="comments">{{ render_disqus_comments() }}</div>
+
+

Optionally the function accepts a few arguemnts:

+
    +
  • identifier and url can be used to forcefully override the automatically +detected defaults.
  • +
  • title can be used to set a title for the discussion that overrides +the title that disqus takes from the page's title tag otherwise.
  • +
  • category_id sets the category id. Look at the disqus documentation +for more information.
  • +
+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-expression-type/index.html b/plugins/lektor-expression-type/index.html new file mode 100644 index 00000000..40cabb62 --- /dev/null +++ b/plugins/lektor-expression-type/index.html @@ -0,0 +1,280 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-expression-type 0.1

+
+
+ + +
+
+
+

Add jinja-evaluated types to Lektor

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.1

+

Author: + + Jeff Dairiki + +

+ + +
+

Tags

+
+ + + + field type, + + + Jinja, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

Lektor Expression Type Plugin

+

PyPI version +PyPI Supported Python Versions +GitHub license +GitHub Actions (Tests)

+

Add jinja-evaluated types, expression and format_expression, to +Lektor.

+

These allow one to define data model fields whose values are Jinja2 +expressions.

+

The Types

+

Both the expression and format_expression types are evaluated by +the jinja template engine.

+

expression

+

The expression type is evaluated as a Jinja2 expression.

+

An example value for this type might be:

+
this.children.order_by('-pub_date').limit(4)
+
+

This would evaluate to a Lektor Query instance.

+

format_expression

+

The format_expression type is evaluated as a Jinja2 template. It +will always evaluate to a string.

+

An example value for this type might be:

+
The blog contains {{ site.get('/blog').count() }} pages.
+
+

Installation

+

Add lektor-expression-type to your project from command line:

+
lektor plugins add lektor-expression-type
+
+

See the Lektor plugin documentation for more information.

+

Motivating Example

+

Suppose you want to create an Index data model, for pages which will +be used display lists of other pages on your site. +You could create a model definition like this (called, perhaps, +models/index.ini):

+
[model]
+name = Index Page
+label = Index: {{ this.title}}
+
+[fields.title]
+label = Title
+type = string
+
+[fields.items]
+label = Items
+type = expression
+description = Pages to list on this page
+
+

In a particular index page which uses this model, you might set the +items field to +site.get('/projects').filter(F.tag == 'interesting'), +then in the page template (e.g. in templates/index.html) one could +reference the items field (e.g. {% for page in this.items %}) +to determine which pages to display on the page.

+

Author

+

Jeff Dairiki dairiki@dairiki.org

+

Changelog

+

0.1 — 2021-02-05

+

No code changes.

+

Update development status classifier to "stable".

+

Fixes

+
    +
  • Include the correct LICENSE file.
  • +
+

0.1b1 — 2020-05-05

+

Initial release.

+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-git-timestamp/index.html b/plugins/lektor-git-timestamp/index.html new file mode 100644 index 00000000..1e287750 --- /dev/null +++ b/plugins/lektor-git-timestamp/index.html @@ -0,0 +1,348 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-git-timestamp 0.1.post1

+
+
+ + +
+
+
+

Lektor type to deduce page modification time from git

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.1.post1

+

Author: + + Jeff Dairiki + +

+ + +
+

Tags

+
+ + + + git, + + + metadata, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

Lektor-Git-Timestamp

+

PyPI version +PyPI Supported Python Versions +GitHub license +GitHub Actions (Tests)

+

This Lektor plugin implements a new datetime-like type, +gittimestamp, which gets it's default value from git timestamps. +This can be used to implement auto-updating pub_date and last_mod +fields in Lektor datamodels.

+

Description

+

The gittimestamp type behaves just like the built-in datetime +type, except that if the field is left blank in contents.lr a +default value will be deduced from git timestamps for the file (or +possibly the file’s filesystem mtime.)

+

If an explicit value for the field is not found, the git log for the +source file (typically contents.lr) is searched using git log --follow --remove-empty -- <source_filename>, and the author +timestamp of all matching commits are considered. Additionally, if +the source file is dirty with respect to git’s HEAD, or if the file is +not checked into the git tree, the file’s mtime is prepended to that +list of timestamps. That list of timestamps is filtered based on the +ignore_commits and skip_first_commit options (see below); then, +finally, a timestamp is selected from those that remain based on the +setting of the strategy option.

+

Options

+

The gittimestamp type supports the following options.

+

ignore_commits

+

This can be set to a string, which is interpreted as a regular +expression. Any git commits whose commit message matches this pattern +are ignored when computing a default timestamp value for the field. +(The matching is performed using re.search.)

+

skip_first_commit

+

If this boolean option is set, the first commit in the git log for the +source file will be ignored. This is useful for implementing a +last_mod field which has a defined value only if the source file has +actually been modified since the initial commit.

+

strategy

+

This option determines which timestamp is selected from the git log +(and/or the file mtime). This can be set to one of four values:

+
    +
  • +

    last: If the source file is dirty (with respect to the git HEAD +tree), the mtime of the file is used. Otherwise, the timestamp of +the last (nominally the most recent) non-ignored git commit is +used. This is the default strategy.

    +
  • +
  • +

    first: The timestamp of the first (nominally the earliest) commit +is used.

    +
  • +
  • +

    latest: The latest timestamp is used. Normally this produces the same +result at last, however due to rebasing, cherry-picking, etc. the git timestamps +may not be monotonically increasing, in which case this option causes the +greatest (most recent) timestamp remaining after any filtering to be selected.

    +
  • +
  • +

    earliest: The earliest timestamp is used. Normally this produces the same +result at first, but if the timestamps in the git log are not monotonic, +this will select the minimum of all the timestamps remaining after any filtering.

    +
  • +
+

Examples

+

Here is a simple example excerpt from a datamodel file:

+
<...>
+
+[fields.last_mod]
+label = Time last modified
+type = gittimestamp
+
+

On a page using the above datamodel, so long as the last_mod field +is left blank in the contents.lr file, the page modification time +will be deduced from timestamp of the most recent git commit which +affected that contents.lr. (Or if that file is dirty, the value of +last_mod will be taken from the file’s filesystem mtime.)

+
+

Here is a more complicated example which demonstrates the use of all the options.

+
<...>
+
+[fields.pub_date]
+label = Time first published
+type = gittimestamp
+strategy = first
+
+[fields.last_mod]
+label = Time last modified
+type = gittimestamp
+ignore_commits = \[nochange\]
+skip_first_commit = true
+
+

This will get the default value of the pub_date field from the +timestamp of the first (earliest) git commit for the source file.

+

The default value for last_mod will, as in the previous example, be taken from the +most recent commit for the file, except that:

+
    +
  • any commits whose commit message include the tag [nochange] will be ignored
  • +
  • the first commit (the one whose timestamp is used for pub_date) is ignored
  • +
+

If there has only been one commit of the source file, last_mod will not have +a default value. (It will evaluate to a jinja2 Undefined instance.)

+

Warning: On sorting by gittimestamp in Lektor <= 3.2

+

A common use case for timestamps is for sorting records. +E.g. in a blog one generally wants to display posts in reverse +chronological order by post date. This generally won't work using +gittimestamp timestamps under any currently released version of Lektor.

+

The gittimestamp type is implemented using a field +descriptor. (This is required in order to defer computation of the +field value until after the record for the page is available.) In +lektor<=3.2, field descriptors are supported for most usages, the +one glaring exception being when sorting records.

+

This was fixed in Lektor PR +#789 which was merged to +the master branch on February 6, 2021. +Unfortunately, the last released version of Lektor (as of August 12, +2021) is version 3.2, released August 20, 2020. For now, you'll have +to install Lektor from git if you want to be able to sort records by +gittimestamp.

+

Author

+

Jeff Dairiki dairiki@dairiki.org

+

Changelog

+

Release 0.1.0.post1 (2021-08-12)

+

No code changes.

+

Add warning to README about lektor > 3.2 (not yet released) being +required in order to be able to sort records by gittimestamp fields.

+

Release 0.1 (2021-02-05)

+

No code changes.

+

Update development status classifier to "stable".

+

Add functional tests.

+

Release 0.1a2 (2021-02-03)

+

Bugs Fixed

+

Fixed attrocious typo which prevented the use of anything other than the +default strategy=last for picking timestamps.

+

Release 0.1a1 (2020-06-16)

+

Initial release.

+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-github-repos/index.html b/plugins/lektor-github-repos/index.html new file mode 100644 index 00000000..44dafbcc --- /dev/null +++ b/plugins/lektor-github-repos/index.html @@ -0,0 +1,212 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-github-repos 0.1.1

+
+
+ + +
+
+
+

Fetches your GitHub repos for display in Lektor templates

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.1.1

+

Author: + + Mark Steve Samson + +

+ + +
+

Tags

+
+ + + + GitHub, + + and + process-template-context + + +

View all tags.

+
+ +
+

Project Description

+ + Plugin has no long_description + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-google-analytics/index.html b/plugins/lektor-google-analytics/index.html new file mode 100644 index 00000000..635b2da1 --- /dev/null +++ b/plugins/lektor-google-analytics/index.html @@ -0,0 +1,272 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-google-analytics 0.1.3

+
+
+ + +
+
+
+

Adds support for Google analytics to Lektor CMS

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.1.3

+

Author: + + Khaled Monsoor + +

+ + +
+

Tags

+
+ + + + analytics, + + + Google Analytics, + + + Jinja globals, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

This plugin adds support for Google analytics to Lektor CMS.

+

Once the plugin is enabled, a generate_google_analytics() function +is available to be included in target template which automatically +include Google-Analytics code in final HTML files rendered by +Lektor.

+
+

Basic Usage

+
+

Enabling the Plugin

+

To enable the plugin add this to your project file:

+
[packages]
+lektor-google-analytics = 0.1
+
+
+
+

Configuring the Plugin

+

The plugin needs a config file with your Google analytics code in +it.

+

Just create a file named google-analytics.ini into ./configs +folder in your Lektor project’s base directory. And, put the +GOOGLE_ANALYTICS_ID key with target property ID of form +UA-XXXXXXXX-Y which you obtained from:

+
GOOGLE_ANALYTICS_ID = UA-XXXXXXXX-Y
+
+
+
+

Using in Templates

+

Now you can add a Google analytics code-snippet in your templates by +just calling the generate_google_analytics function inside its <body> </body> tags.

+
<div class="ga-script">{{ generate_google_analytics() }}</div>
+
+

That’s it. All the HTML files that rendered from that template will +include Google-Analytics code automatically.

+
+
+
+

Advanced

+
+
You can use GOOGLE_ANALYTICS_PROPERTY property to include your
+
custom-built Google Analytics tracking code. In that case, your +./configs/google-analytics.ini will look like this:
+
+
GOOGLE_ANALYTICS_ID = UA-XXXXXXXX-Y
+GOOGLE_ANALYTICS_PROPERTY = 'my custom code'
+
+

Don’t use this property unless you know what are you doing. By default, +it is set to auto.

+

To go deeper than this, please refer to Google-Analytics +documentation.

+
+

Copyright (c) 2015, Khaled Monsoor

+

All rights reserved.

+

Licensed under BSD license.

+
+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-google-search/index.html b/plugins/lektor-google-search/index.html new file mode 100644 index 00000000..1575641d --- /dev/null +++ b/plugins/lektor-google-search/index.html @@ -0,0 +1,247 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-google-search 0.1

+
+
+ + +
+
+
+

Lektor plugin to add google seach to a website

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.1

+

Author: + + Lissan Zahid + +

+ + +
+

Tags

+
+ + + + google search, + + + jinja globals, + + + lektor plugin, + + + search, + + + search engine, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

Lektor-Google-Search

+

This plugin add support for Google Search to Lektor CMS

+

Once the plugin is enabled, a render_google_search() function is available to be included in a taget template which autoatically +include Google-Search code in final HTML fles rendered by Lektor.

+

How to Use the plugin ?

+

Enable the plugin

+

To enable the plugin, add the following to your .lektorproject file:

+
[packages]
+lektor-google-search = 0.1
+
+

Configure the plugin

+

The plugin needs a config file with your search Engine ID code in it

+
    +
  • Create a file named google-serch.ini into ./configs folder in your lektor project's base directory.
  • +
  • Put the SEARCH_ENGINE_ID key with the value of your serch engine ID.
  • +
+
SEARCH_ENGINE_ID = 83892839209432084
+
+

Usage in template

+

Add Google Search code snippet by calling the function render_google_search() in the template of your preference where you want the search box to appear.

+
<div>{{ render_googe_search() }}</div>
+
+

Now, try to run lektor server to see the google search appear.

+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-gulp/index.html b/plugins/lektor-gulp/index.html new file mode 100644 index 00000000..b3ca95f8 --- /dev/null +++ b/plugins/lektor-gulp/index.html @@ -0,0 +1,262 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-gulp 0.3.2

+
+
+ + +
+
+
+

A simple Lektor plugin for gulp

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.3.2

+

Author: + + Maurizio Turatti + +

+ + +
+

Tags

+
+ + + + before-build-all, + + + CSS, + + + gulp, + + + HTML, + + + JavaScript, + + + server-spawn, + + and + server-stop + + +

View all tags.

+
+ +
+

Project Description

+ +

This plugin for Lektor CMS adds gulp support to projects. When +enabled with the -f gulp flag it runs npm install and then the +gulp default or watch tasks as they are defined into your own +gulpfile.js.

+

The general documentation about Lektor plugins is here.

+
+

lektor build

+

The command lektor build -f gulp runs the ``default`` gulp task, +for example defined as something like:

+
gulp.task('build', ['clean', 'copy', 'js', 'css', 'imagemin'], () => { });
+gulp.task('default', ['build'], () => { });
+
+

In the above example the default task points to a build task, +which is usually composed by several other gulp tasks, etc.

+
+
+

lektor server

+

The command lektor server -f gulp runs the Lektor embedded server on +http://localhost:5000, starting a gulp ``watch`` task in background. +For example, you can define something such as:

+
gulp.task('watch', () => {
+    gulp.watch('lib/js/**/*.js', ['js']);
+    gulp.watch('lib/css/**/*.css', ['css']);
+});
+
+

In the above example, each time one touches Javascript or CSS files in +the lib/ folder then assets could be minified, concatenated and +copied into the standard assets/static/ lektor folder, or whatever +is defined into your own gulpfile.js.

+
+
+

Credits

+

This plugin is based on the official Webpack plugin with very little +differences.

+
+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-htmlmin/index.html b/plugins/lektor-htmlmin/index.html new file mode 100644 index 00000000..0b9ce4bf --- /dev/null +++ b/plugins/lektor-htmlmin/index.html @@ -0,0 +1,244 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-htmlmin 1.0.3

+
+
+ + +
+
+
+

HTML minifier for Lektor. Based on htmlmin.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 1.0.3

+

Author: + + Jacopo Cascioli + +

+ + +
+

Tags

+
+ + + + after-build-all, + + + HTML, + + + htmlmin, + + and + minify + + +

View all tags.

+
+ +
+

Project Description

+ +

Pypi

+

HTML minifier for Lektor that automatically minifies generated .html files.

+

Uses htmlmin and looks for .html files, +minifying them as part of the build process.

+
+

Installing

+

You can install the plugin with Lektor’s installer:

+
lektor plugins add lektor-htmlmin
+
+

Or by hand, adding the plugin to the packages section in your lektorproject file:

+
[packages]
+lektor-htmlmin = 1.0
+
+
+
+

Usage

+

To enable minification, pass the htmlmin flag when starting the development +server or when running a build:

+
lektor build -O my_build_folder -f htmlmin
+
+

When the flag is present, htmlmin will overwrite all HTML files in the output +directory with their minified counterparts.

+

Note: The htmlmin plugin currently minifies every file in the project after a build. +Not just files that have been changed. This should have no ill effects, but +might increase build times if there are many files to minify.

+
+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-i18n/index.html b/plugins/lektor-i18n/index.html new file mode 100644 index 00000000..c85628f2 --- /dev/null +++ b/plugins/lektor-i18n/index.html @@ -0,0 +1,233 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-i18n 0.4.4

+
+
+ + +
+
+
+

Use GetText .PO files to translate your site content.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.4.4

+

Author: + + NumeriCube + +

+ + +
+

Tags

+
+ + + + after-build, + + + after-build-all, + + + alternatives, + + + Babel, + + + before-build, + + + before-build-all, + + + GetText, + + + i18n, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ + Plugin has no long_description + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-image-resize/index.html b/plugins/lektor-image-resize/index.html new file mode 100644 index 00000000..ff662b10 --- /dev/null +++ b/plugins/lektor-image-resize/index.html @@ -0,0 +1,277 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-image-resize 1.0.0

+
+
+ + +
+
+
+

Generate JPG and WEBP Images and Thumbnails in predefined sizes.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 1.0.0

+

Author: + + L3D + +

+ + +
+

Tags

+
+ + + + images, + + + thumbnails, + + and + webp + + +

View all tags.

+
+ +
+

Project Description

+ +

lektor image resize plugin

+

PyPI version +Downloads +Linting Python package +Upload Python Package +MIT License

+

This plugin generates JPG and WEBP Images and Thumbnails in predefined sizes for any images in your Lektor content. +The difference between this plugin and the lektor thumbnail filter is that this plugin is converting all images and you don't need to have any references to the images in your templates.

+

TL;DR: What does this plugin do?

+
    +
  • It will generate JPEG images in the sizes you configured of all images in your Lektor content using imagemagic.
  • +
  • It will generate WEBP images in the same sizes using imagemagic.
  • +
+

Usage

+

Use this plugin if you want to be able to link to full-size images in your content, but still want thumbnails to be generated for the link itself. +For example, you may have an image called waffle.jpg, and to link to it in the content (not the template), but also show a thumbnail. +All images will be converted to webp using Pillow.

+

You can use the images like that:

+
<!-- Simple example -->
+<a href="waffle.jpg"><img src="waffle-small.jpg" /></a>
+
+<!-- example with srcset -->
+<a href="waffle-small.webp">
+  <img src="waffle-small.webp"
+    srcset="waffle-small.webp  640w,   // Viewport bis zu 640
+            waffle-medium.webp 1280w,  // Viewport größer als 1280
+            waffle-woowee.webp 1920w"  // Viewport größer als 1920
+  />
+</a>
+
+

Installation

+

To install the plugin, add lektor-image-resize to your plugins from the command line and create a config file:

+
# add the plugin to lektor
+lektor plugins add lektor-image-resize
+
+

If you have trouble, see the plugin +installation section of the Lektor +documentation.

+

Create a config file called configs/image-resize.ini and add +a few sections for images. The section names can be whatever you want, the +final images will be called $(imagename)-$(sectionname).jpg and $(imagename)-$(sectionname).webp.

+

Here is a example config file:

+
[small]
+width = 640
+height = 360
+
+[medium]
+height = 720
+
+[woowee]
+width = 1920
+
+

Will take a file called waffle.jpg and create the files waffle-small.jpg, +waffle-medium.jpg and waffle-woowee.jpg as well as waffle-small.webp, +waffle-medium.webp and waffle-woowee.webp All the files will be created, +regardless of whether the original file is smaller, so you can link without worrying +whether a file will exist or not. If the original file is smaller than the width +you have specified, the file will only be copied, and will not be resized.

+

The max_width/max_height parameters work like for the Lektor +thumbnail command.

+

Good to know

+

There is a filter plugin avaliable at lektor-image-filter available, that can help you to use the image in all configured sizes,

+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-index-pages/index.html b/plugins/lektor-index-pages/index.html new file mode 100644 index 00000000..31e3a9d0 --- /dev/null +++ b/plugins/lektor-index-pages/index.html @@ -0,0 +1,323 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-index-pages 1.0.0

+
+
+ + +
+
+
+

Lektor plugin to generate blog-like index pages

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 1.0.0

+

Author: + + Jeff Dairiki + +

+ + +
+

Tags

+
+ + + + before-build, + + + blog, + + + indexing, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

Lektor Index Pages Plugin

+

PyPI version +PyPI Supported Python Versions +GitHub license +Documentation Status +GitHub Actions (Tests)

+

This Lektor plugin can be used to generate “index pages” for a +blog or similar collection of pages. These index pages list the blog posts +segregated by some key, with each index page containing only those posts +which match that key.

+

Examples of what this can be used for include:

+
    +
  • +

    Category Indexes: A set of index pages, one for each category, +which lists all the posts in that category. (Multi-valued index keys +are also supported, so that each post can appear on more than a single +index page: e.g. keyword indexes.)

    +
  • +
  • +

    Date Indexes: A set of index pages, one for each year (say), which +list all the posts in that year. (Sub-indexes are supported +subindexes — e.g., each year index may have as children a sequence +of month indexes.)

    +
  • +
+

Behind the scenes, judicious caching of indexing results, and careful +control of Lektor’s dependency tracking prevent all this from slowing +the build process down too excruciatingly much.

+

Project Links

+ +

Author

+

Jeff Dairiki dairiki@dairiki.org

+

Changelog

+

Release 1.0 (2022-01-28)

+
    +
  • Drop support for python 2.7 and 3.6.
  • +
  • Fix deprecation warning from jinja2. Jinja2 version 3 is now required.
  • +
+

Documentation

+
    +
  • +

    Documentation clarifications, updates and fixes. +(PR #2 — Thank you Bart Van Loon!)

    +
  • +
  • +

    Add missing requirement recommonmark to docs/requirements.txt.

    +
  • +
  • +

    Add docs enviroment to tox.ini to test that docs will build cleanly.

    +
  • +
+

Testing

+
    +
  • Test under python 3.10 and lektor<3.3
  • +
+

Release 0.1 (2021-02-05)

+

No code changes.

+

Update development status classifier to "stable".

+

Release 0.1a3 (2020-05-08)

+

API changes

+
    +
  • +

    Added a key field on the index virtual source object. It is an +alias to _id, but is syntactically more self-explanatory.

    +
  • +
  • +

    The keys configuration key has been renamed to key.

    +
  • +
  • +

    When the key expression is being evaluted, the record whose key(s) +is(are) to be be computed is now available in the jinja context as +item rather than this.

    +
  • +
+

Documentation

+
    +
  • Documentation moved from README to Sphinx docs at RTFD.io
  • +
+

Release 0.1a2 (2020-05-06)

+

API changes

+
    +
  • +

    The record argument has been dropped from the (jinja) global +index_pages function. (Since indexes can not have multiple +parents, it is not necessary.)

    +
  • +
  • +

    The parent configuration key has been renamed to parent_path.

    +
  • +
  • +

    The slug configuration key has been renamed to slug_format.

    +
  • +
  • +

    The attributes config section has been renamed to fields.

    +

    Though they are not quite like regular Lektor Record fields, they +are more field-like than attribute-like. (I.e. access is via +getitem rather than getattr.)

    +
  • +
+

Release 0.1a1 (2020-05-05)

+

Initial release.

+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-jinja-content/index.html b/plugins/lektor-jinja-content/index.html new file mode 100644 index 00000000..53d6a95b --- /dev/null +++ b/plugins/lektor-jinja-content/index.html @@ -0,0 +1,261 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-jinja-content 0.4.3

+
+
+ + +
+
+
+

Render content fields with Jinja2.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.4.3

+

Author: + + Terminal Labs, Joseph Nix + +

+ + +
+

Tags

+
+ + + + content, + + + context, + + + Jinja, + + + Markdown, + + + process-template-context, + + and + templates + + +

View all tags.

+
+ +
+

Project Description

+ +

lektor-jinja-content

+

Build Status +Code Coverage +PyPI version +PyPI - Python Version +Code style: black

+

This is a Lektor plugin that allows you to render Jinja2 inside your content fields that are string-like. For example, this means that inside your content fields that are of type string or Markdown, you can write Jinja logic, and access Lektor's Template Context, and has access to all normal Jinja filters, including those provided by other plugins. In a Markdown field (or other field that is rendered - like rst), the Jinja is processed first, then the formatting processor.

+

You can set and use Jinja variables, but they will only have meaning within their field that is being rendered.

+

With this plugin, you'll have to make sure the content that is rendered is valid Jinja. Jinja syntax erros will throw an exception. Don't forget about the handy {% raw %} {% endraw %} tags if you want content that is not valid Jinja.

+

N.B. Using this plugin is rendering many more items with Jinja, and your build process will slow down as a result. As an early benchmark and anecdote, my small website's build time rose from 4.89s to 5.39s even while I actually had no Jinja-Content that needed rendering. I plan on adding the ability to configure this plugin later so that you don't have to run everything through Jinja if you don't want to.

+

Examples

+

Querying context: {{ site.get('/').title }} or {{ this.path }}

+

Logic:

+
{% set meaning_of_life, meaning_of_universe = this.life, this.universe %}
+{% if meaning_of_life == meaning_of_universe == 42 %}
+  {% set meaning_of_it_all = meaning_of_life %}
+{% else %}
+  {% set meaning_of_it_all = 'Undefined' %}
+{% endif %}
+{{ meaning_of_it_all }}
+
+

Jinja in Markdown:

+
[link text]({{ this|url }})
+
+

Jinja in reStructuredText:

+
`link text <{{ this|url }}>`_
+
+

Try running the test site for more examples.

+

Possible future of this plugin.

+

This Plugin opens the door to some pretty powerful and pretty funky functionality. Here's some food for though:

+ + + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-limit-dependencies/index.html b/plugins/lektor-limit-dependencies/index.html new file mode 100644 index 00000000..8a2cb1b9 --- /dev/null +++ b/plugins/lektor-limit-dependencies/index.html @@ -0,0 +1,296 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-limit-dependencies 0.1

+
+
+ + +
+
+
+

Lektor plugin to limit dependencies created by queries

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.1

+

Author: + + Jeff Dairiki + +

+ + +
+

Tags

+
+ + + + build optimization, + + + Jinja filters, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

Lektor Limit Dependencies

+

PyPI version +PyPI Supported Python Versions +GitHub license +GitHub Actions (Tests)

+

This is an experimental Lektor plugin which aims to provide tools (or, +at least, a tool) to help keep Lektor’s dependency tracking under +control.

+

Introduction

+

Motivating Example

+

Suppose that you would like to list the three most recent blog posts +in the sidebar of your Lektor-based site. This can be done by adding +something like to your site base template:

+
<h3>Recent Posts</h3>
+<ul>
+  {% for post in site.query('/blog').order_by('-pub_date').limit(3) %}
+    <li><a href="{{ post|url }}">{{ post.title }}</a></li>
+  {% endfor %}
+</ul>
+
+

This is not without drawbacks, however. To sort the post query by +date, Lektor iterates through all of the blog’s posts, then sorts +them. In so doing, it records all of the blog posts as dependencies +of every page on which this most-recent-post query is used. If this +is in the sidebar of every page on your site, now every page on your +site will be rebuilt whenever any blog post at all (not just one of +the three most recent posts) is edited.

+

Technically, it is true that all pages now depend on all posts. You +might well edit the pub_date of one of your older posts, such that +it should now appear in the most-recent listing. However, it is not +true that all pages need to be rebuilt for any edit of any post. +Unfortunately, Lektor’s dependency tracking system is not elaborate +enough to be able to express details about how pages are +dependent on other pages; it only records that they are +dependent, so Lektor has no option but to rebuild everything.

+

A Solution?

+

This plugin introduces a Jinja filter, limit_dependencies. It +expects, as input, a Lektor query instance. It iterates through the +input query, and returns a new query instance which will yield the +same results. While it is doing its iteration, it — essentially — +monkey-patches Lektor’s dependency tracking machinery to prevent it +from recording any dependencies.

+

At the end, limit_dependencies records one dependency on a virtual +source object which depends only on the sequence of the identities +of the records in the query result. (Lektor provides a means by which +virtual source objects can report checksums. The +dependency tracking mechanism records those checksums, and will +trigger a rebuild should the checksum change. Limit_dependencies +generates a virtual source object whose checksum depends on the +sequence of identities in the query result.)

+

In the above example, this is exactly what we want. We only want to +trigger a rebuild if the order or composition of the most-recent three +posts changes. (Or if any of their titles change. Note that this +gets covered, too, since when the resulting query is iterated over in +the {% for %} loop, dependencies will be recorded on the three +most-recent posts.)

+

Thus, the example above, if replaced by:

+
<h3>Recent Posts</h3>
+<ul>
+  {% for post in site.query('/blog').order_by('-pub_date').limit(3)|limit_dependencies %}
+    <li><a href="{{ post|url }}">{{ post.title }}</a></li>
+  {% endfor %}
+</ul>
+
+

will work in a much more efficient and sane manner. Pages will be +rebuilt only if there are changes in the order, composition or content +of the three most recent posts.

+

Installation

+

Add lektor-limit-dependencies to your project from command line:

+
lektor plugins add lektor-limit-dependencies
+
+

See the Lektor plugin documentation for more information.

+

Author

+

Jeff Dairiki dairiki@dairiki.org

+

Changelog

+

Release 0.1 (2021-02-05)

+

No code changes.

+

Update development status classifier to "stable".

+

Test under python 3.9. Stop testing under 3.5.

+

Release 0.1a1 (2020-05-19)

+

Initial release.

+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-make/index.html b/plugins/lektor-make/index.html new file mode 100644 index 00000000..30a69090 --- /dev/null +++ b/plugins/lektor-make/index.html @@ -0,0 +1,211 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-make 0.3

+
+
+ + +
+
+
+

Run make lektor for custom build systems.

+

+
+ + +
+
+

Project links

+ + + + +
+

Meta

+
+

Version: 0.3

+

Author: + + Barnaby Shearer + +

+ + +
+

Tags

+
+ + + + before-build-all, + + and + make + + +

View all tags.

+
+ +
+

Project Description

+ + https://readthedocs.org/projects/lektor-make/badge/?version=latest +https://img.shields.io/pypi/v/lektor-make?color=success +

Lektor plugin to run make lektor for custom build systems.

+
+

Install

+
python3 -m pip install lektor-make
+
+
+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-markdown-admonition/index.html b/plugins/lektor-markdown-admonition/index.html new file mode 100644 index 00000000..db8151f5 --- /dev/null +++ b/plugins/lektor-markdown-admonition/index.html @@ -0,0 +1,262 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-markdown-admonition 0.3.1

+
+
+ + +
+
+
+

Adds basic admonition tag support to Markdown.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.3.1

+

Author: + + Armin Ronacher + +

+ + +
+

Tags

+
+ + + + admonition, + + + Markdown, + + + markdown-config, + + and + official + + +

View all tags.

+
+ +
+

Project Description

+ +

lektor-markdown-admonition

+

This plugin adds admonition tags to Markdown for Lektor. This feature is +inspired by the extension in Python Markdown but simplified.

+

Enabling the Plugin

+

To enable the plugin run this command:

+
$ lektor plugins add markdown-admonition
+
+

Syntax

+

A paragraph prefixed with exclamation marks is handled as admonition:

+
! a note
+
+!! an informational message
+
+!!! a tip to users
+
+!!!! a warning
+
+

They are rendered as follows:

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Markdown PrefixRendered div
!<div class="admonition admonition-note">
!!<div class="admonition admonition-info">
!!!<div class="admonition admonition-tip">
!!!!<div class="admonition admonition-warning">
+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-markdown-excerpt/index.html b/plugins/lektor-markdown-excerpt/index.html new file mode 100644 index 00000000..59c6f390 --- /dev/null +++ b/plugins/lektor-markdown-excerpt/index.html @@ -0,0 +1,232 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-markdown-excerpt 0.1

+
+
+ + +
+
+
+

Adds filter for Markdown body excerpt.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.1

+

Author: + + Luka Zakrajsek + +

+ + +
+

Tags

+
+ + + + Jinja filters, + + + Markdown, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

# lektor-markdown-excerpt

+

This plugin adds filter for Markdown body excerpt.

+

## Enabling the Plugin

+

To enable the plugin run this command:

+

`ini +$ lektor plugins add markdown-excerpt +`

+

## In Templates

+

Plugin provides the |excerpt filter that can be used to render first +paragraph of Markdown:

+

`jinja +{{ post.body|excerpt }} +`

+

It takes one optional argument which is the separator for the excerpt:

+

`jinja +{{ post.body|excerpt:'\n\n##' }} +`

+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-markdown-header-anchors/index.html b/plugins/lektor-markdown-header-anchors/index.html new file mode 100644 index 00000000..ea206d1b --- /dev/null +++ b/plugins/lektor-markdown-header-anchors/index.html @@ -0,0 +1,254 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-markdown-header-anchors 0.3.1

+
+
+ + +
+
+
+

Lektor plugin that adds anchors and table of contents to markdown headers.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.3.1

+

Author: + + Armin Ronacher + +

+ + +
+

Tags

+
+ + + + anchors, + + + headers, + + + Markdown, + + + markdown-config, + + + markdown-meta-init, + + + markdown-meta-postprocess, + + + official, + + and + table of contents + + +

View all tags.

+
+ +
+

Project Description

+ +

lektor-markdown-header-anchors

+

This plugin extends the markdown support in Lektor in a way that headlines +are given anchors and a table of contents is collected.

+

Enabling the Plugin

+

To enable the plugin run this command:

+
$ lektor plugins add markdown-header-anchors
+
+

In Templates

+

Within templates it becomes possible to access the .toc property of +markdown data. It's a list where each item has the following attributes:

+
    +
  • anchor: the name of the anchor
  • +
  • title: the title of the headline as HTML
  • +
  • children: a list of headers below that header
  • +
+

Example rendering:

+
<h4>Table Of Contents</h4>
+<ul class="toc">
+{% for item in this.body.toc recursive %}
+  <li><a href="#{{ item.anchor }}">{{ item.title }}</a>{%
+   if item.children %}<ul>{{ loop(item.children) }}</ul>{% endif %}</li>
+{% endfor %}
+</ul>
+
+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-markdown-highlighter/index.html b/plugins/lektor-markdown-highlighter/index.html new file mode 100644 index 00000000..6fa86970 --- /dev/null +++ b/plugins/lektor-markdown-highlighter/index.html @@ -0,0 +1,257 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-markdown-highlighter 0.3.1

+
+
+ + +
+
+
+

Lektor plugin that adds syntax highlighting for markdown blocks with Pygments.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.3.1

+

Author: + + Armin Ronacher + +

+ + +
+

Tags

+
+ + + + Markdown, + + + markdown-config, + + + official, + + + Pygments, + + + setup-env, + + and + syntax highlighting + + +

View all tags.

+
+ +
+

Project Description

+ +

lektor-markdown-highlighter

+

This plugin adds support for syntax highlighting through Pygments to +Lektor's markdown support.

+

Enabling the Plugin

+

To enable the plugin run this command:

+
lektor plugins add markdown-highlighter
+
+

Configuring the Plugin

+

The plugin has a config file that is used to configure a few things +for Pygments. Just create a file named markdown-highlighter.ini into your +configs/ folder. Currently only pygments.style is used:

+
[pygments]
+style = tango
+
+

You can use this to select any of the built-in Pygments styles. Support for +custom styles will come in the future.

+

The config file is considered the "source" for the Pygments stylesheet, so you must create the configuration file (it can be empty) or Lektor's build will prune pygments.css.

+

In Markdown

+

To use the syntax highlighter you need to use fenced blocks and pass the name +of the pygments lexer after the opening fence:

+
```python
+print("Hello World!")
+```
+
+

In Templates

+

In templates the plugin provides the get_pygments_stylesheet function which +can be used to generate and retrieve a link to the pygments stylesheet:

+
<link rel="stylesheet" href="{{ get_pygments_stylesheet()|url }}">
+
+

In addition the |pygmentize filter can be used to highlight code from +templates. It takes one argument which is the lexer name:

+
{{ 'print "Hello World!"'|pygmentize('python') }}
+
+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-minify/index.html b/plugins/lektor-minify/index.html new file mode 100644 index 00000000..62478e76 --- /dev/null +++ b/plugins/lektor-minify/index.html @@ -0,0 +1,232 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-minify 1.2

+
+
+ + +
+
+
+

Minify build artifacts during the Lektor build process

+

+
+ + +
+
+

Project links

+ + + + +
+

Meta

+
+

Version: 1.2

+

Author: + + Pietro Albini + +

+ + +
+

Tags

+
+ + + + after-build, + + + CSS, + + + django-htmlmin, + + + HTML, + + + JavaScript, + + + minify, + + + RCSSmin, + + + rJSmin, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

This plugin allows you to minify the build artifacts of your Lektor project +during the build process, without any additional tool. It currently supports +minifying HTML, CSS and JS files.

+

The plugin only minifies the files changed during the last build, avoiding +slowing down the build if your project consists of a lot of files. Internally +it uses the rcssmin and rjsmin libraries, and it’s released under the MIT +license.

+

Learn more about the plugin

+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-natural-language/index.html b/plugins/lektor-natural-language/index.html new file mode 100644 index 00000000..15f062c7 --- /dev/null +++ b/plugins/lektor-natural-language/index.html @@ -0,0 +1,230 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-natural-language 0.3.1

+
+
+ + +
+
+
+

Adds NLTK based template filters.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.3.1

+

Author: + + Terminal Labs + +

+ + +
+

Tags

+
+ + + + Jinja filters, + + + natural language, + + + NLTK, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

lektor-natural-language

+

This is a Lektor plugin that provides a few simple template filters with the Natural Language ToolKit (nltk).

+

This offers the following filters:

+

sentences_filter

+

Accept a string of text and return a list of its sentences.

+

Usage: {{ this.text|sentences }}

+

firstsentences_filter

+

Accept a string of text and return its the first sentence.

+

Usage: {{ this.text|firstsentence }}

+

sentences_filter

+

Accept a string of text and return a list its keywords as determined by nltk's Rake.

+

Usage: {{ this.text|keywords }}

+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-netlify/index.html b/plugins/lektor-netlify/index.html new file mode 100644 index 00000000..b4bf3ea5 --- /dev/null +++ b/plugins/lektor-netlify/index.html @@ -0,0 +1,246 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-netlify 0.3

+
+
+ + +
+
+
+

Allows you to publish your lektor website to netlify easily.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.3

+

Author: + + A. Jesse Jiryu Davis + +

+ + +
+

Tags

+
+ + + + Netlify, + + + publisher, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

Lektor Netlify Publisher Plugin

+

Publish your Lektor site to Netlify.

+

Installation

+

Install the netlify command-line program according to the instructions on netlify.com.

+

Add lektor-netlify to your project from the command line:

+
lektor plugins add lektor-netlify
+
+

See the Lektor documentation for more instructions on installing plugins.

+

Configuration

+

Configure a server in your .lektorproject file:

+
[servers.production]
+name = Production
+target = netlify://my-domain.com
+
+

Access Token

+

Get a personal access token from Netlify's "applications" page:

+ +

You must use this access token each time you publish. If your project file is private you can save the token there. Do not commit this!

+
[servers.production]
+name = Production
+target = netlify://my-domain.com
+key = ACCESS_TOKEN
+
+

Now deploy your site like:

+
lektor deploy production
+
+

Otherwise, pass the token on the command line:

+
lektor deploy production --key ACCESS_TOKEN    
+
+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-nofollow/index.html b/plugins/lektor-nofollow/index.html new file mode 100644 index 00000000..12243747 --- /dev/null +++ b/plugins/lektor-nofollow/index.html @@ -0,0 +1,215 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-nofollow 0.1

+
+
+ + +
+
+
+

Easily create nofollow links in Markdown.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.1

+

Author: + + Kenji Wellman + +

+ + +
+

Tags

+
+ + + + Markdown, + + + markdown-config, + + and + nofollow links + + +

View all tags.

+
+ +
+

Project Description

+ + Plugin has no long_description + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-npm-support/index.html b/plugins/lektor-npm-support/index.html new file mode 100644 index 00000000..2a44a481 --- /dev/null +++ b/plugins/lektor-npm-support/index.html @@ -0,0 +1,315 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-npm-support 0.1.4

+
+
+ + +
+
+
+

Adds support for using npm/yarn to build assets in Lektor using tools such as Parcel, webpack, etc.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.1.4

+

Author: + + Baruch Sterin + +

+ + +
+

Tags

+
+ + + + Babel, + + + before-build-all, + + + Browserify, + + + Node, + + + npm, + + + Parcel, + + + Sass, + + + server-spawn, + + + server-stop, + + + webpack, + + and + Yarn + + +

View all tags.

+
+ +
+

Project Description

+ +

lektor-npm-support

+

Build Status +Build status +Code Coverage

+

lektor-npm-support makes it easy to use Parcel, webpack, browserify, or any other tool to build assets for Lektor projects.

+

Enabling the Plugin

+

To enable the plugin, run this command while inside your Lektor project directory:

+
lektor plugins add lektor-npm-support
+
+

Example: Creating a Parcel Project

+

Create a parcel/ folder and inside that folder create the following files:

+

configs/npm-support.ini

+

This file instructs the plugin how to generate the assets:

+
[parcel]
+npm = yarn
+watch_script = watch
+build_script = build
+
+
    +
  • The section name [parcel] is the name of the folder where the Parcel project is located.
  • +
  • npm is the package manager command used to build the project. This example will use Yarn.
  • +
  • watch_script is the npm script used in lektor server -f npm,
  • +
  • build_script is the npm script used in lektor build -f npm.
  • +
+

This plugin supports more than one such entry.

+

parcel/package.json

+

This is a standard package.json file. It should contain two entries in the scripts section. The build script is used during lektor build -f npm, and the watch script is used during lektor server -f npm.

+
{
+  "name": "my-parcel-project",
+  "version": "1.0.0",
+  "scripts": {
+    "watch": "NODE_ENV=development parcel --out-dir=../assets/static/gen --out-file=main.js --public-url=./assets/ main.js",
+    "build": "NODE_ENV=production parcel build --out-dir=../assets/static/gen --out-file=main.js --public-url=./assets/ main.js"
+  },
+  "private": true
+}
+
+

Now we can use yarn add to add Parcel, Babel and Sass:

+
$ cd </path/to/your/lektor/project>/parcel
+$ yarn add parcel-bundler babel-preset-env node-sass
+
+

parcel/babelr.rc

+

Next up is a simple Babel config file, using the recommended env preset.

+
{
+  "presets": ["env"]
+}
+
+

parcel/main.scss

+

A simple SCSS file.

+
body {
+  border: 10px solid red;
+}
+
+

parcel/main.js

+

A simple Javascript file that imports the SCSS file so that Parcel will know to include it as well.

+
import './main.scss';
+
+

Running the Server

+

Now you're ready to go. When you run lektor server nothing wil happen, +instead you need to now run it as lektor server -f npm which +will enable the Parcel build. Parcel will automatically build your files +into assets/static/gen and this is where Lektor will then pick up the +files. This is done so that you can ship the generated assets +to others that might not have these tools, which simplifies using a +Lektor website that use this plugin.

+

Manual Builds

+

To manually trigger a build that also invokes webpack you can use lektor build -f npm.

+

Including The Files

+

Now you need to include the files in your template. This will do it:

+
<link rel="stylesheet" href="{{ '/static/gen/main.css'| asseturl }}">
+<script type=text/javascript src="{{ '/static/gen/main.js'| asseturl }}" charset="utf-8"></script>
+
+

Complete Working Example

+

The examples folder of this repository contains working projects.

+

Credits

+

This plugin is based on the official lektor-webpack-support Lektor plugin by Armin Ronacher.

+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-polymorphic-type/index.html b/plugins/lektor-polymorphic-type/index.html new file mode 100644 index 00000000..5bb64f42 --- /dev/null +++ b/plugins/lektor-polymorphic-type/index.html @@ -0,0 +1,290 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-polymorphic-type 0.1

+
+
+ + +
+
+
+

Add polymorphic field type to Lektor

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.1

+

Author: + + Jeff Dairiki + +

+ + +
+

Tags

+
+ + + + field type, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

Lektor Polymorphic Type

+

PyPI version +PyPI Supported Python Versions +GitHub license +GitHub Actions (Tests)

+

This plugin adds a new polymorphic lektor field type, polymorphic. +The determination of the actual type implementation of the field value +is deferred until evaluation time.

+

A motivating use case is to support having a “body” field whose +formatting can be switched between, e.g., markdown, and html (or +some other formatted type, such as reStructuredText.)

+

Installation

+

Add lektor-polymorphic-type to your project from command line:

+
lektor plugins add lektor-polymorphic-type
+
+

See the Lektor plugin documentation for more information.

+

How It Works

+

If the field has a polymorphic_type option set, that value is evaluated +and the result is interpreted as the name of the final type for the +field.

+

If no polymorphic_type option is set for the field, then we look for a +field on the current record whose name is name of the current field +with “_type” appended.

+

Examples

+

Simple Example

+

Here is an example model file for a simple page, with a selectable body format:

+
# page.ini
+
+[model]
+name = Page
+label = {{ this.title }}
+
+[fields.title]
+label = Title
+type = string
+
+[fields.body]
+label = Body
+type = polymorphic
+
+[fields.body_type]
+label = Body Type
+type = select
+choices = markdown, html, text
+default = markdown
+
+

Here, the value of the body_type field on a particular page will +determine whether the body field is interpreted as being markdown, +html or text.

+

Contrived Example

+

Here is a contrived example showing the use of the polymorphic_type option:

+
# page.ini
+
+[model]
+name = Page
+label = {{ this.title }}
+
+[fields.title]
+label = Title
+type = string
+
+[fields.body]
+label = Body
+type = polymorphic
+polymorphic_type = 'html' if this.body.lstrip().startswith('<') else 'markdown'
+
+

In this case, the body field will be interpreted as raw HTML if the +content of that field starts with a “<”, otherwise it will be +interpreted as Markdown text.

+

Author

+

Jeff Dairiki dairiki@dairiki.org

+

Changelog

+

0.1 — 2021-02-05

+

No code changes.

+

Update development status classifier to "stable".

+

Test under python 3.9. Stop testing under 3.5.

+

0.1b1 — 2020-05-04

+

Initial release.

+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-pythonmarkdown/index.html b/plugins/lektor-pythonmarkdown/index.html new file mode 100644 index 00000000..911fcd76 --- /dev/null +++ b/plugins/lektor-pythonmarkdown/index.html @@ -0,0 +1,281 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-pythonmarkdown 1.2

+
+
+ + +
+
+
+

Add pythonmarkdownn field type to Lektor to make use of python-markdown as a renderer.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 1.2

+

Author: + + Patrik Dufresne Service Logiciel inc. + +

+ + +
+

Tags

+
+ + + + field type, + + + Markdown, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

Lektor Python-Markdown Plugin

+

pipeline status

+

A Lektor plugin to parse markdown using +Python-Markdown. By default, lektor +uses mistune to parse markdown +field. +With this plugin, you can chose which parser is to be used by setting a +different type on the field. Either: markdown or pythonmarkdown

+

Installation

+

Add lektor-pythonmarkdown to your project from command line:

+
lektor plugins add lektor-pythonmarkdown
+
+

Usage

+

In your model, you need to define the type of field as follow:

+
[model]
+name = Page
+
+[fields.body]
+label = Body
+type = pythonmarkdown
+
+
+

Warning !

+

This plugins is is obviously incompatible with all of the mistune-specific events and plugins. Namely, all of markdown-* events and the plugins built around them.

+

Advance configuration

+

This lektor plugins provide a nice way to configure python-markdown. For instance, it's possible to explicitly define the extentions to be enabled and to configure each of them seperatly.

+

For an advance configuration, you need to create a file named pythonmarkdown.ini in the configs folder.

+

In that file you may write something similar to the following:

+
[markdown]
+# Define the configuration of python-markdown.
+# Reference: https://python-markdown.github.io/reference/#markdown
+
+#output_format = xhtml1
+#tab_length = 4
+#safe_mode = False
+#enable_attributes = True
+#smart_emphasis = True
+#lazy_ol = True
+
+[extensions]
+# List extensions to be enabled.
+markdown.extensions.extra = 1
+markdown.extensions.admonition = 1
+markdown.extensions.codehilite = 1
+markdown.extensions.meta = 1
+markdown.extensions.nl2br = 1
+markdown.extensions.sane_lists = 1
+markdown.extensions.smarty = 1
+markdown.extensions.toc = 1
+markdown.extensions.wikilinks = 1
+
+[markdown.extensions.codehilite]
+# Specific configuration for an extension.
+# Reference: https://python-markdown.github.io/extensions/code_hilite/#usage
+linenums = True
+#guess_lang = True
+#css_class = codehilite
+#pygments_style = default
+#noclasses = False
+#use_pygments = True
+
+
+

References

+ + + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-qiniu/index.html b/plugins/lektor-qiniu/index.html new file mode 100644 index 00000000..61a4dcd3 --- /dev/null +++ b/plugins/lektor-qiniu/index.html @@ -0,0 +1,298 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-qiniu 0.1.3

+
+
+ + +
+
+
+

Publish to Qiniu Cloud buckets and refresh the CDN cache.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.1.3

+

Author: + + Aaron Peng + +

+ + +
+

Tags

+
+ + + + publisher, + + + Qiniu, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

lektor-qiniu Lektor CMS 七牛云插件

+

lektor-qiniu is a plugin to deploy your lektor site to a qiniu cloud bucket.

+

简体中文说明

+

Main Features

+
    +
  1. deploy your site to your qiniu bucket
  2. +
  3. deploy your site to a folder in a qiniu bucket
  4. +
  5. exclude files and directories from deployment.
  6. +
  7. refresh your qiniu cdn.
  8. +
+

Before Installation

+

You may need a bucket from qiniu cloud to deploy your lektor project. Qiniu Cloud provides 10GB storage and cdn for free, that should be enough for most small projects.

+

Go to QINIU Cloud for more details.

+

This plugin does not do anything to help you create or configure qiniu account or bucket. You will have to make it done by yourself.

+

Installation

+

There ways to install plugin in Lektor, the easy ways is run below command in your project.

+
lektor plugins add lektor-qiniu
+
+

Press Enter and lektor will automatically download and install this plugin for you.

+

Usage

+

After Installation, open your lektorproject file, first it should have a section like this:

+
[packages]
+lektor-qiniu= 0.1.3
+
+

then below this section, you need add your bucket and folder(optional) as a target of a deploy server, like this:

+
[servers.qiniu]
+name = qiniu
+enabled = yes
+target = qiniu://<YOUR-BUCKET>
+
+

or if you want deploy your site to a folder in a bucket, mostly for backups, you can add server section as below:

+
[servers.qiniu]
+name = qiniu
+enabled = yes
+target = qiniu://<YOUR-BUCKET>/<NAME-OF-FOLDER>
+
+

for example, if you want to deploy your site to a bucket name "abcde", folder "fjhi", you will need to add a server section as below:

+
[servers.qiniu]
+name = qiniu
+enabled = yes
+target = qiniu://abcde/fjhi
+
+

after this you should see a server shows when you push the deploy button in your Lektor Admin Dashboard.

+

but still you will need just 5 minutes to configure this plugin to make it works.

+

Configuration

+

After setup your target server, you need to configure the plugin to make it works.

+

Go to your project's configs folder, which should be in root directory of your project. this folder is where Lektor keep the configuration files of all plugins. If you can't find any configs folder in your project's root directory, you need create it.

+

In configs folder, create a configuration file exactly named qiniu.ini.

+

Attention: DO NOT name the configuration file with other names, otherwise this plugin will not work properly.

+

In this configuration file, you will need add few more sections, you can copy a sample configuration ini file from the sample_config folder, it looks like this:

+
[auth]
+Access_Key = replace_with_your_own_AK
+Secret_Key = replace_with_your_won_SK
+
+[cdn]
+refresh_enable =  yes
+refresh_url = https://www.your-own-site.com/
+
+[exclusions]
+dirs = .lektor
+files =  
+
+

Credentials

+

You need to get your own Access Key and Secret Key from Qiniu Admin Dashboard, and put them in the auth section.

+

Refresh cdn cache

+

mostly, Qiniu provides a free(with limitations) cdn for your bucket site, after you update your bucket file, the cdn wouldn't update automatically, therefore you will need to refresh your bucket site's directory (via your site's root url), for more details you can check Qiniu's documentation.

+

fortunately, you don't need to do refresh manually, you can just set the refresh_enable to yes in your cdn section, and change the refresh_url to your site's root url. this plugin will automatically refresh your cdn site after all files are uploaded.

+

exclusions

+

Another function this plugin provides is exclude folders or files you want to upload during deployment.

+

To exclude files or folders, just put the name of the folders or files in the exclusions section of configuration file, separated each one with commas.

+
[exclusions]
+dirs = .lektor, dir1, dir2
+files =  file1, file2,file3
+
+

One special folder here is .lektor, which Lektor officially suggests that this folder should be exclude during deployment, therefore you should keep at least this one, unless you have other needs for this folder.

+

About Lektor CMS

+

Lektor CMS is one of my favorite static website generators, I have use this in production for several projects, you can see some of my sites as below:

+

新风网 +Intersonic Group +F&S Always Auto Parts +THEORING Seal Rings +THORING 密封圈

+

Looks pretty good, right? Thanks for lektor, you can try this best Static CMS as well via Lektor CMS Official Site

+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-read-full-post/index.html b/plugins/lektor-read-full-post/index.html new file mode 100644 index 00000000..56021021 --- /dev/null +++ b/plugins/lektor-read-full-post/index.html @@ -0,0 +1,210 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-read-full-post 0.3

+
+
+ + +
+
+
+

Allows blog listing posts to be shortened with a link to the full post.

+

+
+ + +
+
+

Project links

+ + + + +
+

Meta

+
+

Version: 0.3

+

Author: + + Andrew Shay + +

+ + +
+

Tags

+
+ + + + blog, + + + Jinja globals, + + + Markdown, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

Lektor plugin that allows blog listing posts to be shortened with a link to the full post.

+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-root-relative-path/index.html b/plugins/lektor-root-relative-path/index.html new file mode 100644 index 00000000..12f0c19e --- /dev/null +++ b/plugins/lektor-root-relative-path/index.html @@ -0,0 +1,249 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-root-relative-path 0.2.1

+
+
+ + +
+
+
+

Root relative path plugin for Lektor

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.2.1

+

Author: + + Atsushi Suga + +

+ + +
+

Tags

+
+ + + + Jinja filters, + + + navigation, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

Lektor root-relative-path plugin

+

This plugin returns root-relative-path list from top page to current page as below.

+
[(toppage_url, toppage_name), ...(parent_url, parent_name), (url, name)]
+
+

Installation

+

Add lektor-root-relative-path to your project from the command line:

+
lektor plugins add lektor-root-relative-path
+
+

See the Lektor documentation for more instructions on installing plugins.

+

Configuration

+

Set these option in configs/root-relative-path.ini:

+

navi_top_page_name

+

Optional. Name of top page inidicated in the navication. Default is 'Top Page'

+
navi_top_page_name = 'Top Page'
+
+

How to use

+

Insert the following line in the template (e.g. layout.html) which you would like to show navigation.

+
{% for i in this._path | root_relative_path_list %}
+  >><a href="{{i[0]}}">{{i[1]}}</a>
+{% endfor %}
+
+

Then, navigation is shown as below in case the page 'blog/first-post/'

+
>>Top Page >>blog >>first-post
+
+

If you do not want to show current page in the navigation, modify template as below.

+
{% for i in this._path | root_relative_path_list %}
+  {% if not loop.last %}
+    >><a href="{{i[0]}}">{{i[1]}}</a>
+  {% endif %}
+{% endfor %}
+
+

Then, navigation is shown as below.

+
>>Top Page >>blog
+
+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-rst/index.html b/plugins/lektor-rst/index.html new file mode 100644 index 00000000..07aa2718 --- /dev/null +++ b/plugins/lektor-rst/index.html @@ -0,0 +1,215 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-rst 0.2.0

+
+
+ + +
+
+
+

Adds reStructuredText support to Lektor.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.2.0

+

Author: + + Florian Schulze + +

+ + +
+

Tags

+
+ + + + field type, + + + reStructuredText, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ + Plugin has no long_description + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-s3/index.html b/plugins/lektor-s3/index.html new file mode 100644 index 00000000..733d8add --- /dev/null +++ b/plugins/lektor-s3/index.html @@ -0,0 +1,319 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-s3 0.5.1

+
+
+ + +
+
+
+

Publish to S3 buckets and Cloudfront.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.5.1

+

Author: + + Spencer Nelson + +

+ + +
+

Tags

+
+ + + + AWS, + + + CloudFront, + + + publisher, + + + S3, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

lektor-s3

+

Build Status

+

lektor-s3 makes it easy to deploy your +Lektor project to an S3 bucket.

+

Before you start

+

You're going to be storing your website's data in an S3 bucket. The code +here won't do anything to create or configure that bucket. You'll have to +create the S3 bucket and set it up yourself.

+

AWS has a pretty good guide +for how to set up a bucket to host a static website. You'll need to both +create the bucket and set its permissions to allow global read access. +Remember to do this first because lektor-s3 won't do it automatically.

+

Installation and Usage

+

Install with the usual Lektor toolchain. Within your project, run

+
lektor plugins add lektor-s3
+
+

You should see a message saying lektor-s3 has been added to the project.

+

Next, add an S3 bucket to your project's servers. In your project file +(like blog.lektorproject), add the following:

+
[servers.s3]
+name = S3
+enabled = yes
+target = s3://<YOUR-BUCKET>
+
+

For example, if you wanted to deploy to a bucket named 'huntedwumpus', +you'd make that last line

+
target = s3://huntedwumpus
+
+

Now, if you call lektor deploy s3, Lektor will upload your built +website to S3 in the bucket you targeted.

+

CloudFront

+

Optionally, you can also provide a CloudFront +distribution ID. If you do, Lektor will invalidate all objects in that CloudFront +distribution after every deploy.

+
cloudfront = <YOUR-DISTRIBUTION-ID>
+
+

Credentials

+

You need to prove to S3 that you have permission to upload to the +bucket you've chosen.

+

lektor-s3 uses boto, which means it will obey +boto's usual flow for gathering credentials.

+

For a refresher, that means you have two options: you can store your +credentials in an INI file at ~/.aws/credentials, or you can pass +credentials in through the environment variables AWS_ACCESS_KEY_ID +and AWS_SECRET_ACCESS_KEY.

+

If you have multiple sets of credentials, you can group them into profiles in +your credentials file and choose the right one using the AWS_PROFILE +environment variable. Your ~/.aws/credenials file might look like this:

+
[work]
+aws_access_key_id = <...>
+aws_secret_access_key = <...>
+
+[personal]
+aws_access_key_id = <...>
+aws_secret_access_key = <...>
+
+

And then you can invoke lektor with the environment variable:

+
$ AWS_PROFILE=personal lektor deploy`
+
+

Configuration

+

You can specify headers to be attached to particular files when uploading them +to S3. These can be configured in an INI file at configs/s3.ini under your +project root.

+

You can name the sections anything that makes sense to you, but every section +must have either a match or an extensions item to specify which files the +configuration applies to. If using match, you should write this as a regular +expression that will be applied against the filename using the regular +expression's search method. If using extensions, write a comma-separated list +of the file extensions to which the configuration applies. Both match and +extensions may be specified.

+

The rest of the items in each section should specify one or more headers and +their values. A list of valid headers is defined in the boto documentation as +ALLOWED_UPLOAD_ARGS.

+

Defaults can be defined via the usual INI file way, in a [DEFAULTS] section.

+

For example, your configuration file might look like this:

+
[DEFAULT]
+CacheControl = public,max-age=3600
+
+[static files]
+match = \.(css|js|woff|woff2)$
+CacheControl = public,max-age=31536000
+
+[media]
+extensions = jpg,jpeg,png,mp4
+CacheControl = public,max-age=259200
+
+[fonts]
+extensions = woff2
+ContentType = application/font-woff2
+
+[documents]
+extensions = html,txt
+ContentLanguage = en
+
+

Contributing

+

Pull requests are super useful and encouraged! Once accepted, changes +are published using lektor with lektor dev publish-plugin.

+

Run your tests by invoking python setup.py test.

+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-scss/index.html b/plugins/lektor-scss/index.html new file mode 100644 index 00000000..44dfd7f9 --- /dev/null +++ b/plugins/lektor-scss/index.html @@ -0,0 +1,309 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-scss 1.4.1

+
+
+ + +
+
+
+

Lektor plugin to compile css out of sass - based on libsass

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 1.4.1

+

Author: + + L3D + +

+ + +
+

Tags

+
+ + + + before-build-all, + + + HTML, + + + Sass, + + + SCSS, + + + server-spawn, + + and + server-stop + + +

View all tags.

+
+ +
+

Project Description

+ +

SCSS compiler for lektor

+

PyPI version +Downloads +Upload Python Package +Linting Python package

+

SCSS compiler for Lektor that compiles css from sass.

+

How does it actually work?

+
    +
  • It uses libsass
  • +
  • It looks for .scss and .sass files (ignores part files that begin with a underscore e.g. '_testfile.scss') and compiles them as part of the build process.
  • +
  • It only rebuilds the css when it's needed (file changed, a file it imports changed or the config changed).
  • +
  • When starting the the development server it watches the files for changes in the background and rebuilds them when needed.
  • +
+

Installation

+

You can install the plugin with Lektor's installer:

+
lektor plugins add lektor-scss
+
+

Or by hand, adding the plugin to the packages section in your lektorproject file:

+
[packages]
+lektor-scss = 1.4.1
+
+

Usage

+

To enable the plugin, pass the scss flag when starting the development +server or when running a build:

+
# build and compile css from scss
+lektor build -f scss
+
+# edit site with new generated css
+lektor server -f scss
+
+

Python3

+

It is highly recommended to use this plugin with a python3 version of lektor.

+

Since lektor can be used as a python module it is possible to enforce this (after lektor is installed eg. with pip3 install --user --upgrade lektor) with the following command:

+
# run a python3 lektor server with new generated css
+python3 -m lektor server -f scss
+
+

Configuration

+

The Plugin has the following settings you can adjust to your needs:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
parameterdefault valuedescription
source_dirassets/scss/the directory in which the plugin searchs for sass files (subdirectories are included)
output_dirassets/css/the directory the compiled css files get place at
output_stylecompressedcoding style of the compiled result. choose one of: 'nested', 'expanded', 'compact', 'compressed'
source_commentsFalsewhether to add comments about source lines
precision5precision for numbers
include_pathsIf you want to include SASS libraries from a different directory, libsass's compile function has a parameter called include_paths to add those directories to the search path.
+

An example file with the default config can be found at configs/scss.ini. For every parameter that is not specified in the config file the default value is used by the plugin.

+

Development

+

To test and/or develop on this plugin in your running lektor installation, simply place it in the packages/ Folder and have a look at the Lektor Doku

+ + + + + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-scsscompile/index.html b/plugins/lektor-scsscompile/index.html new file mode 100644 index 00000000..18774e15 --- /dev/null +++ b/plugins/lektor-scsscompile/index.html @@ -0,0 +1,291 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-scsscompile 1.3.0

+
+
+ + +
+
+
+

SASS compiler for Lektor, thats based on libsass.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 1.3.0

+

Author: + + maxbachmann + +

+ + +
+

Tags

+
+ + + + before-build-all, + + + libsass, + + + minify, + + + Sass, + + + SCSS, + + + server-spawn, + + and + server-stop + + +

View all tags.

+
+ +
+

Project Description

+ +

SCSScompile

+

PyPI version Downloads

+

SCSS compiler for Lektor that automatically compiles sass.

+

Uses libsass and looks for .scss/.sass files (ignores part files that begin with a underscore e.g. '_testfile.scss'), +compiling them as part of the build process. It only rebuilds when it's needed (file changed, a file it imports changed or the config changed). When starting the the development server it watchs the files for changes in the background and rebuilds them when needed.

+

Installing

+

You can install the plugin with Lektor's installer::

+
lektor plugins add lektor-scsscompile
+
+

Or by hand, adding the plugin to the packages section in your lektorproject file::

+
[packages]
+lektor-scsscompile = 1.3.0
+
+

Usage

+
+

To enable scsscompile, pass the scsscompile flag when starting the development +server or when running a build::

+
lektor build -f scsscompile
+
+
lektor build -f scsscompile
+
+

The Plugin has the following settings you can adjust to your needs:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
parameterdefault valuedescription
source_dirasset_sources/scss/the directory in which the plugin searchs for sass files (subdirectories are included)
output_dirassets/css/the directory the compiled css files get place at
output_stylecompressedcoding style of the compiled result. choose one of: 'nested', 'expanded', 'compact', 'compressed'
source_commentsFalsewhether to add comments about source lines
precision5precision for numbers
output_source_mapFalsewhether a source map should be generated
+

An example file with the default config can be found at configs/scsscompile.ini

+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-shortcodes/index.html b/plugins/lektor-shortcodes/index.html new file mode 100644 index 00000000..12ac42d4 --- /dev/null +++ b/plugins/lektor-shortcodes/index.html @@ -0,0 +1,221 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-shortcodes 0.2.5

+
+
+ + +
+
+
+

Allows you to use shortcodes (something like tags) in your model fields.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.2.5

+

Author: + + Stavros Korokithakis,,, + +

+ + +
+

Tags

+
+ + + + Jinja filters, + + + Markdown, + + + markdown-config, + + + setup-env, + + and + shortcodes + + +

View all tags.

+
+ +
+

Project Description

+ + Lektor Shortcodes
=================

[![PyPI](https://img.shields.io/pypi/v/lektor-shortcodes.svg)](https://pypi.python.org/pypi/lektor-shortcodes)

The Lektor Shortcodes plugin allows you to use shortcodes (shortcodes are
something like custom tags) in your fields (not templates), so your content
doesn't have to have repetitive snippets over and over.

For example, my blog has some specific HTML that I add when I want an image with
a border and caption to be displayed. The HTML looks like this:


~~~html
<div class="alignright">
<a href="image-large.jpg">
<img src="image.jpg" />
<span class="caption">The caption</span>
</a>
</div>
~~~

Copy-pasting this every time gets tedious, and I have to search and replace it
in all the content files every time I want to make a change. With the
shortcodes plugin, this can be written as:

~~~
[% image align=right link="image-large.jpg" image=image.jpg caption="The caption" %]
~~~

Much easier, cleaner and less repetitive.


Installation
------------

To install the plugin, just add `lektor-shortcodes` to your plugins from the
command line:

~~~
lektor plugins add lektor-shortcodes
~~~


Usage
-----

Using the plugin is simple. Just create a config file called `shortcodes.ini` in
your `configs` directory and specify some shortcode templates. The templates are
full Jinja templates, although (due to some limitations of ini files) they need
to be on one line.

For instance, for the example above, the config file could be:

~~~ini
[global]
image = '<div class="align{{ align }}">{% if link %}<a href="{{ link }}"{% if not link.startswith("http") %} data-lightbox="gallery"{% endif %}>{% endif %}<img src="{{ image }}">{% if link %}</a>{% endif %}{% if caption %}<span class="caption">{{ caption }}</span>{% endif %}</div>'
~~~

This will allow you to use shortcodes with optional arguments, like so:

~~~
# An image with no caption or link:
[% image align=right image=hello.jpg %]


# An image with a link:
[% image align=right link=http://www.example.com image=hello.jpg %]

# Link and caption:
[% image align=right link=http://www.example.com image=hello.jpg caption="Hello!" %]
~~~

Shortcodes defined within the section named `global` will be processed
automatically inside any of your site’s Markdown content. It is also possible to
define shortcodes which are only expanded when the Jinja2 template for a page
explicitly requests it. Shortcodes defined in any section not named `global`
will only be applied when the template passed the content through a Jinja2
filter named `shortcode`. For example, if your HTML template references a field
called `body`, you may request expanding shortcodes defined within the
`body-only` section of your config file, like so:

~~~
{{ body|shortcodes(section="body-only") }}
~~~

This will enable all shortcodes from the specified section, in addition to all
globally defined shortcodes. If no section is specified, the filter defaults to
the section named `main`.


Miscellanea
-----------

If you find a bug or have a feature request, please open an issue or file a PR.
Thanks!
+ + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-slugify/index.html b/plugins/lektor-slugify/index.html new file mode 100644 index 00000000..be4d168a --- /dev/null +++ b/plugins/lektor-slugify/index.html @@ -0,0 +1,223 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-slugify 0.4

+
+
+ + +
+
+
+

Lektor plugin that adds a slugify Jinja filter.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.4

+

Author: + + Terminal Labs, Michael Verhulst, Joseph Nix + +

+ + +
+

Tags

+
+ + + + Jinja filters, + + + python-slugify, + + + setup-env, + + and + slugify + + +

View all tags.

+
+ +
+

Project Description

+ +

lektor-slugify

+

This is a Lektor plugin that provides a simple template filter that transforms a (unicode) string into a slug.

+

Usage: {{ var|slug }}

+

Advanced usage: The |slug filter can also accept keyword arguements that are passed to python-slugify. That means you have the option of doing, for example, {{ var|slug(lowercase=False) }} to preserve case sensitivity.

+

This is a simple use of the Python package python-slugify.

+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-strip-html-tags/index.html b/plugins/lektor-strip-html-tags/index.html new file mode 100644 index 00000000..eeb1e979 --- /dev/null +++ b/plugins/lektor-strip-html-tags/index.html @@ -0,0 +1,223 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-strip-html-tags 0.3.1

+
+
+ + +
+
+
+

Strip HTML tags, effectively turning HTML into plain text.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.3.1

+

Author: + + Terminal Labs + +

+ + +
+

Tags

+
+ + + + HTML, + + + Jinja filters, + + and + setup-env + + +

View all tags.

+
+ +
+

Project Description

+ +

lektor-strip-html-tags

+

This is a simple Lektor plugin that creates a template filter to remove HTML tags from a string. The use it was created for was to do processing on HTML outputted from a Markdown content field. The Markdown is rendered into HTML, and this filter can turn that into simple text, which was then passed to the lektor-natural-language filters to get keywords, unsullied by things like <div> tags.

+

Example usage:

+

{{ this.body|striphtmltags }}

+
{% set var = '<p><strong>Hello</strong>World!</p>' %}
+{{ var|striphtmltags }}
+
+

The last example will render as "Hello World!"

+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-surge/index.html b/plugins/lektor-surge/index.html new file mode 100644 index 00000000..1c67bc8f --- /dev/null +++ b/plugins/lektor-surge/index.html @@ -0,0 +1,236 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-surge 0.3

+
+
+ + +
+
+
+

Lektor plugin to publish your site to surge.sh

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.3

+

Author: + + A. Jesse Jiryu Davis + +

+ + +
+

Tags

+
+ + + + publisher, + + + setup-env, + + and + Surge + + +

View all tags.

+
+ +
+

Project Description

+ +

Lektor Surge Publisher Plugin

+

Publishes your Lektor site to Surge.

+

Installation

+

Add lektor-surge to your project from command line:

+
lektor plugins add lektor-surge
+
+

See the Lektor documentation for more instructions on installing plugins.

+

Configuration

+

Configure Surge in your .lektorproject file:

+
[servers.surge]
+target = surge:my-domain.com
+
+

To force all traffic to HTTPS, update your .lektorproject file:

+
[servers.surge]
+target = surge+https:my-domain.com
+
+

For more information, see the Surge guide to HTTPS.

+

Deployment

+

Deploy your site with Lektor from the command line:

+
lektor deploy surge
+
+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-tags/index.html b/plugins/lektor-tags/index.html new file mode 100644 index 00000000..bc7c6452 --- /dev/null +++ b/plugins/lektor-tags/index.html @@ -0,0 +1,409 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-tags 0.5.0

+
+
+ + +
+
+
+

Lektor plugin to add tags.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.5.0

+

Author: + + A. Jesse Jiryu Davis + +

+ + +
+

Tags

+
+ + + + page generation, + + + setup-env, + + + tags, + + and + virtual paths + + +

View all tags.

+
+ +
+

Project Description

+ +

Lektor Tags Plugin

+

PyPI version +Code style: black

+

Introduction

+

This plugin implements tagging for your site. For each of your tags, it builds a page displaying a list of items that have that tag. This can be used for standard tag-based blog navigation. With this plugin you can give any number of tags to any blog posts, and a page will be created for each tag.

+

For example, if your site has blog posts in your content/blog directory tagged with coffee and tea:

+
name: First Post
+---
+tags:
+
+coffee
+tea
+
+

The lektor-tags plugin builds pages at these URLs:

+
    +
  • /blog/tag/coffee/
  • +
  • /blog/tag/tea/
  • +
+

Each page can list all the posts with that tag.

+

Installation

+

Add lektor-tags to your project from command line:

+
lektor plugins add lektor-tags
+
+

See the Lektor documentation for more instructions on installing plugins.

+

Overview

+

Say you have a "blog-post" model like this:

+
[model]
+name = Blog Post
+
+[fields.tags]
+type = strings
+
+

Make a blog-post.html template that includes:

+
{% if this.tags %}
+  <ul>
+    {% for t in this.tags -%}
+      <li>
+        <a href="{{ ('/blog@tag/' ~ t)|url }}">
+          All posts tagged {{ t }}
+        </a>
+      </li>
+    {% endfor %}
+  </ul>
+{% endif %}
+
+

This expression in the template generates a source path for each of the blog post's tags:

+
'/blog@tag/' ~ t
+
+

Then if the tag is "my-tag", the expression renders a source path like:

+
/blog/tag/my-tag
+
+

A Lektor source path becomes an actual URL using the url filter. So the template generates URLs to tag pages like:

+
<a href="{{ ('/blog@tag/' ~ t)|url }}"></a>
+
+

This uses the source path expression from before, but pipes it through url to generate an actual link from the blog post to a tag page.

+

Configuration

+

Set these options in configs/tags.ini:

+

parent

+

Required. The source path of the tag pages' parent page. For example:

+
parent = /blog
+
+

Then tag pages' source paths are like:

+
/blog/tag/my-tag
+
+

You can specify the root as the parent:

+
parent = /
+
+

items

+

A query for all items on the page for one tag. You can use the variables site and tag. The template's this variable has a parent attribute. The default query is:

+
items = this.parent.children.filter(F.tags.contains(tag))
+
+

You can sort and filter with any expression:

+
items = this.parent.children.filter(F.tags.contains(tag) and F.status == 'published').order_by('-pub_date')
+
+

If the parent page has a pagination query you may want to use it for tagged pages:

+
items = this.parent.pagination.items.filter(F.tags.contains(tag))
+
+

See the Lektor documentation for queries.

+

tags_field

+

The name of the field in your model that contains tags. Defaults to tags. The field should be of type strings. See the Lektor documentation for the strings type.

+

For example, if your model is like:

+
[fields.labels]
+type = strings
+
+

Then add this to tags.ini:

+
tags_field = labels
+
+

template

+

The template for the page that lists all posts with a certain tag. The template's this variable has attributes tag and items. An example template:

+
<h1>Tag: {{ this.tag }}</h1>
+<h1>Items:</h1>
+<ul>
+  {% for i in this.items %}
+    <li><a href="{{ i|url }}">{{ i._id }}</a></li>
+  {% else %}
+    <li><em>No items.</em></li>
+  {% endfor %}
+</ul>
+
+

Save a file like this to your project's templates/tags.html. If you name the file something different, like label.html, add this line to tags.ini:

+
template = label.html
+
+

The plugin provides a default template if you don't specify one.

+

url_path

+

An expression for the location of each tag page. You can use the variables site and tag. The this variable is a page with attributes parent and items. The default expression is:

+
url_path = {{ this.parent.url_path }}tag/{{ tag }}
+
+

This expression generates URLs like /blog/tag/coffee.

+

ignore_missing

+

Default false. To set true, add this line to tags.ini:

+
ignore_missing = true
+
+

This allows URLs to missing tag pages to be silently replaced with "". The example use case is if your blog-post.html template includes a statement like:

+
{% for t in this.tags -%}
+  <a href="{{ ('/blog@tag/' ~ t)|url }}">{{ t }}</a>
+{% endfor %}
+
+

If a blog post draft is not discoverable, and it has any new tags used by no published blog posts, then those tag pages do not yet exist. Turn on ignore_missing to allow such drafts to be built. The tag-page URL path will be the empty string "", until the draft is published and the tag page is created.

+

tags

+

Advanced configuration. An expression for the set of tags. Note that this expression is also useful in a template to get a list of all tags. The default expression is:

+
tags = parent.children.distinct("tags")
+
+

If you set tags_field to a different field name than "tags", the default expression uses your custom field name. For example if you have this line in tags.ini:

+
tags_field = labels
+
+

Then the default value of tags is:

+
tags = parent.children.distinct("labels")
+
+

You can use any template expression. For example, if your items have a "published" boolean field, you can select tags of published items:

+
tags = parent.children.filter(F.published).distinct("tags")
+
+

Or even list your tags manually:

+
tags = ["tag1", "tag2"]
+
+

See the Lektor documentation for queries.

+

Tags are always deduplicated. Tags are sorted in the order listed in the contents.lr / admin, allowing you to control their order manually. Since {{ tags }} simply returns a list, you can always apply any Jinja2 filter on that list such as sort, slice, or rejectattr.

+

Tag cloud & tag weights

+

This plugin won't automatically build a tag cloud, but it provides the tools to build it.

+

The Jinja2 context has a tagweights() function, which returns a dictionary that maps tags to their weight using several attributes or functions. Here are those attributes and functions, with examples of how they can be used in a template.

+

Unused tags are ignored.

+

TL;DR Which weight function should I use?

+
    +
  • To get the number of pages tagged by each tag, use count.
  • +
  • To map tags to numbers, use log(lower, upper).
  • +
  • To map tags to everything else, use loggroup(list).
  • +
+

count — Number of pages tagged with this tag

+

This is the basic weight, used as a base for the following tags.

+

Example: Tags (with tag count) sorted by tag count (most used first)

+
<ul>
+{% for tag, weight in (tagweights() | dictsort(by='value', reverse=true)) %}
+    <li>{{ tag }} ({{ weight.count }} articles).</li>
+{% endfor %}
+</ul>
+
+

linear — Tags are mapped with a number between lower and upper.

+

The less used tag is mapped lower, the most used tag is mapped upper (lower and upper can be equal, upper can be smaller than lower).

+

Mapping is done using a linear function.

+

The result is a float: you might want to convert them to integers first (see example for log).

+

Unless you know what you are doing, you should use log instead.

+

log — Logarithm of tag counts are mapped with a number between lower and upper.

+

The less used tag is mapped lower, the most used tag is mapped upper (lower and upper can be equal, upper can be smaller than lower).

+

Mapping is done using a linear function over the logarithm of tag counts.

+

The result is a float: you might want to convert them to integers first (see example).

+

Example: Most used tag is twice as big as least used tag

+
{% for tag, weight in tagweights()|dictsort %}
+<a
+    href="{{ ('/blog@tag/' ~ tag)|url }}"
+    style="font-size: {{ weight.log(100, 200)|round|int }}%;"
+    >
+        {{ tag }}
+    </a>
+{% endfor %}
+
+

lineargroup — Map each tag with an item of the list given in argument

+

The less used tag is mapped with the first item, the most used tag is mapped with the last item.

+

Mapping is done using a linear function.

+

Unless you know what you are doing, you should use loggroup instead.

+

loggroup — Logarithm of tag counts are mapped with an item of the list given in argument

+

The less used tag is mapped with the first item, the most used tag is mapped with the last item.

+

Mapping is done using a linear function over the logarithm of tag counts.

+

Example: Tags are given CSS classes tagcloud-tiny, tagcloud-small, etc.

+
{% for tag, weight in tagweights()|dictsort %}
+<a
+    href="{{ ('/blog@tag/' ~ tag)|url }}"
+    class="tagcloud-{{ weight.loggroup(["tiny", "small", "normal", "big", "large"]) }}"
+    >
+        {{ tag }}
+    </a>
+{% endfor %}
+
+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-tawk/index.html b/plugins/lektor-tawk/index.html new file mode 100644 index 00000000..f0e1fa20 --- /dev/null +++ b/plugins/lektor-tawk/index.html @@ -0,0 +1,235 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-tawk 0.1

+
+
+ + +
+
+
+

Embed Tawk Live Chat into your website.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.1

+

Author: + + Fabio Oliveira + +

+ + +
+

Tags

+
+ + + + setup-env, + + + tawk, + + + templates, + + and + website + + +

View all tags.

+
+ +
+

Project Description

+ +

# Lektor Tawk

+

This plugin adds support for Tawk to Lektor. Once the plugin is enabled a render_tawk function will render a Tawk Live Chat.

+

## Enabling the Plugin

+

To enable the plugin add this to your project file:

+

` +$ lektor plugins add lektor-tawk +`

+

## Configuring the Plugin

+

The plugin has a config file that is needed to inform it about your website. Just create a file named tawk.ini into your configs/ folder and configure the live_chat_code key with the ID if your Tawk:

+

` +live_chat_code = your_live_chat_code +`

+

## In Templates

+

Now you can render to any of your templates by just using the render_tawk function. Just calling it is enough to get the live chat:

+

` +<div>{{ render_tawk }}</div> +`

+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-thumbnail-generator/index.html b/plugins/lektor-thumbnail-generator/index.html new file mode 100644 index 00000000..b1800225 --- /dev/null +++ b/plugins/lektor-thumbnail-generator/index.html @@ -0,0 +1,254 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-thumbnail-generator 0.5.0

+
+
+ + +
+
+
+

This plugin automatically generates thumbnails for any images in your Lektor content. The difference between this plugin and the `thumbnail` filter is that this is geared towards content, i.e. you don't need to have any references to the images in your templates at all.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.5.0

+

Author: + + Stavros Korokithakis,,, + +

+ + +
+

Tags

+
+ + + + images, + + and + thumbnails + + +

View all tags.

+
+ +
+

Project Description

+ +

Lektor Thumbnail Generator

+

This plugin automatically generates thumbnails for any images in your Lektor +content. The difference between this plugin and the thumbnail filter is that +this is geared towards content, i.e. you don't need to have any references to +the images in your templates at all.

+

Usage

+

Use this plugin if you want to be able to link to full-size images in your +content, but still want thumbnails to be generated for the link itself. For +example, you may have an image called cat.jpg, and to link to it in the +content (not the template), but also show a thumbnail.

+

You can do that like so:

+
<a href="cat.jpg"><img src="cat-small.jpg" /></a>
+
+

Installation

+

To install the plugin, just add lektor-thumbnail-generator to your plugins +from the command line:

+
lektor plugins add lektor-thumbnail-generator
+
+

If you have trouble, see the plugin +installation section of the Lektor +documentation.

+

Then, create a config file called configs/thumbnail-generator.ini and add +a few sections for images. The section names can be whatever you want, the +final images will be called imagename-sectionname.ext. For example, this +config file:

+
[small]
+max_width = 30
+
+[medium]
+max_width = 400
+max_height = 400
+
+[woowee]
+max_width = 2000
+
+

Will take a file called cat.jpg and create the files cat-small.jpg, +cat-medium.jpg and cat-woowee.jpg. All the files will be created, regardless +of whether the original file is smaller, so you can link without worrying +whether a file will exist or not. If the original file is smaller than the width +you have specified, the file will only be copied, and will not be resized. +The max_width/max_height parameters work like for the Lektor +thumbnail command.

+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-webdav/index.html b/plugins/lektor-webdav/index.html new file mode 100644 index 00000000..6014c7ed --- /dev/null +++ b/plugins/lektor-webdav/index.html @@ -0,0 +1,380 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-webdav 0.1.1.post5

+
+
+ + +
+
+
+

Lektor plugin to get a list of files from a WebDAV server

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.1.1.post5

+

Author: + + Amin Mesbah + +

+ + +
+

Tags

+
+ + + + content, + + + Jinja filters, + + + Jinja globals, + + + remote content, + + + setup-env, + + and + WebDAV + + +

View all tags.

+
+ +
+

Project Description

+ +

Lektor WebDAV Plugin

+

PyPI version shields.io

+

Get a list of files hosted on a WebDAV server for use in your +Lektor templates.

+

Installation

+
mkdir packages
+cd packages
+git clone https://github.com/mesbahamin/lektor-webdav
+
+

I'll try to set this up soon so it can be installed properly with lektor plugins add.

+

Configuration

+

For each WebDAV server you want to use, add a section in configs/webdav.ini:

+
[photos]
+url = https://my.webdav.domain/photography/
+username = my_user@example.com
+passcmd = pass my_webdav_server
+
+

Replace 'photos' with whatever label you want for this particular webdav server.

+

Options

+ + + + + + + + + + + + + + + + + + + + + +
OptionDescription
urlURL of your WebDAV folder
usernameUsername with which to authenticate with the WebDAV server
passcmdA command that will return your WebDAV password as a UTF-8 string
+

Use In Templates

+

This plugin exposes the following for use in Jinja2 templates:

+

Functions

+
    +
  • webdav_ls_files +
      +
    • Return a list of all files (not folders) in a WebDAV directory. The files +are returned in the form of a list of WebdavFile instances.
    • +
    • Parameters: +
        +
      • webdav_id. This is the name you chose as the section title in +webdav.ini ('photos' in the above snippet).
      • +
      • path (optional). If you want to look in a subfolder of your WebDAV +folder, pass its name in here.
      • +
      +
    • +
    +
  • +
  • webdav_ls_file_names +
      +
    • Same as webdav_ls_files, but only return the names.
    • +
    +
  • +
  • webdav_ls_file_paths +
      +
    • Same as webdav_ls_files, but only return the paths.
    • +
    +
  • +
+

Tuples

+
    +
  • WebdavFile: A named tuple that holds information about a file. +
      +
    • path +
        +
      • The full path of the file with the WebDAV server's URL as its root.
      • +
      • Example: '/photographs/my_photograph_of_a_wall.jpg'
      • +
      +
    • +
    • name +
        +
      • Just the name of the file itself.
      • +
      • Example: 'my_photograph_of_a_wall.jpg'
      • +
      +
    • +
    • content_type +
        +
      • Filetype metadata supplied by the WebDAV server.
      • +
      • Example: 'images/jpeg'
      • +
      +
    • +
    +
  • +
+

Filters

+
    +
  • webdav_zip +
      +
    • Jinja2 doesn't have a zip filter, so I included one here since I needed +to pair up my photos with generated thumbnails (see example below).
    • +
    • Usage: {{ zipped_iterator_ab = iterator_a|zip(iterator_b) }}
    • +
    +
  • +
+

Example

+

I made this because I wanted to make a photo gallery on my blog. I already had +a webDAV server through my Fastmail account, and I wanted to host the images +there.

+

My full site configuration can be found +here, but here are the main bits:

+

Config

+

My webdav.ini looks like this:

+
[photography]
+url = https://myfiles.fastmail.com/photography/
+username = me@mydomain.com
+passcmd = pass sync/fastmail_webdav
+
+

I using pass to manage my passwords, so +I invoke it in passcmd.

+

Template

+

The template for my photography page looks like this:

+
{% extends "layout.html" %}
+{% block body %}
+<h2>Photography</h2>
+<section class="photos">
+<div class="photo-list">
+{% set photo_host_url = bag('photo_list', 'host_url') %}
+{% set thumb_dimension = bag('photo_list', 'thumb_dimension') %}
+{%
+    for photo_file_name, thumbnail_file_name
+    in (
+        webdav_ls_file_names('photography')
+        |webdav_zip(webdav_ls_file_names('photography', 'thumbnails')
+    )
+    |sort(reverse=True))
+%}
+    {% set photo_url = photo_host_url + photo_file_name %}
+    {% set thumb_url = photo_host_url + 'thumbnails/' + thumbnail_file_name %}
+    <div class="photo">
+    <a href="{{ photo_url }}">
+        <img src="{{ thumb_url }}" width="{{ thumb_dimension }}" height="{{ thumb_dimension }}"/>
+    </a>
+    </div>
+{% endfor %}
+</div>
+</section>
+{% endblock %}
+
+

I get a list of my WebDAV hosted photos and a list of pre-generated thumbnails. +Then I zip them together with webdav_zip and iterate through them +simultaneously.

+

Result

+

My gallery page looks like this.

+

When I want to add more photos, I simply upload them to my WebDAV server, then +run lektor build.

+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-webpack-html-helper/index.html b/plugins/lektor-webpack-html-helper/index.html new file mode 100644 index 00000000..d5f4e91e --- /dev/null +++ b/plugins/lektor-webpack-html-helper/index.html @@ -0,0 +1,296 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-webpack-html-helper 0.1.3

+
+
+ + +
+
+
+

Observes the assets directory for html files and copies them into the templates folder.

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.1.3

+

Author: + + Oliver Epper + +

+ + +
+

Tags

+
+ + + + html-webpack-plugin, + + + server-spawn, + + + server-stop, + + + watchdog, + + and + webpack + + +

View all tags.

+
+ +
+

Project Description

+ +

lektor-webpack-html-helper

+

This is a plugin for Lektor that adds support for generating templates with webpacks HtmlWebpackPlugin. These templates can be generated into Lektors assets folder which will be observed for newly created or modified html files. +These files will then be copied over to Lektors templates folder so that they can be used by Lektor. +This plugin depends on the lektor-webpack-support plugin to be really useful.

+

webpack/webpack.config.js

+
const path = require("path");
+const MiniCssExtractPlugin = require("mini-css-extract-plugin");
+const HtmlWebpackPlugin = require("html-webpack-plugin");
+const { CleanWebpackPlugin } = require("clean-webpack-plugin");
+
+
+module.exports = {
+    mode: "production",
+    entry: {
+        main: "./src/index.js"
+    },
+    output: {
+        filename: "[name].bundle.js",
+        path: path.dirname(__dirname) + "/assets/generated" 
+    },
+    optimization: {
+        minimizer: [
+            new HtmlWebpackPlugin({
+                inject: false,
+                filename: "layout_generated.html",
+                template: "./src/layout_template.html"
+            })
+        ],
+    },
+    plugins: [
+        new CleanWebpackPlugin(),
+        new MiniCssExtractPlugin({
+            filename: "[name].css"
+        })
+    ],
+    module: {
+        rules: [{
+            test: /\.scss$/,
+            use: [
+                MiniCssExtractPlugin.loader,
+                "css-loader",
+                "sass-loader"
+            ]
+        }]
+    }
+}
+
+

webpack/src/layout_template.html

+
<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <meta http-equiv="X-UA-Compatible" content="ie=edge">
+    <title>{{ this.title }} &middot; {{ config.PROJECT.name }} </title>
+
+    <% for (var css in htmlWebpackPlugin.files.css) { %>
+    <link href="{{ '/generated/<%= htmlWebpackPlugin.files.css[css] %>' | asseturl }}" rel="stylesheet">
+    <% } %>
+</head>
+
+<body>
+    <main>
+        {% block content %}
+        {% endblock content %}
+    </main>
+
+    <% for (var chunk in htmlWebpackPlugin.files.chunks) { %>
+    <script src="{{ '/generated/<%= htmlWebpackPlugin.files.chunks[chunk].entry %>' | asseturl }}"></script>
+    <% } %>
+</body>
+
+</html>
+
+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-webpack-support/index.html b/plugins/lektor-webpack-support/index.html new file mode 100644 index 00000000..3a365af7 --- /dev/null +++ b/plugins/lektor-webpack-support/index.html @@ -0,0 +1,329 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-webpack-support 0.6.0

+
+
+ + +
+
+
+

Super simple Lektor plugin that runs a webpack watcher

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.6.0

+

Author: + + Armin Ronacher + +

+ + +
+

Tags

+
+ + + + before-build-all, + + + Node, + + + npm, + + + official, + + + SCSS, + + + server-spawn, + + + server-stop, + + + webpack, + + and + Yarn + + +

View all tags.

+
+ +
+

Project Description

+ +

lektor-webpack-support

+

This is a plugin for Lektor that adds support for webpack to projects. When +enabled it can build a webpack project from the webpack/ folder into the +asset folder automatically when the server (or build process) is run with +the -f webpack flag.

+

Enabling the Plugin

+

To enable the plugin add this to your project file, run this command while +sitting in your Lektor project directory:

+
lektor plugins add lektor-webpack-support
+
+

Creating a Webpack Project

+

Next you need to create a webpack project. Create a webpack/ folder and +inside that folder create package.json and a webpack.config.js

+

webpack/package.json

+

This file instructs npm which packages we will need. All we need for a +start is to create an almost empty file (name and version fields are mandatory +but not important for functionality, change them to suit your own needs):

+
{
+  "name": "lektor-webpack",
+  "version": "1.0.0",
+  "private": true
+}
+
+

Now we can npm install (or yarn add) the rest:

+
$ cd </path/to/your/lektor/project>/webpack
+$ npm install --save-dev webpack webpack-cli @babel/core sass babel-loader sass-loader css-loader url-loader file-loader mini-css-extract-plugin
+
+

This will install webpack itself together with babel and sass as well as +a bunch of loaders we need for getting all that configured. Because we +created a package.json before and we use --save-dev the dependencies +will be remembered in the package.json file.

+

webpack/webpack.config.js

+

Next up is the webpack config file. Here we will go with a very basic +setup that's good enough to cover most things you will encounter. The +idea is to build the files from webpack/scss and webpack/js into +assets/static/gen so that we can use it even if we do not have webpack +installed for as long as someone else ran it before.

+
const path = require("path");
+const MiniCssExtractPlugin = require("mini-css-extract-plugin");
+
+module.exports = = {
+  entry: {
+    app: "./js/main.js",
+    styles: "./scss/main.scss",
+  },
+  output: {
+    path: path.join(path.dirname(__dirname), "assets", "static", "gen"),
+    filename: "[name].js",
+  },
+  devtool: "source-map",
+  mode: "production",
+  module: {
+    rules: [
+      {
+        test: /\.js$/,
+        exclude: /node_modules/,
+        use: ["babel-loader"],
+      },
+      {
+        test: /\.scss$/,
+        use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
+      },
+      {
+        test: /\.css$/,
+        use: [MiniCssExtractPlugin.loader, "css-loader"],
+      },
+      {
+        test: /\.(woff2?|ttf|eot|svg|png|jpe?g|gif)$/,
+        use: ["file"],
+      },
+    ],
+  },
+  plugins: [new MiniCssExtractPlugin({ filename: "styles.css" })],
+};
+
+

Creating the App

+

Now we can start building our app. We configured at least two files +in webpack: js/main.js and scss/main.scss. Those are the entry +points we need to have. You can create them as empty files in +webpack/js/main.js and webpack/scss/main.scss.

+

Running the Server

+

Now you're ready to go. When you run lektor server webpack will not +run, instead you need to now run it as lektor server -f webpack which +will enable the webpack build. Webpack automatically builds your files +into assets/static/gen and this is where Lektor will then pick up the +files. This is done so that you can ship the webpack generated assets +to others that do not have webpack installed which simplifies using a +Lektor website that uses webpack.

+

Manual Builds

+

To manually trigger a build that also invokes webpack you can use +lektor build -f webpack.

+

Including The Files

+

Now you need to include the files in your template. This will do it:

+
<link rel="stylesheet" href="{{ '/static/gen/styles.css'|asseturl }}">
+<script type=text/javascript src="{{ '/static/gen/app.js'|asseturl }}" charset="utf-8"></script>
+
+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/lektor-yandex-metrica/index.html b/plugins/lektor-yandex-metrica/index.html new file mode 100644 index 00000000..618d0261 --- /dev/null +++ b/plugins/lektor-yandex-metrica/index.html @@ -0,0 +1,237 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ + + + + + + + +
+
+
+

Plugin – lektor-yandex-metrica 0.1.2

+
+
+ + +
+
+
+

Adds support for Yandex Metrica to Lektor CMS

+

+
+ + +
+
+

Project links

+ + + +
+

GitHub Statistics

+
+ + + +
+

Meta

+
+

Version: 0.1.2

+

Author: + + Alex Khomchenko + +

+ + +
+

Tags

+
+ + + + analytics, + + + Jinja globals, + + + setup-env, + + and + Yandex Metrica + + +

View all tags.

+
+ +
+

Project Description

+ +

This plugin adds support for Yandex Metrica +to Lektor CMS

+
+

Enabling the Plugin

+
lektor plugins add lektor-yandex-metrica
+
+
+
+

Configuring the Plugin

+

Just create a file named yandex-metrica.ini in your configs/ folder and configure id key with the provided counter id:

+
id = YOUR_COUNTER_ID
+
+
+
+

In Templates

+

Now you can add a Yandex Metrica counter to any of your templates by just using the generate_yandex_metrica function in its tag as below.

+
{{ generate_yandex_metrica() }}
+
+
+ + + + +
+

Comments

+ +
+ + + +
+ +
+
+
+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/AWS/index.html b/plugins/tag/AWS/index.html new file mode 100644 index 00000000..33413134 --- /dev/null +++ b/plugins/tag/AWS/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: AWS

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ + + +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/AsciiDoc/index.html b/plugins/tag/AsciiDoc/index.html new file mode 100644 index 00000000..3d226d3b --- /dev/null +++ b/plugins/tag/AsciiDoc/index.html @@ -0,0 +1,176 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: AsciiDoc

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • asciidoc: Adds AsciiDoc field type to Lektor.
  • + + + + + + + + +
  • asciidoctor: Adds AsciiDoc field type to Lektor.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/Atom/index.html b/plugins/tag/Atom/index.html new file mode 100644 index 00000000..9d323392 --- /dev/null +++ b/plugins/tag/Atom/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: Atom

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • atom: Lektor plugin that generates Atom feeds.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/Babel/index.html b/plugins/tag/Babel/index.html new file mode 100644 index 00000000..64635226 --- /dev/null +++ b/plugins/tag/Babel/index.html @@ -0,0 +1,176 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: Babel

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • i18n: Use GetText .PO files to translate your site content.
  • + + + + + + + + +
  • npm-support: Adds support for using npm/yarn to build assets in Lektor using tools such as Parcel, webpack, etc.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/Browserify/index.html b/plugins/tag/Browserify/index.html new file mode 100644 index 00000000..ecd4cc2b --- /dev/null +++ b/plugins/tag/Browserify/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: Browserify

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • npm-support: Adds support for using npm/yarn to build assets in Lektor using tools such as Parcel, webpack, etc.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/CSS/index.html b/plugins/tag/CSS/index.html new file mode 100644 index 00000000..a8eac2ca --- /dev/null +++ b/plugins/tag/CSS/index.html @@ -0,0 +1,176 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: CSS

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • gulp: A simple Lektor plugin for gulp
  • + + + + + + + + +
  • minify: Minify build artifacts during the Lektor build process
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/CloudFront/index.html b/plugins/tag/CloudFront/index.html new file mode 100644 index 00000000..d7d4512a --- /dev/null +++ b/plugins/tag/CloudFront/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: CloudFront

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ + + +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/Creative-Commons/index.html b/plugins/tag/Creative-Commons/index.html new file mode 100644 index 00000000..bf43e637 --- /dev/null +++ b/plugins/tag/Creative-Commons/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: Creative Commons

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • creative-commons: Lektor plugin to add Creative Commons license to your pages
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/Disqus/index.html b/plugins/tag/Disqus/index.html new file mode 100644 index 00000000..fd4c6d24 --- /dev/null +++ b/plugins/tag/Disqus/index.html @@ -0,0 +1,168 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: Disqus

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * disqus-comments: Embed Disqus comments into your website.
  • + + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/GetText/index.html b/plugins/tag/GetText/index.html new file mode 100644 index 00000000..c5dfed8d --- /dev/null +++ b/plugins/tag/GetText/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: GetText

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • i18n: Use GetText .PO files to translate your site content.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/GitHub/index.html b/plugins/tag/GitHub/index.html new file mode 100644 index 00000000..fe987bb6 --- /dev/null +++ b/plugins/tag/GitHub/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: GitHub

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • github-repos: Fetches your GitHub repos for display in Lektor templates
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/Google-Analytics/index.html b/plugins/tag/Google-Analytics/index.html new file mode 100644 index 00000000..0d6b36a2 --- /dev/null +++ b/plugins/tag/Google-Analytics/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: Google Analytics

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • google-analytics: Adds support for Google analytics to Lektor CMS
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/HTML/index.html b/plugins/tag/HTML/index.html new file mode 100644 index 00000000..76bcc665 --- /dev/null +++ b/plugins/tag/HTML/index.html @@ -0,0 +1,203 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: HTML

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • gulp: A simple Lektor plugin for gulp
  • + + + + + + + + +
  • htmlmin: HTML minifier for Lektor. Based on htmlmin.
  • + + + + + + + + +
  • minify: Minify build artifacts during the Lektor build process
  • + + + + + + + + +
  • scss: Lektor plugin to compile css out of sass - based on libsass
  • + + + + + + + + +
  • strip-html-tags: Strip HTML tags, effectively turning HTML into plain text.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/JavaScript/index.html b/plugins/tag/JavaScript/index.html new file mode 100644 index 00000000..a83e5b3f --- /dev/null +++ b/plugins/tag/JavaScript/index.html @@ -0,0 +1,176 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: JavaScript

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • gulp: A simple Lektor plugin for gulp
  • + + + + + + + + +
  • minify: Minify build artifacts during the Lektor build process
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/Jinja-filters/index.html b/plugins/tag/Jinja-filters/index.html new file mode 100644 index 00000000..fd02f232 --- /dev/null +++ b/plugins/tag/Jinja-filters/index.html @@ -0,0 +1,230 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: Jinja filters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • limit-dependencies: Lektor plugin to limit dependencies created by queries
  • + + + + + + + + +
  • markdown-excerpt: Adds filter for Markdown body excerpt.
  • + + + + + + + + +
  • natural-language: Adds NLTK based template filters.
  • + + + + + + + + +
  • root-relative-path: Root relative path plugin for Lektor
  • + + + + + + + + +
  • shortcodes: Allows you to use shortcodes (something like tags) in your model fields.
  • + + + + + + + + +
  • slugify: Lektor plugin that adds a slugify Jinja filter.
  • + + + + + + + + +
  • strip-html-tags: Strip HTML tags, effectively turning HTML into plain text.
  • + + + + + + + + +
  • webdav: Lektor plugin to get a list of files from a WebDAV server
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/Jinja-globals/index.html b/plugins/tag/Jinja-globals/index.html new file mode 100644 index 00000000..c00944fe --- /dev/null +++ b/plugins/tag/Jinja-globals/index.html @@ -0,0 +1,221 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: Jinja globals

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • bibtex-support: Bibtex file support to easily include publication lists.
  • + + + + + + + + +
  • citation: This Plugin should extend lektor with APA-styled citations using bibtex files. It was based on the known lektor-bibtex-support plugin by arunpersaud.
  • + + + + + + + + +
  • creative-commons: Lektor plugin to add Creative Commons license to your pages
  • + + + + + + + + +
  • google-analytics: Adds support for Google analytics to Lektor CMS
  • + + + + + + + + +
  • read-full-post: Allows blog listing posts to be shortened with a link to the full post.
  • + + + + + + + + +
  • webdav: Lektor plugin to get a list of files from a WebDAV server
  • + + + + + + + + +
  • yandex-metrica: Adds support for Yandex Metrica to Lektor CMS
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/Jinja/index.html b/plugins/tag/Jinja/index.html new file mode 100644 index 00000000..d36c5727 --- /dev/null +++ b/plugins/tag/Jinja/index.html @@ -0,0 +1,176 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: Jinja

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • expression-type: Add jinja-evaluated types to Lektor
  • + + + + + + + + +
  • jinja-content: Render content fields with Jinja2.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/LaTeX/index.html b/plugins/tag/LaTeX/index.html new file mode 100644 index 00000000..bf61e776 --- /dev/null +++ b/plugins/tag/LaTeX/index.html @@ -0,0 +1,176 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: LaTeX

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • bibtex-support: Bibtex file support to easily include publication lists.
  • + + + + + + + + +
  • citation: This Plugin should extend lektor with APA-styled citations using bibtex files. It was based on the known lektor-bibtex-support plugin by arunpersaud.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/Licensing/index.html b/plugins/tag/Licensing/index.html new file mode 100644 index 00000000..c53ee84b --- /dev/null +++ b/plugins/tag/Licensing/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: Licensing

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • creative-commons: Lektor plugin to add Creative Commons license to your pages
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/Markdown/index.html b/plugins/tag/Markdown/index.html new file mode 100644 index 00000000..f767bd38 --- /dev/null +++ b/plugins/tag/Markdown/index.html @@ -0,0 +1,250 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: Markdown

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * markdown-admonition: Adds basic admonition tag support to Markdown.
  • + + + + + + + + + + + +
  • * markdown-header-anchors: Lektor plugin that adds anchors and table of contents to markdown headers.
  • + + + + + + + + + + + +
  • * markdown-highlighter: Lektor plugin that adds syntax highlighting for markdown blocks with Pygments.
  • + + + --- + + + + + + + + + + +
  • jinja-content: Render content fields with Jinja2.
  • + + + + + + + + +
  • markdown-excerpt: Adds filter for Markdown body excerpt.
  • + + + + + + + + +
  • nofollow: Easily create nofollow links in Markdown.
  • + + + + + + + + +
  • pythonmarkdown: Add pythonmarkdownn field type to Lektor to make use of python-markdown as a renderer.
  • + + + + + + + + +
  • read-full-post: Allows blog listing posts to be shortened with a link to the full post.
  • + + + + + + + + +
  • shortcodes: Allows you to use shortcodes (something like tags) in your model fields.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/NLTK/index.html b/plugins/tag/NLTK/index.html new file mode 100644 index 00000000..94a7c4a2 --- /dev/null +++ b/plugins/tag/NLTK/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: NLTK

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ + + +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/Netlify/index.html b/plugins/tag/Netlify/index.html new file mode 100644 index 00000000..c239f4bb --- /dev/null +++ b/plugins/tag/Netlify/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: Netlify

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • netlify: Allows you to publish your lektor website to netlify easily.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/Node/index.html b/plugins/tag/Node/index.html new file mode 100644 index 00000000..7f3f389b --- /dev/null +++ b/plugins/tag/Node/index.html @@ -0,0 +1,181 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: Node

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * webpack-support: Super simple Lektor plugin that runs a webpack watcher
  • + + + --- + + + + + + + + + + +
  • npm-support: Adds support for using npm/yarn to build assets in Lektor using tools such as Parcel, webpack, etc.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/Parcel/index.html b/plugins/tag/Parcel/index.html new file mode 100644 index 00000000..88b089c3 --- /dev/null +++ b/plugins/tag/Parcel/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: Parcel

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • npm-support: Adds support for using npm/yarn to build assets in Lektor using tools such as Parcel, webpack, etc.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/Pygments/index.html b/plugins/tag/Pygments/index.html new file mode 100644 index 00000000..db277d39 --- /dev/null +++ b/plugins/tag/Pygments/index.html @@ -0,0 +1,168 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: Pygments

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * markdown-highlighter: Lektor plugin that adds syntax highlighting for markdown blocks with Pygments.
  • + + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/Qiniu/index.html b/plugins/tag/Qiniu/index.html new file mode 100644 index 00000000..8241561a --- /dev/null +++ b/plugins/tag/Qiniu/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: Qiniu

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • qiniu: Publish to Qiniu Cloud buckets and refresh the CDN cache.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/RCSSmin/index.html b/plugins/tag/RCSSmin/index.html new file mode 100644 index 00000000..4e6f81ff --- /dev/null +++ b/plugins/tag/RCSSmin/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: RCSSmin

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • minify: Minify build artifacts during the Lektor build process
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/RSS/index.html b/plugins/tag/RSS/index.html new file mode 100644 index 00000000..aa65005c --- /dev/null +++ b/plugins/tag/RSS/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: RSS

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • atom: Lektor plugin that generates Atom feeds.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/S3/index.html b/plugins/tag/S3/index.html new file mode 100644 index 00000000..261c244a --- /dev/null +++ b/plugins/tag/S3/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: S3

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ + + +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/SASS/index.html b/plugins/tag/SASS/index.html new file mode 100644 index 00000000..6fbc5277 --- /dev/null +++ b/plugins/tag/SASS/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: SASS

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • scsscompile: SASS compiler for Lektor, thats based on libsass.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/SCSS/index.html b/plugins/tag/SCSS/index.html new file mode 100644 index 00000000..369b253d --- /dev/null +++ b/plugins/tag/SCSS/index.html @@ -0,0 +1,190 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: SCSS

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * webpack-support: Super simple Lektor plugin that runs a webpack watcher
  • + + + --- + + + + + + + + + + +
  • scss: Lektor plugin to compile css out of sass - based on libsass
  • + + + + + + + + +
  • scsscompile: SASS compiler for Lektor, thats based on libsass.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/Sass/index.html b/plugins/tag/Sass/index.html new file mode 100644 index 00000000..19dc7678 --- /dev/null +++ b/plugins/tag/Sass/index.html @@ -0,0 +1,185 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: Sass

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • npm-support: Adds support for using npm/yarn to build assets in Lektor using tools such as Parcel, webpack, etc.
  • + + + + + + + + +
  • scss: Lektor plugin to compile css out of sass - based on libsass
  • + + + + + + + + +
  • scsscompile: SASS compiler for Lektor, thats based on libsass.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/Surge/index.html b/plugins/tag/Surge/index.html new file mode 100644 index 00000000..6cb6f7c8 --- /dev/null +++ b/plugins/tag/Surge/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: Surge

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • surge: Lektor plugin to publish your site to surge.sh
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/WebDAV/index.html b/plugins/tag/WebDAV/index.html new file mode 100644 index 00000000..5b27173b --- /dev/null +++ b/plugins/tag/WebDAV/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: WebDAV

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • webdav: Lektor plugin to get a list of files from a WebDAV server
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/Yandex-Metrica/index.html b/plugins/tag/Yandex-Metrica/index.html new file mode 100644 index 00000000..b634fdbb --- /dev/null +++ b/plugins/tag/Yandex-Metrica/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: Yandex Metrica

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • yandex-metrica: Adds support for Yandex Metrica to Lektor CMS
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/Yarn/index.html b/plugins/tag/Yarn/index.html new file mode 100644 index 00000000..48a0eb54 --- /dev/null +++ b/plugins/tag/Yarn/index.html @@ -0,0 +1,181 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: Yarn

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * webpack-support: Super simple Lektor plugin that runs a webpack watcher
  • + + + --- + + + + + + + + + + +
  • npm-support: Adds support for using npm/yarn to build assets in Lektor using tools such as Parcel, webpack, etc.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/admonition/index.html b/plugins/tag/admonition/index.html new file mode 100644 index 00000000..804ad79f --- /dev/null +++ b/plugins/tag/admonition/index.html @@ -0,0 +1,168 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: admonition

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ + + +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/after-build-all/index.html b/plugins/tag/after-build-all/index.html new file mode 100644 index 00000000..f6d0bc6f --- /dev/null +++ b/plugins/tag/after-build-all/index.html @@ -0,0 +1,191 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: after-build-all

+ + + + + +

+ This is an event emitted by Lektor for plugins to hook. + The following plugins hook this event. + Take a look at their source code to see how they work! +

+

+ Intro to Plugins + || + Plugin Commands + || + Plugin API + || + This Event +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • htmlmin: HTML minifier for Lektor. Based on htmlmin.
  • + + + + + + + + +
  • i18n: Use GetText .PO files to translate your site content.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/after-build/index.html b/plugins/tag/after-build/index.html new file mode 100644 index 00000000..1b193a13 --- /dev/null +++ b/plugins/tag/after-build/index.html @@ -0,0 +1,191 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: after-build

+ + + +

+ This is an event emitted by Lektor for plugins to hook. + The following plugins hook this event. + Take a look at their source code to see how they work! +

+

+ Intro to Plugins + || + Plugin Commands + || + Plugin API + || + This Event +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • i18n: Use GetText .PO files to translate your site content.
  • + + + + + + + + +
  • minify: Minify build artifacts during the Lektor build process
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/alternatives/index.html b/plugins/tag/alternatives/index.html new file mode 100644 index 00000000..98a73d7f --- /dev/null +++ b/plugins/tag/alternatives/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: alternatives

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • i18n: Use GetText .PO files to translate your site content.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/analytics/index.html b/plugins/tag/analytics/index.html new file mode 100644 index 00000000..7fcd741b --- /dev/null +++ b/plugins/tag/analytics/index.html @@ -0,0 +1,176 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: analytics

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • google-analytics: Adds support for Google analytics to Lektor CMS
  • + + + + + + + + +
  • yandex-metrica: Adds support for Yandex Metrica to Lektor CMS
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/anchors/index.html b/plugins/tag/anchors/index.html new file mode 100644 index 00000000..d9c5d096 --- /dev/null +++ b/plugins/tag/anchors/index.html @@ -0,0 +1,168 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: anchors

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * markdown-header-anchors: Lektor plugin that adds anchors and table of contents to markdown headers.
  • + + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/before-build-all/index.html b/plugins/tag/before-build-all/index.html new file mode 100644 index 00000000..e5dd3ed8 --- /dev/null +++ b/plugins/tag/before-build-all/index.html @@ -0,0 +1,241 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: before-build-all

+ + + + + + + + + + + +

+ This is an event emitted by Lektor for plugins to hook. + The following plugins hook this event. + Take a look at their source code to see how they work! +

+

+ Intro to Plugins + || + Plugin Commands + || + Plugin API + || + This Event +

+ + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * webpack-support: Super simple Lektor plugin that runs a webpack watcher
  • + + + --- + + + + + + + + + + +
  • gulp: A simple Lektor plugin for gulp
  • + + + + + + + + +
  • i18n: Use GetText .PO files to translate your site content.
  • + + + + + + + + +
  • make: Run make lektor for custom build systems.
  • + + + + + + + + +
  • npm-support: Adds support for using npm/yarn to build assets in Lektor using tools such as Parcel, webpack, etc.
  • + + + + + + + + +
  • scss: Lektor plugin to compile css out of sass - based on libsass
  • + + + + + + + + +
  • scsscompile: SASS compiler for Lektor, thats based on libsass.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/before-build/index.html b/plugins/tag/before-build/index.html new file mode 100644 index 00000000..84d9badc --- /dev/null +++ b/plugins/tag/before-build/index.html @@ -0,0 +1,191 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: before-build

+ + + + + + + + + +

+ This is an event emitted by Lektor for plugins to hook. + The following plugins hook this event. + Take a look at their source code to see how they work! +

+

+ Intro to Plugins + || + Plugin Commands + || + Plugin API + || + This Event +

+ + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • i18n: Use GetText .PO files to translate your site content.
  • + + + + + + + + +
  • index-pages: Lektor plugin to generate blog-like index pages
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/bibliography/index.html b/plugins/tag/bibliography/index.html new file mode 100644 index 00000000..5c106cf9 --- /dev/null +++ b/plugins/tag/bibliography/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: bibliography

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • citation: This Plugin should extend lektor with APA-styled citations using bibtex files. It was based on the known lektor-bibtex-support plugin by arunpersaud.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/blog/index.html b/plugins/tag/blog/index.html new file mode 100644 index 00000000..38abd393 --- /dev/null +++ b/plugins/tag/blog/index.html @@ -0,0 +1,190 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: blog

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * disqus-comments: Embed Disqus comments into your website.
  • + + + --- + + + + + + + + + + +
  • index-pages: Lektor plugin to generate blog-like index pages
  • + + + + + + + + +
  • read-full-post: Allows blog listing posts to be shortened with a link to the full post.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/build-optimization/index.html b/plugins/tag/build-optimization/index.html new file mode 100644 index 00000000..0db7acb2 --- /dev/null +++ b/plugins/tag/build-optimization/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: build optimization

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • limit-dependencies: Lektor plugin to limit dependencies created by queries
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/citation/index.html b/plugins/tag/citation/index.html new file mode 100644 index 00000000..dc184a99 --- /dev/null +++ b/plugins/tag/citation/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: citation

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • citation: This Plugin should extend lektor with APA-styled citations using bibtex files. It was based on the known lektor-bibtex-support plugin by arunpersaud.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/comments/index.html b/plugins/tag/comments/index.html new file mode 100644 index 00000000..25f2e298 --- /dev/null +++ b/plugins/tag/comments/index.html @@ -0,0 +1,168 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: comments

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * disqus-comments: Embed Disqus comments into your website.
  • + + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/content/index.html b/plugins/tag/content/index.html new file mode 100644 index 00000000..cde3c5a4 --- /dev/null +++ b/plugins/tag/content/index.html @@ -0,0 +1,185 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: content

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • citation: This Plugin should extend lektor with APA-styled citations using bibtex files. It was based on the known lektor-bibtex-support plugin by arunpersaud.
  • + + + + + + + + +
  • jinja-content: Render content fields with Jinja2.
  • + + + + + + + + +
  • webdav: Lektor plugin to get a list of files from a WebDAV server
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/context/index.html b/plugins/tag/context/index.html new file mode 100644 index 00000000..14f9394f --- /dev/null +++ b/plugins/tag/context/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: context

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • jinja-content: Render content fields with Jinja2.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/django-htmlmin/index.html b/plugins/tag/django-htmlmin/index.html new file mode 100644 index 00000000..02931f01 --- /dev/null +++ b/plugins/tag/django-htmlmin/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: django-htmlmin

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • minify: Minify build artifacts during the Lektor build process
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/field-type/index.html b/plugins/tag/field-type/index.html new file mode 100644 index 00000000..709cf535 --- /dev/null +++ b/plugins/tag/field-type/index.html @@ -0,0 +1,212 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: field type

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • asciidoc: Adds AsciiDoc field type to Lektor.
  • + + + + + + + + +
  • asciidoctor: Adds AsciiDoc field type to Lektor.
  • + + + + + + + + +
  • expression-type: Add jinja-evaluated types to Lektor
  • + + + + + + + + +
  • polymorphic-type: Add polymorphic field type to Lektor
  • + + + + + + + + +
  • pythonmarkdown: Add pythonmarkdownn field type to Lektor to make use of python-markdown as a renderer.
  • + + + + + + + + +
  • rst: Adds reStructuredText support to Lektor.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/git/index.html b/plugins/tag/git/index.html new file mode 100644 index 00000000..fdf3f323 --- /dev/null +++ b/plugins/tag/git/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: git

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • git-timestamp: Lektor type to deduce page modification time from git
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/google-search/index.html b/plugins/tag/google-search/index.html new file mode 100644 index 00000000..92c7d6a1 --- /dev/null +++ b/plugins/tag/google-search/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: google search

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • google-search: Lektor plugin to add google seach to a website
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/gulp/index.html b/plugins/tag/gulp/index.html new file mode 100644 index 00000000..e156ebbd --- /dev/null +++ b/plugins/tag/gulp/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: gulp

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • gulp: A simple Lektor plugin for gulp
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/headers/index.html b/plugins/tag/headers/index.html new file mode 100644 index 00000000..331b338f --- /dev/null +++ b/plugins/tag/headers/index.html @@ -0,0 +1,168 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: headers

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * markdown-header-anchors: Lektor plugin that adds anchors and table of contents to markdown headers.
  • + + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/html-webpack-plugin/index.html b/plugins/tag/html-webpack-plugin/index.html new file mode 100644 index 00000000..ddfb37b4 --- /dev/null +++ b/plugins/tag/html-webpack-plugin/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: html-webpack-plugin

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • webpack-html-helper: Observes the assets directory for html files and copies them into the templates folder.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/htmlmin/index.html b/plugins/tag/htmlmin/index.html new file mode 100644 index 00000000..6f017f10 --- /dev/null +++ b/plugins/tag/htmlmin/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: htmlmin

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • htmlmin: HTML minifier for Lektor. Based on htmlmin.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/i18n/index.html b/plugins/tag/i18n/index.html new file mode 100644 index 00000000..22277684 --- /dev/null +++ b/plugins/tag/i18n/index.html @@ -0,0 +1,176 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: i18n

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • creative-commons: Lektor plugin to add Creative Commons license to your pages
  • + + + + + + + + +
  • i18n: Use GetText .PO files to translate your site content.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/images/index.html b/plugins/tag/images/index.html new file mode 100644 index 00000000..eff7648e --- /dev/null +++ b/plugins/tag/images/index.html @@ -0,0 +1,176 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: images

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • image-resize: Generate JPG and WEBP Images and Thumbnails in predefined sizes.
  • + + + + + + + + +
  • thumbnail-generator: This plugin automatically generates thumbnails for any images in your Lektor content. The difference between this plugin and the `thumbnail` filter is that this is geared towards content, i.e. you don't need to have any references to the images in your templates at all.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/indexing/index.html b/plugins/tag/indexing/index.html new file mode 100644 index 00000000..72978bf4 --- /dev/null +++ b/plugins/tag/indexing/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: indexing

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • index-pages: Lektor plugin to generate blog-like index pages
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/jinja-globals/index.html b/plugins/tag/jinja-globals/index.html new file mode 100644 index 00000000..9fdb7ddb --- /dev/null +++ b/plugins/tag/jinja-globals/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: jinja globals

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • google-search: Lektor plugin to add google seach to a website
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/lektor-plugin/index.html b/plugins/tag/lektor-plugin/index.html new file mode 100644 index 00000000..f086b953 --- /dev/null +++ b/plugins/tag/lektor-plugin/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: lektor plugin

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • google-search: Lektor plugin to add google seach to a website
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/libsass/index.html b/plugins/tag/libsass/index.html new file mode 100644 index 00000000..8f33f45b --- /dev/null +++ b/plugins/tag/libsass/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: libsass

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • scsscompile: SASS compiler for Lektor, thats based on libsass.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/make/index.html b/plugins/tag/make/index.html new file mode 100644 index 00000000..ccf495f6 --- /dev/null +++ b/plugins/tag/make/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: make

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • make: Run make lektor for custom build systems.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/makrdown-meta-init/index.html b/plugins/tag/makrdown-meta-init/index.html new file mode 100644 index 00000000..f2d6d28e --- /dev/null +++ b/plugins/tag/makrdown-meta-init/index.html @@ -0,0 +1,168 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: makrdown-meta-init

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * markdown-header-anchors: Lektor plugin that adds anchors and table of contents to markdown headers.
  • + + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/markdown-config/index.html b/plugins/tag/markdown-config/index.html new file mode 100644 index 00000000..448cf235 --- /dev/null +++ b/plugins/tag/markdown-config/index.html @@ -0,0 +1,229 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: markdown-config

+ + + + + + + + + + + + + + + +

+ This is an event emitted by Lektor for plugins to hook. + The following plugins hook this event. + Take a look at their source code to see how they work! +

+

+ Intro to Plugins + || + Plugin Commands + || + Plugin API + || + This Event +

+ + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * markdown-admonition: Adds basic admonition tag support to Markdown.
  • + + + + + + + + + + + +
  • * markdown-header-anchors: Lektor plugin that adds anchors and table of contents to markdown headers.
  • + + + + + + + + + + + +
  • * markdown-highlighter: Lektor plugin that adds syntax highlighting for markdown blocks with Pygments.
  • + + + --- + + + + + + + + + + +
  • nofollow: Easily create nofollow links in Markdown.
  • + + + + + + + + +
  • shortcodes: Allows you to use shortcodes (something like tags) in your model fields.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/markdown-meta-init/index.html b/plugins/tag/markdown-meta-init/index.html new file mode 100644 index 00000000..3f808eb9 --- /dev/null +++ b/plugins/tag/markdown-meta-init/index.html @@ -0,0 +1,183 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: markdown-meta-init

+ + + + + + + + + + + + + + + + + + + +

+ This is an event emitted by Lektor for plugins to hook. + The following plugins hook this event. + Take a look at their source code to see how they work! +

+

+ Intro to Plugins + || + Plugin Commands + || + Plugin API + || + This Event +

+ + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * markdown-header-anchors: Lektor plugin that adds anchors and table of contents to markdown headers.
  • + + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/markdown-meta-postprocess/index.html b/plugins/tag/markdown-meta-postprocess/index.html new file mode 100644 index 00000000..1e6ca9cc --- /dev/null +++ b/plugins/tag/markdown-meta-postprocess/index.html @@ -0,0 +1,183 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: markdown-meta-postprocess

+ + + + + + + + + + + + + + + + + + + + + +

+ This is an event emitted by Lektor for plugins to hook. + The following plugins hook this event. + Take a look at their source code to see how they work! +

+

+ Intro to Plugins + || + Plugin Commands + || + Plugin API + || + This Event +

+ + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * markdown-header-anchors: Lektor plugin that adds anchors and table of contents to markdown headers.
  • + + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/metadata/index.html b/plugins/tag/metadata/index.html new file mode 100644 index 00000000..61474f6a --- /dev/null +++ b/plugins/tag/metadata/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: metadata

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • git-timestamp: Lektor type to deduce page modification time from git
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/minify/index.html b/plugins/tag/minify/index.html new file mode 100644 index 00000000..0e786d70 --- /dev/null +++ b/plugins/tag/minify/index.html @@ -0,0 +1,185 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: minify

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • htmlmin: HTML minifier for Lektor. Based on htmlmin.
  • + + + + + + + + +
  • minify: Minify build artifacts during the Lektor build process
  • + + + + + + + + +
  • scsscompile: SASS compiler for Lektor, thats based on libsass.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/natural-language/index.html b/plugins/tag/natural-language/index.html new file mode 100644 index 00000000..29938469 --- /dev/null +++ b/plugins/tag/natural-language/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: natural language

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ + + +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/navigation/index.html b/plugins/tag/navigation/index.html new file mode 100644 index 00000000..1dab1f92 --- /dev/null +++ b/plugins/tag/navigation/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: navigation

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ + + +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/nofollow-links/index.html b/plugins/tag/nofollow-links/index.html new file mode 100644 index 00000000..1955e67b --- /dev/null +++ b/plugins/tag/nofollow-links/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: nofollow links

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • nofollow: Easily create nofollow links in Markdown.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/npm/index.html b/plugins/tag/npm/index.html new file mode 100644 index 00000000..abe5804c --- /dev/null +++ b/plugins/tag/npm/index.html @@ -0,0 +1,181 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: npm

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * webpack-support: Super simple Lektor plugin that runs a webpack watcher
  • + + + --- + + + + + + + + + + +
  • npm-support: Adds support for using npm/yarn to build assets in Lektor using tools such as Parcel, webpack, etc.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/official/index.html b/plugins/tag/official/index.html new file mode 100644 index 00000000..517519a4 --- /dev/null +++ b/plugins/tag/official/index.html @@ -0,0 +1,216 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: official

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * disqus-comments: Embed Disqus comments into your website.
  • + + + + + + + + + + + +
  • * markdown-admonition: Adds basic admonition tag support to Markdown.
  • + + + + + + + + + + + +
  • * markdown-header-anchors: Lektor plugin that adds anchors and table of contents to markdown headers.
  • + + + + + + + + + + + +
  • * markdown-highlighter: Lektor plugin that adds syntax highlighting for markdown blocks with Pygments.
  • + + + + + + + + + + + +
  • * webpack-support: Super simple Lektor plugin that runs a webpack watcher
  • + + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/page-generation/index.html b/plugins/tag/page-generation/index.html new file mode 100644 index 00000000..7564290f --- /dev/null +++ b/plugins/tag/page-generation/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: page generation

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • tags: Lektor plugin to add tags.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/process-template-context/index.html b/plugins/tag/process-template-context/index.html new file mode 100644 index 00000000..6a3e7575 --- /dev/null +++ b/plugins/tag/process-template-context/index.html @@ -0,0 +1,191 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: process-template-context

+ + + + + + + + + + + + + + + + + + + + + + + +

+ This is an event emitted by Lektor for plugins to hook. + The following plugins hook this event. + Take a look at their source code to see how they work! +

+

+ Intro to Plugins + || + Plugin Commands + || + Plugin API + || + This Event +

+ + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • github-repos: Fetches your GitHub repos for display in Lektor templates
  • + + + + + + + + +
  • jinja-content: Render content fields with Jinja2.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/publisher/index.html b/plugins/tag/publisher/index.html new file mode 100644 index 00000000..78c45c7b --- /dev/null +++ b/plugins/tag/publisher/index.html @@ -0,0 +1,194 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: publisher

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • netlify: Allows you to publish your lektor website to netlify easily.
  • + + + + + + + + +
  • qiniu: Publish to Qiniu Cloud buckets and refresh the CDN cache.
  • + + + + + + + + +
  • s3: Publish to S3 buckets and Cloudfront.
  • + + + + + + + + +
  • surge: Lektor plugin to publish your site to surge.sh
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/python-slugify/index.html b/plugins/tag/python-slugify/index.html new file mode 100644 index 00000000..57cc315f --- /dev/null +++ b/plugins/tag/python-slugify/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: python-slugify

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • slugify: Lektor plugin that adds a slugify Jinja filter.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/rCSSmin/index.html b/plugins/tag/rCSSmin/index.html new file mode 100644 index 00000000..9e404941 --- /dev/null +++ b/plugins/tag/rCSSmin/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: rCSSmin

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • minify: Minify build artifacts during the Lektor build process
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/rJSmin/index.html b/plugins/tag/rJSmin/index.html new file mode 100644 index 00000000..c0c484bd --- /dev/null +++ b/plugins/tag/rJSmin/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: rJSmin

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • minify: Minify build artifacts during the Lektor build process
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/reStructuredText/index.html b/plugins/tag/reStructuredText/index.html new file mode 100644 index 00000000..f202df45 --- /dev/null +++ b/plugins/tag/reStructuredText/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: reStructuredText

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • rst: Adds reStructuredText support to Lektor.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/remote-content/index.html b/plugins/tag/remote-content/index.html new file mode 100644 index 00000000..97b21dc2 --- /dev/null +++ b/plugins/tag/remote-content/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: remote content

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • webdav: Lektor plugin to get a list of files from a WebDAV server
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/sCSS/index.html b/plugins/tag/sCSS/index.html new file mode 100644 index 00000000..472407c6 --- /dev/null +++ b/plugins/tag/sCSS/index.html @@ -0,0 +1,168 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: sCSS

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * webpack-support: Super simple Lektor plugin that runs a webpack watcher
  • + + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/sass/index.html b/plugins/tag/sass/index.html new file mode 100644 index 00000000..6695f342 --- /dev/null +++ b/plugins/tag/sass/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: sass

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • scss: Lektor plugin to compile css out of sass - based on libsass
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/scss/index.html b/plugins/tag/scss/index.html new file mode 100644 index 00000000..48911d9f --- /dev/null +++ b/plugins/tag/scss/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: scss

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • scss: Lektor plugin to compile css out of sass - based on libsass
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/search-engine/index.html b/plugins/tag/search-engine/index.html new file mode 100644 index 00000000..c1ad84c5 --- /dev/null +++ b/plugins/tag/search-engine/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: search engine

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • google-search: Lektor plugin to add google seach to a website
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/search/index.html b/plugins/tag/search/index.html new file mode 100644 index 00000000..bc4eca19 --- /dev/null +++ b/plugins/tag/search/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: search

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • google-search: Lektor plugin to add google seach to a website
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/server-spawn/index.html b/plugins/tag/server-spawn/index.html new file mode 100644 index 00000000..d6c61926 --- /dev/null +++ b/plugins/tag/server-spawn/index.html @@ -0,0 +1,232 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: server-spawn

+ + + + + + + + + + + + + + + + + + + + + + + + + +

+ This is an event emitted by Lektor for plugins to hook. + The following plugins hook this event. + Take a look at their source code to see how they work! +

+

+ Intro to Plugins + || + Plugin Commands + || + Plugin API + || + This Event +

+ + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * webpack-support: Super simple Lektor plugin that runs a webpack watcher
  • + + + --- + + + + + + + + + + +
  • gulp: A simple Lektor plugin for gulp
  • + + + + + + + + +
  • npm-support: Adds support for using npm/yarn to build assets in Lektor using tools such as Parcel, webpack, etc.
  • + + + + + + + + +
  • scss: Lektor plugin to compile css out of sass - based on libsass
  • + + + + + + + + +
  • scsscompile: SASS compiler for Lektor, thats based on libsass.
  • + + + + + + + + +
  • webpack-html-helper: Observes the assets directory for html files and copies them into the templates folder.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/server-stop/index.html b/plugins/tag/server-stop/index.html new file mode 100644 index 00000000..15e91579 --- /dev/null +++ b/plugins/tag/server-stop/index.html @@ -0,0 +1,232 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: server-stop

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ This is an event emitted by Lektor for plugins to hook. + The following plugins hook this event. + Take a look at their source code to see how they work! +

+

+ Intro to Plugins + || + Plugin Commands + || + Plugin API + || + This Event +

+ + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * webpack-support: Super simple Lektor plugin that runs a webpack watcher
  • + + + --- + + + + + + + + + + +
  • gulp: A simple Lektor plugin for gulp
  • + + + + + + + + +
  • npm-support: Adds support for using npm/yarn to build assets in Lektor using tools such as Parcel, webpack, etc.
  • + + + + + + + + +
  • scss: Lektor plugin to compile css out of sass - based on libsass
  • + + + + + + + + +
  • scsscompile: SASS compiler for Lektor, thats based on libsass.
  • + + + + + + + + +
  • webpack-html-helper: Observes the assets directory for html files and copies them into the templates folder.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/setup-env/index.html b/plugins/tag/setup-env/index.html new file mode 100644 index 00000000..c0fbe862 --- /dev/null +++ b/plugins/tag/setup-env/index.html @@ -0,0 +1,487 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: setup-env

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ This is an event emitted by Lektor for plugins to hook. + The following plugins hook this event. + Take a look at their source code to see how they work! +

+

+ Intro to Plugins + || + Plugin Commands + || + Plugin API + || + This Event +

+ + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * disqus-comments: Embed Disqus comments into your website.
  • + + + + + + + + + + + +
  • * markdown-highlighter: Lektor plugin that adds syntax highlighting for markdown blocks with Pygments.
  • + + + --- + + + + + + + + + + +
  • asciidoc: Adds AsciiDoc field type to Lektor.
  • + + + + + + + + +
  • asciidoctor: Adds AsciiDoc field type to Lektor.
  • + + + + + + + + +
  • atom: Lektor plugin that generates Atom feeds.
  • + + + + + + + + +
  • bibtex-support: Bibtex file support to easily include publication lists.
  • + + + + + + + + +
  • citation: This Plugin should extend lektor with APA-styled citations using bibtex files. It was based on the known lektor-bibtex-support plugin by arunpersaud.
  • + + + + + + + + +
  • creative-commons: Lektor plugin to add Creative Commons license to your pages
  • + + + + + + + + +
  • expression-type: Add jinja-evaluated types to Lektor
  • + + + + + + + + +
  • git-timestamp: Lektor type to deduce page modification time from git
  • + + + + + + + + +
  • google-analytics: Adds support for Google analytics to Lektor CMS
  • + + + + + + + + +
  • google-search: Lektor plugin to add google seach to a website
  • + + + + + + + + +
  • i18n: Use GetText .PO files to translate your site content.
  • + + + + + + + + +
  • index-pages: Lektor plugin to generate blog-like index pages
  • + + + + + + + + +
  • limit-dependencies: Lektor plugin to limit dependencies created by queries
  • + + + + + + + + +
  • markdown-excerpt: Adds filter for Markdown body excerpt.
  • + + + + + + + + +
  • minify: Minify build artifacts during the Lektor build process
  • + + + + + + + + +
  • natural-language: Adds NLTK based template filters.
  • + + + + + + + + +
  • netlify: Allows you to publish your lektor website to netlify easily.
  • + + + + + + + + +
  • polymorphic-type: Add polymorphic field type to Lektor
  • + + + + + + + + +
  • pythonmarkdown: Add pythonmarkdownn field type to Lektor to make use of python-markdown as a renderer.
  • + + + + + + + + +
  • qiniu: Publish to Qiniu Cloud buckets and refresh the CDN cache.
  • + + + + + + + + +
  • read-full-post: Allows blog listing posts to be shortened with a link to the full post.
  • + + + + + + + + +
  • root-relative-path: Root relative path plugin for Lektor
  • + + + + + + + + +
  • rst: Adds reStructuredText support to Lektor.
  • + + + + + + + + +
  • s3: Publish to S3 buckets and Cloudfront.
  • + + + + + + + + +
  • shortcodes: Allows you to use shortcodes (something like tags) in your model fields.
  • + + + + + + + + +
  • slugify: Lektor plugin that adds a slugify Jinja filter.
  • + + + + + + + + +
  • strip-html-tags: Strip HTML tags, effectively turning HTML into plain text.
  • + + + + + + + + +
  • surge: Lektor plugin to publish your site to surge.sh
  • + + + + + + + + +
  • tags: Lektor plugin to add tags.
  • + + + + + + + + +
  • tawk: Embed Tawk Live Chat into your website.
  • + + + + + + + + +
  • webdav: Lektor plugin to get a list of files from a WebDAV server
  • + + + + + + + + +
  • yandex-metrica: Adds support for Yandex Metrica to Lektor CMS
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/shortcodes/index.html b/plugins/tag/shortcodes/index.html new file mode 100644 index 00000000..2301085c --- /dev/null +++ b/plugins/tag/shortcodes/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: shortcodes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • shortcodes: Allows you to use shortcodes (something like tags) in your model fields.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/slugify/index.html b/plugins/tag/slugify/index.html new file mode 100644 index 00000000..4fffad7c --- /dev/null +++ b/plugins/tag/slugify/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: slugify

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • slugify: Lektor plugin that adds a slugify Jinja filter.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/syntax-highlighting/index.html b/plugins/tag/syntax-highlighting/index.html new file mode 100644 index 00000000..bae863af --- /dev/null +++ b/plugins/tag/syntax-highlighting/index.html @@ -0,0 +1,168 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: syntax highlighting

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * markdown-highlighter: Lektor plugin that adds syntax highlighting for markdown blocks with Pygments.
  • + + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/table-of-contents/index.html b/plugins/tag/table-of-contents/index.html new file mode 100644 index 00000000..d657980c --- /dev/null +++ b/plugins/tag/table-of-contents/index.html @@ -0,0 +1,168 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: table of contents

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * markdown-header-anchors: Lektor plugin that adds anchors and table of contents to markdown headers.
  • + + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/tags/index.html b/plugins/tag/tags/index.html new file mode 100644 index 00000000..787fef1b --- /dev/null +++ b/plugins/tag/tags/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: tags

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • tags: Lektor plugin to add tags.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/tawk/index.html b/plugins/tag/tawk/index.html new file mode 100644 index 00000000..c49b0dfb --- /dev/null +++ b/plugins/tag/tawk/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: tawk

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • tawk: Embed Tawk Live Chat into your website.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/templates/index.html b/plugins/tag/templates/index.html new file mode 100644 index 00000000..f6ed995e --- /dev/null +++ b/plugins/tag/templates/index.html @@ -0,0 +1,176 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: templates

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • jinja-content: Render content fields with Jinja2.
  • + + + + + + + + +
  • tawk: Embed Tawk Live Chat into your website.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/thumbnails/index.html b/plugins/tag/thumbnails/index.html new file mode 100644 index 00000000..2159dd85 --- /dev/null +++ b/plugins/tag/thumbnails/index.html @@ -0,0 +1,176 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: thumbnails

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • image-resize: Generate JPG and WEBP Images and Thumbnails in predefined sizes.
  • + + + + + + + + +
  • thumbnail-generator: This plugin automatically generates thumbnails for any images in your Lektor content. The difference between this plugin and the `thumbnail` filter is that this is geared towards content, i.e. you don't need to have any references to the images in your templates at all.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/virtual-paths/index.html b/plugins/tag/virtual-paths/index.html new file mode 100644 index 00000000..f159b040 --- /dev/null +++ b/plugins/tag/virtual-paths/index.html @@ -0,0 +1,176 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: virtual paths

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • atom: Lektor plugin that generates Atom feeds.
  • + + + + + + + + +
  • tags: Lektor plugin to add tags.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/watchdog/index.html b/plugins/tag/watchdog/index.html new file mode 100644 index 00000000..24528a1f --- /dev/null +++ b/plugins/tag/watchdog/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: watchdog

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • webpack-html-helper: Observes the assets directory for html files and copies them into the templates folder.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/webp/index.html b/plugins/tag/webp/index.html new file mode 100644 index 00000000..1a4997c7 --- /dev/null +++ b/plugins/tag/webp/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: webp

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • image-resize: Generate JPG and WEBP Images and Thumbnails in predefined sizes.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/webpack/index.html b/plugins/tag/webpack/index.html new file mode 100644 index 00000000..4d3b46e7 --- /dev/null +++ b/plugins/tag/webpack/index.html @@ -0,0 +1,190 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: webpack

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • * webpack-support: Super simple Lektor plugin that runs a webpack watcher
  • + + + --- + + + + + + + + + + +
  • npm-support: Adds support for using npm/yarn to build assets in Lektor using tools such as Parcel, webpack, etc.
  • + + + + + + + + +
  • webpack-html-helper: Observes the assets directory for html files and copies them into the templates folder.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tag/website/index.html b/plugins/tag/website/index.html new file mode 100644 index 00000000..53bc5d45 --- /dev/null +++ b/plugins/tag/website/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Tag: website

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Plugins:

+

(*) Asterisks denote official plugins.

+
+ +
    + + + + + + + +
  • tawk: Embed Tawk Live Chat into your website.
  • + + +
+ +
+ +

View a list of all Lektor plugin tags here.

+ +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/plugins/tags/index.html b/plugins/tags/index.html new file mode 100644 index 00000000..9d58bc0c --- /dev/null +++ b/plugins/tags/index.html @@ -0,0 +1,345 @@ + + + + + + + + + + tags | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Plugin Tags

+ +

+ This is a list of all tags that Lektor plugins have. + Click on individual tags to see which plugins use that tag. +

+ + +
+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/preview.png b/preview.png new file mode 100644 index 00000000..074989af Binary files /dev/null and b/preview.png differ diff --git a/publish.png b/publish.png new file mode 100644 index 00000000..608277f0 Binary files /dev/null and b/publish.png differ diff --git a/showcase/allnew-selfstudythai/index.html b/showcase/allnew-selfstudythai/index.html new file mode 100644 index 00000000..d30b05cc --- /dev/null +++ b/showcase/allnew-selfstudythai/index.html @@ -0,0 +1,184 @@ + + + + + + + + + + All-New Self Study Thai | Lektor Static Content Management System + + + + +
+ +
+
+ +

All-New Self Study Thai

+
+
+
+

This responsive website offers Thai audio, corresponding transcripts, for news articles from "Voice of America", commonly referred to as VOA.

+

What started out as study tools for myself, I decided that with some extra work could be made useful to others.

+

It's all self study and it's all FREE, though you do need to be able to read Thai to be able to take advantage of this website's content.

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/allnew-selfstudythai/sst_0_frontpage.png b/showcase/allnew-selfstudythai/sst_0_frontpage.png new file mode 100644 index 00000000..965c4ce0 Binary files /dev/null and b/showcase/allnew-selfstudythai/sst_0_frontpage.png differ diff --git a/showcase/allnew-selfstudythai/sst_1_articles.png b/showcase/allnew-selfstudythai/sst_1_articles.png new file mode 100644 index 00000000..b18c9ae3 Binary files /dev/null and b/showcase/allnew-selfstudythai/sst_1_articles.png differ diff --git a/showcase/allnew-selfstudythai/sst_2_article.png b/showcase/allnew-selfstudythai/sst_2_article.png new file mode 100644 index 00000000..181194d4 Binary files /dev/null and b/showcase/allnew-selfstudythai/sst_2_article.png differ diff --git a/showcase/allnew-selfstudythai/sst_3_study.png b/showcase/allnew-selfstudythai/sst_3_study.png new file mode 100644 index 00000000..85a2d309 Binary files /dev/null and b/showcase/allnew-selfstudythai/sst_3_study.png differ diff --git a/showcase/allnew-selfstudythai/sst_3_study@480.png b/showcase/allnew-selfstudythai/sst_3_study@480.png new file mode 100644 index 00000000..f2efcd1f Binary files /dev/null and b/showcase/allnew-selfstudythai/sst_3_study@480.png differ diff --git a/showcase/allnew-selfstudythai/sst_4_footer.png b/showcase/allnew-selfstudythai/sst_4_footer.png new file mode 100644 index 00000000..aaa007ce Binary files /dev/null and b/showcase/allnew-selfstudythai/sst_4_footer.png differ diff --git a/showcase/amin-mesbah/frontpage.png b/showcase/amin-mesbah/frontpage.png new file mode 100644 index 00000000..f033e992 Binary files /dev/null and b/showcase/amin-mesbah/frontpage.png differ diff --git a/showcase/amin-mesbah/frontpage@480.png b/showcase/amin-mesbah/frontpage@480.png new file mode 100644 index 00000000..644f2388 Binary files /dev/null and b/showcase/amin-mesbah/frontpage@480.png differ diff --git a/showcase/amin-mesbah/index.html b/showcase/amin-mesbah/index.html new file mode 100644 index 00000000..3fb4ecdf --- /dev/null +++ b/showcase/amin-mesbah/index.html @@ -0,0 +1,162 @@ + + + + + + + + + + Amin Mesbah | Lektor Static Content Management System + + + + +
+ +
+
+ +

Amin Mesbah

+
+
+
+

This is my simple personal blog. I write about programming. I also recently +added a photography section, for which I wrote a little Lektor plugin that +fetches image links off my WebDAV file host.

+

I've found Lektor to be delightfully efficient and extensible, and a pleasure to +work with. The source files for my site can be found on GitHub.

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/amin-mesbah/photography.png b/showcase/amin-mesbah/photography.png new file mode 100644 index 00000000..5389d950 Binary files /dev/null and b/showcase/amin-mesbah/photography.png differ diff --git a/showcase/andrew-shay/1-frontpage.png b/showcase/andrew-shay/1-frontpage.png new file mode 100644 index 00000000..0db23b98 Binary files /dev/null and b/showcase/andrew-shay/1-frontpage.png differ diff --git a/showcase/andrew-shay/1-frontpage@480.png b/showcase/andrew-shay/1-frontpage@480.png new file mode 100644 index 00000000..8a5a8d2f Binary files /dev/null and b/showcase/andrew-shay/1-frontpage@480.png differ diff --git a/showcase/andrew-shay/2-blog.png b/showcase/andrew-shay/2-blog.png new file mode 100644 index 00000000..ae07fdd9 Binary files /dev/null and b/showcase/andrew-shay/2-blog.png differ diff --git a/showcase/andrew-shay/index.html b/showcase/andrew-shay/index.html new file mode 100644 index 00000000..bc581be4 --- /dev/null +++ b/showcase/andrew-shay/index.html @@ -0,0 +1,159 @@ + + + + + + + + + + Andrew Shay | Lektor Static Content Management System + + + + +
+ +
+
+ +

Andrew Shay

+
+
+
+

This is my personal website that I use to showcase my projects and discuss software engineering.

+

View the Sourcecode on GitHub

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/architekten-ronacher/frontpage.jpg b/showcase/architekten-ronacher/frontpage.jpg new file mode 100644 index 00000000..9ee0a0a3 Binary files /dev/null and b/showcase/architekten-ronacher/frontpage.jpg differ diff --git a/showcase/architekten-ronacher/frontpage@480.jpg b/showcase/architekten-ronacher/frontpage@480.jpg new file mode 100644 index 00000000..3df09bba Binary files /dev/null and b/showcase/architekten-ronacher/frontpage@480.jpg differ diff --git a/showcase/architekten-ronacher/index.html b/showcase/architekten-ronacher/index.html new file mode 100644 index 00000000..51590e38 --- /dev/null +++ b/showcase/architekten-ronacher/index.html @@ -0,0 +1,175 @@ + + + + + + + + + + Architekten Ronacher | Lektor Static Content Management System + + + + +
+ +
+
+ +

Architekten Ronacher

+
+
+
+

This website is what originally inspired Lektor. At the center of project was +the idea to bring the photos of the projects in the foreground and to render +them out as full-size images with info text on top and optional additional +project information below the fold.

+

To achieve uniformity between the different projects a predefined structure for +all of them was defined. Editors just upload pictures and fill out the form to +add a new project. Lektor automatically generates out the necessary thumbnails +and builds the overview pages.

+

Minimal use of JavaScript is used to drive the slideshows and the filter on +the overview page.

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/architekten-ronacher/news.jpg b/showcase/architekten-ronacher/news.jpg new file mode 100644 index 00000000..790662cc Binary files /dev/null and b/showcase/architekten-ronacher/news.jpg differ diff --git a/showcase/architekten-ronacher/project.jpg b/showcase/architekten-ronacher/project.jpg new file mode 100644 index 00000000..189ba6b7 Binary files /dev/null and b/showcase/architekten-ronacher/project.jpg differ diff --git a/showcase/atelier-ronacher/flats.jpg b/showcase/atelier-ronacher/flats.jpg new file mode 100644 index 00000000..297f4904 Binary files /dev/null and b/showcase/atelier-ronacher/flats.jpg differ diff --git a/showcase/atelier-ronacher/frontpage.jpg b/showcase/atelier-ronacher/frontpage.jpg new file mode 100644 index 00000000..36a0c553 Binary files /dev/null and b/showcase/atelier-ronacher/frontpage.jpg differ diff --git a/showcase/atelier-ronacher/frontpage@480.jpg b/showcase/atelier-ronacher/frontpage@480.jpg new file mode 100644 index 00000000..c8b4e7ea Binary files /dev/null and b/showcase/atelier-ronacher/frontpage@480.jpg differ diff --git a/showcase/atelier-ronacher/index.html b/showcase/atelier-ronacher/index.html new file mode 100644 index 00000000..054607d0 --- /dev/null +++ b/showcase/atelier-ronacher/index.html @@ -0,0 +1,171 @@ + + + + + + + + + + Atelier Ronacher | Lektor Static Content Management System + + + + +
+ +
+
+ +

Atelier Ronacher

+
+
+
+

Based on the design and general concept behind the website of Architekten +Ronacher a second project was created for a +vacation rental website. It uses Lektor to present itself, the apartments and +the area surrounding it.

+

Because this is for a rental it also embeds external services like Google +Maps and a booking engine.

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/atelier-ronacher/inside.jpg b/showcase/atelier-ronacher/inside.jpg new file mode 100644 index 00000000..43445181 Binary files /dev/null and b/showcase/atelier-ronacher/inside.jpg differ diff --git a/showcase/davidbaumgold/frontpage.png b/showcase/davidbaumgold/frontpage.png new file mode 100644 index 00000000..be3824b4 Binary files /dev/null and b/showcase/davidbaumgold/frontpage.png differ diff --git a/showcase/davidbaumgold/frontpage@480.png b/showcase/davidbaumgold/frontpage@480.png new file mode 100644 index 00000000..649f8b64 Binary files /dev/null and b/showcase/davidbaumgold/frontpage@480.png differ diff --git a/showcase/davidbaumgold/index.html b/showcase/davidbaumgold/index.html new file mode 100644 index 00000000..5f37f4e7 --- /dev/null +++ b/showcase/davidbaumgold/index.html @@ -0,0 +1,154 @@ + + + + + + + + + + David Baumgold | Lektor Static Content Management System + + + + +
+ +
+
+ +

David Baumgold

+
+
+
+

My former website was hand-written HTML files, and quickly proved to be +impossible to maintain. Using Lektor, I rebuilt it using +Bootstrap 4 and +Font Awesome for a simple, maintainable +personal website.

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/eric-ma/frontpage.png b/showcase/eric-ma/frontpage.png new file mode 100644 index 00000000..0b227da1 Binary files /dev/null and b/showcase/eric-ma/frontpage.png differ diff --git a/showcase/eric-ma/frontpage@480.png b/showcase/eric-ma/frontpage@480.png new file mode 100644 index 00000000..3b81d5fe Binary files /dev/null and b/showcase/eric-ma/frontpage@480.png differ diff --git a/showcase/eric-ma/index.html b/showcase/eric-ma/index.html new file mode 100644 index 00000000..25c6ac40 --- /dev/null +++ b/showcase/eric-ma/index.html @@ -0,0 +1,159 @@ + + + + + + + + + + Eric J. Ma | Lektor Static Content Management System + + + + +
+ +
+
+ +

Eric J. Ma

+
+
+
+

I used to maintain a blog on Wordpress, but that got slow for me. +On David Baumgold's suggestion, +I tried out Lektor. +He guided me through the basics of the web, +and now I have a site that I am very extremely happy to maintain. +Lektor's separation of data model, content and templates has made it +a very powerful to create complex content, +but at the same time, +to get a simple website going on which I retain full control +is not difficult at all.

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/eswar-malla/blog.png b/showcase/eswar-malla/blog.png new file mode 100644 index 00000000..693419ec Binary files /dev/null and b/showcase/eswar-malla/blog.png differ diff --git a/showcase/eswar-malla/home_page.png b/showcase/eswar-malla/home_page.png new file mode 100644 index 00000000..efef6e22 Binary files /dev/null and b/showcase/eswar-malla/home_page.png differ diff --git a/showcase/eswar-malla/home_page@480.png b/showcase/eswar-malla/home_page@480.png new file mode 100644 index 00000000..6d070891 Binary files /dev/null and b/showcase/eswar-malla/home_page@480.png differ diff --git a/showcase/eswar-malla/index.html b/showcase/eswar-malla/index.html new file mode 100644 index 00000000..2975e49b --- /dev/null +++ b/showcase/eswar-malla/index.html @@ -0,0 +1,166 @@ + + + + + + + + + + Eswar Malla | Lektor Static Content Management System + + + + +
+ +
+
+ +

Eswar Malla

+
+
+
+

I am using lektor for my personal blog. In the process I also ported a jekyll theme(pixyll) to be used with lektor, which you can find it here and preview here. One of the primary reasons for moving to lektor for me is the admin panel provided.

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/eswar-malla/post.png b/showcase/eswar-malla/post.png new file mode 100644 index 00000000..7127a332 Binary files /dev/null and b/showcase/eswar-malla/post.png differ diff --git a/showcase/frank-tisellano/blog.png b/showcase/frank-tisellano/blog.png new file mode 100644 index 00000000..946f89c5 Binary files /dev/null and b/showcase/frank-tisellano/blog.png differ diff --git a/showcase/frank-tisellano/home.png b/showcase/frank-tisellano/home.png new file mode 100644 index 00000000..358ae689 Binary files /dev/null and b/showcase/frank-tisellano/home.png differ diff --git a/showcase/frank-tisellano/home@480.png b/showcase/frank-tisellano/home@480.png new file mode 100644 index 00000000..67ee4cf8 Binary files /dev/null and b/showcase/frank-tisellano/home@480.png differ diff --git a/showcase/frank-tisellano/index.html b/showcase/frank-tisellano/index.html new file mode 100644 index 00000000..5c849754 --- /dev/null +++ b/showcase/frank-tisellano/index.html @@ -0,0 +1,168 @@ + + + + + + + + + + Frank Tisellano | Lektor Static Content Management System + + + + +
+ +
+
+ +

Frank Tisellano

+
+
+
+

This is my personal website. It includes a simple about page, a blog, and a curated list of interesting links I've come across. I generally link to and blog about product management, marketing, strategy, and design.

+

Links are stored statically in lektor in the same way blog posts are stored, but I wrote a bit of code that syncs those links before lektor deployments from pinboard, where I manage them centrally.

+

The site is hosted on S3 behind Cloudflare, and I use the excellent lektor-s3 plugin to get it there.

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/frank-tisellano/links.png b/showcase/frank-tisellano/links.png new file mode 100644 index 00000000..5df4ff6a Binary files /dev/null and b/showcase/frank-tisellano/links.png differ diff --git a/showcase/freedombox/downloads.png b/showcase/freedombox/downloads.png new file mode 100644 index 00000000..876c75c4 Binary files /dev/null and b/showcase/freedombox/downloads.png differ diff --git a/showcase/freedombox/home.png b/showcase/freedombox/home.png new file mode 100644 index 00000000..910d2a24 Binary files /dev/null and b/showcase/freedombox/home.png differ diff --git a/showcase/freedombox/home@480.png b/showcase/freedombox/home@480.png new file mode 100644 index 00000000..ce0d7a39 Binary files /dev/null and b/showcase/freedombox/home@480.png differ diff --git a/showcase/freedombox/index.html b/showcase/freedombox/index.html new file mode 100644 index 00000000..e78a10ad --- /dev/null +++ b/showcase/freedombox/index.html @@ -0,0 +1,171 @@ + + + + + + + + + + FreedomBox | Lektor Static Content Management System + + + + +
+ +
+
+ +

FreedomBox

+
+
+
+

FreedomBox is a personal server running a free +software operating system, with free applications designed to create and +preserve personal privacy.

+

The official website of the FreedomBox project was created using Lektor. You can +find the source code for the website on Debian +Salsa.

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/freedombox/stable-downloads.png b/showcase/freedombox/stable-downloads.png new file mode 100644 index 00000000..e2b87670 Binary files /dev/null and b/showcase/freedombox/stable-downloads.png differ diff --git a/showcase/happyhols/happyhols1.jpg b/showcase/happyhols/happyhols1.jpg new file mode 100644 index 00000000..da2a9d22 Binary files /dev/null and b/showcase/happyhols/happyhols1.jpg differ diff --git a/showcase/happyhols/happyhols1@480.jpg b/showcase/happyhols/happyhols1@480.jpg new file mode 100644 index 00000000..f78dd099 Binary files /dev/null and b/showcase/happyhols/happyhols1@480.jpg differ diff --git a/showcase/happyhols/happyhols2.png b/showcase/happyhols/happyhols2.png new file mode 100644 index 00000000..55446767 Binary files /dev/null and b/showcase/happyhols/happyhols2.png differ diff --git a/showcase/happyhols/happyhols3.png b/showcase/happyhols/happyhols3.png new file mode 100644 index 00000000..8ef2ae39 Binary files /dev/null and b/showcase/happyhols/happyhols3.png differ diff --git a/showcase/happyhols/happyhols4.png b/showcase/happyhols/happyhols4.png new file mode 100644 index 00000000..8b20ac84 Binary files /dev/null and b/showcase/happyhols/happyhols4.png differ diff --git a/showcase/happyhols/index.html b/showcase/happyhols/index.html new file mode 100644 index 00000000..41c33a22 --- /dev/null +++ b/showcase/happyhols/index.html @@ -0,0 +1,177 @@ + + + + + + + + + + happyhols | Lektor Static Content Management System + + + + +
+ +
+
+ +

happyhols

+
+
+
+

I created this project to learn about Lektor, Markdown, and the Bulma CSS framework. I think they work well together and I had fun making this project. +The site is deployed on Netlify via a GitHub repo. I followed this tutorial to get it set up and working. +The contact form is powered by FormSpree, which is a super easy form solution for static sites.

+

You can view the source code for the site on GitHub.

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/header.jpg b/showcase/header.jpg new file mode 100644 index 00000000..5173842b Binary files /dev/null and b/showcase/header.jpg differ diff --git a/showcase/index.html b/showcase/index.html new file mode 100644 index 00000000..08300f86 --- /dev/null +++ b/showcase/index.html @@ -0,0 +1,460 @@ + + + + + + + + + + Showcase | Lektor Static Content Management System + + + + +
+ + + +
+ + +
+ +

Showcase

+

+ Want to see what Lektor is used for? This should give you a brief overview + of what projects are built on the basis of Lektor. We take good care of + ensuring this list stays up to date by carefully moderating it. +

+ Click any of the showcases to learn a bit more about how it uses Lektor. +

+

+ You want your own website on here? Fork + the Lektor Website Repository on GitHub to add your own project. + Make sure to add screenshots and a description about the project. + The primary screenshot is thumbnailed on this page to 415px wide, and cropped to + 260px tall, and on your site's individual page the larger images are 870px wide. + + We encourage you to add a link to your source code + so that others can learn from your example. + + +

+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/lektor-website/docs.png b/showcase/lektor-website/docs.png new file mode 100644 index 00000000..4c819511 Binary files /dev/null and b/showcase/lektor-website/docs.png differ diff --git a/showcase/lektor-website/downloads.png b/showcase/lektor-website/downloads.png new file mode 100644 index 00000000..438b7d44 Binary files /dev/null and b/showcase/lektor-website/downloads.png differ diff --git a/showcase/lektor-website/frontpage.png b/showcase/lektor-website/frontpage.png new file mode 100644 index 00000000..1255ca39 Binary files /dev/null and b/showcase/lektor-website/frontpage.png differ diff --git a/showcase/lektor-website/frontpage@480.png b/showcase/lektor-website/frontpage@480.png new file mode 100644 index 00000000..705c5250 Binary files /dev/null and b/showcase/lektor-website/frontpage@480.png differ diff --git a/showcase/lektor-website/index.html b/showcase/lektor-website/index.html new file mode 100644 index 00000000..51426d49 --- /dev/null +++ b/showcase/lektor-website/index.html @@ -0,0 +1,169 @@ + + + + + + + + + + Lektor Website | Lektor Static Content Management System + + + + +
+ +
+
+ +

Lektor Website

+
+
+
+

This is the website of the Lektor CMS itself. It's the very website you are +looking at right now. What's special about this one is that its structure +and content is available on GitHub so you can see how it's built.

+

View the Sourcecode on GitHub

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/mark-steve-samson/1-frontpage.jpg b/showcase/mark-steve-samson/1-frontpage.jpg new file mode 100644 index 00000000..b31be4dc Binary files /dev/null and b/showcase/mark-steve-samson/1-frontpage.jpg differ diff --git a/showcase/mark-steve-samson/1-frontpage@480.jpg b/showcase/mark-steve-samson/1-frontpage@480.jpg new file mode 100644 index 00000000..9393dad6 Binary files /dev/null and b/showcase/mark-steve-samson/1-frontpage@480.jpg differ diff --git a/showcase/mark-steve-samson/2-blog.jpg b/showcase/mark-steve-samson/2-blog.jpg new file mode 100644 index 00000000..6e7766a8 Binary files /dev/null and b/showcase/mark-steve-samson/2-blog.jpg differ diff --git a/showcase/mark-steve-samson/index.html b/showcase/mark-steve-samson/index.html new file mode 100644 index 00000000..92e225b0 --- /dev/null +++ b/showcase/mark-steve-samson/index.html @@ -0,0 +1,159 @@ + + + + + + + + + + Mark Steve Samson | Lektor Static Content Management System + + + + +
+ +
+
+ +

Mark Steve Samson

+
+
+
+

This personal homepage was once powered by Jekyll. Porting to Lektor took less than half a day. The Open Source Projects section that used to be filled through XHR is now populated by a Lektor plugin.

+

View the Sourcecode on GitHub

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/pallets-projects/1-home.png b/showcase/pallets-projects/1-home.png new file mode 100644 index 00000000..8415d6a9 Binary files /dev/null and b/showcase/pallets-projects/1-home.png differ diff --git a/showcase/pallets-projects/1-home@480.png b/showcase/pallets-projects/1-home@480.png new file mode 100644 index 00000000..af6be0a4 Binary files /dev/null and b/showcase/pallets-projects/1-home@480.png differ diff --git a/showcase/pallets-projects/2-project.png b/showcase/pallets-projects/2-project.png new file mode 100644 index 00000000..6f945d0b Binary files /dev/null and b/showcase/pallets-projects/2-project.png differ diff --git a/showcase/pallets-projects/3-blog.png b/showcase/pallets-projects/3-blog.png new file mode 100644 index 00000000..3da4353a Binary files /dev/null and b/showcase/pallets-projects/3-blog.png differ diff --git a/showcase/pallets-projects/index.html b/showcase/pallets-projects/index.html new file mode 100644 index 00000000..0290c632 --- /dev/null +++ b/showcase/pallets-projects/index.html @@ -0,0 +1,169 @@ + + + + + + + + + + Pallets Projects | Lektor Static Content Management System + + + + +
+ +
+
+ +

Pallets Projects

+
+
+
+

This is the website of the Pallets Projects - a collection of very popular +Python software development libraries including the Flask web framework, +the Werkzeug WSGI library, the Jinja template engine and more.

+

View the Sourcecode on GitHub

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/playwarwick/1-home.png b/showcase/playwarwick/1-home.png new file mode 100644 index 00000000..464c76d2 Binary files /dev/null and b/showcase/playwarwick/1-home.png differ diff --git a/showcase/playwarwick/1-home@480.png b/showcase/playwarwick/1-home@480.png new file mode 100644 index 00000000..a49e2477 Binary files /dev/null and b/showcase/playwarwick/1-home@480.png differ diff --git a/showcase/playwarwick/2-contact-us.png b/showcase/playwarwick/2-contact-us.png new file mode 100644 index 00000000..2a94f2c6 Binary files /dev/null and b/showcase/playwarwick/2-contact-us.png differ diff --git a/showcase/playwarwick/index.html b/showcase/playwarwick/index.html new file mode 100644 index 00000000..c3eb06fb --- /dev/null +++ b/showcase/playwarwick/index.html @@ -0,0 +1,161 @@ + + + + + + + + + + Playwarwick | Lektor Static Content Management System + + + + +
+ +
+
+ +

Playwarwick

+
+
+
+

Website for Warwick, a terminal-based strategy game.

+

Lektor is used as templating engine and content manager, while Grunt is used +for minification and assets manipulation.

+

View the Sourcecode on GitHub

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/pybee/index.html b/showcase/pybee/index.html new file mode 100644 index 00000000..c5da3beb --- /dev/null +++ b/showcase/pybee/index.html @@ -0,0 +1,159 @@ + + + + + + + + + + BeeWare | Lektor Static Content Management System + + + + +
+ +
+
+ +

BeeWare

+
+
+
+

Python has proven itself as a highly capable language - approachable for newcomers, but powerful in the hands of experts. The BeeWare Project aims to take the power of Python as a language, and use it to enable users of all skill levels to develop applications with native user interfaces. BeeWare allows you to write your app in Python and release it on multiple platforms. No need to rewrite the app in multiple programming languages. It means no issues with build tools, environments, compatibility, etc.

+

You can view the source code for our site here, or view any of our other public repositories over on our GitHub page.

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/pybee/pybee-donate.png b/showcase/pybee/pybee-donate.png new file mode 100644 index 00000000..c06f786e Binary files /dev/null and b/showcase/pybee/pybee-donate.png differ diff --git a/showcase/pybee/pybee-homepage.png b/showcase/pybee/pybee-homepage.png new file mode 100644 index 00000000..3016f02f Binary files /dev/null and b/showcase/pybee/pybee-homepage.png differ diff --git a/showcase/pybee/pybee-homepage@480.png b/showcase/pybee/pybee-homepage@480.png new file mode 100644 index 00000000..d633f793 Binary files /dev/null and b/showcase/pybee/pybee-homepage@480.png differ diff --git a/showcase/pycon-colombia-2018/index.html b/showcase/pycon-colombia-2018/index.html new file mode 100644 index 00000000..8c51465e --- /dev/null +++ b/showcase/pycon-colombia-2018/index.html @@ -0,0 +1,150 @@ + + + + + + + + + + PyCon Colombia 2018 | Lektor Static Content Management System + + + + +
+ +
+
+ +

PyCon Colombia 2018

+
+
+
+

This is the website for the Python Colombia Conference (PyCon Colombia) for the year 2018

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/pycon-colombia-2018/pycon-colombia-2018-landing.png b/showcase/pycon-colombia-2018/pycon-colombia-2018-landing.png new file mode 100644 index 00000000..0f2a9a8e Binary files /dev/null and b/showcase/pycon-colombia-2018/pycon-colombia-2018-landing.png differ diff --git a/showcase/pycon-colombia-2018/pycon-colombia-2018-landing@480.png b/showcase/pycon-colombia-2018/pycon-colombia-2018-landing@480.png new file mode 100644 index 00000000..d754ba22 Binary files /dev/null and b/showcase/pycon-colombia-2018/pycon-colombia-2018-landing@480.png differ diff --git a/showcase/pycon-philippines-2016/01-about.png b/showcase/pycon-philippines-2016/01-about.png new file mode 100644 index 00000000..2fffb647 Binary files /dev/null and b/showcase/pycon-philippines-2016/01-about.png differ diff --git a/showcase/pycon-philippines-2016/01-about@480.png b/showcase/pycon-philippines-2016/01-about@480.png new file mode 100644 index 00000000..8afeb95b Binary files /dev/null and b/showcase/pycon-philippines-2016/01-about@480.png differ diff --git a/showcase/pycon-philippines-2016/02-schedule.png b/showcase/pycon-philippines-2016/02-schedule.png new file mode 100644 index 00000000..015b5be0 Binary files /dev/null and b/showcase/pycon-philippines-2016/02-schedule.png differ diff --git a/showcase/pycon-philippines-2016/03-speakers.png b/showcase/pycon-philippines-2016/03-speakers.png new file mode 100644 index 00000000..ecd2e973 Binary files /dev/null and b/showcase/pycon-philippines-2016/03-speakers.png differ diff --git a/showcase/pycon-philippines-2016/index.html b/showcase/pycon-philippines-2016/index.html new file mode 100644 index 00000000..14da2dec --- /dev/null +++ b/showcase/pycon-philippines-2016/index.html @@ -0,0 +1,166 @@ + + + + + + + + + + PyCon Philippines 2016 | Lektor Static Content Management System + + + + +
+ +
+
+ +

PyCon Philippines 2016

+
+
+
+

We built the PyCon Philippines 2016 event website using Lektor. Speakers, schedule and sponsors were managed using Flow. This allowed easy collaboration for our contributors.

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/taiga-support/frontpage.png b/showcase/taiga-support/frontpage.png new file mode 100644 index 00000000..42243fcd Binary files /dev/null and b/showcase/taiga-support/frontpage.png differ diff --git a/showcase/taiga-support/frontpage@480.png b/showcase/taiga-support/frontpage@480.png new file mode 100644 index 00000000..80b966c2 Binary files /dev/null and b/showcase/taiga-support/frontpage@480.png differ diff --git a/showcase/taiga-support/index.html b/showcase/taiga-support/index.html new file mode 100644 index 00000000..d458676b --- /dev/null +++ b/showcase/taiga-support/index.html @@ -0,0 +1,179 @@ + + + + + + + + + + Taiga Support | Lektor Static Content Management System + + + + +
+ +
+
+ +

Taiga Support

+
+
+
+

We define Taiga as an Open Source (AGPL v3) powerful project management platform for startups +and agile developers & designers who want a simple, beautiful tool that makes work + truly enjoyable.

+

We use Lektor to create the site with all the help documentation. Its content is available on +GitHub so you can see and contribute to it.

+

View the Sourcecode on GitHub

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/taiga-support/site-article1.png b/showcase/taiga-support/site-article1.png new file mode 100644 index 00000000..db15044d Binary files /dev/null and b/showcase/taiga-support/site-article1.png differ diff --git a/showcase/taiga-support/site-article2.png b/showcase/taiga-support/site-article2.png new file mode 100644 index 00000000..8f9b9ce6 Binary files /dev/null and b/showcase/taiga-support/site-article2.png differ diff --git a/showcase/taiga-support/site-article3.png b/showcase/taiga-support/site-article3.png new file mode 100644 index 00000000..8b1aff22 Binary files /dev/null and b/showcase/taiga-support/site-article3.png differ diff --git a/showcase/terminal-labs/index.html b/showcase/terminal-labs/index.html new file mode 100644 index 00000000..9d4e1245 --- /dev/null +++ b/showcase/terminal-labs/index.html @@ -0,0 +1,159 @@ + + + + + + + + + + Terminal Labs | Lektor Static Content Management System + + + + +
+ +
+
+ +

Terminal Labs

+
+
+
+

Terminal Labs is a consulting firm specializing in Python, Data Science, and DevOps. We love science and technology. We make clusters for fun, and enjoy experimenting to find and make better tools. That's what led us to find and try out Lektor. We love it. Right now a Lektor-based static site hosted on a CDN is just what we want, since it's is easy and fast to develop with and deploy, and is very performant.

+

You can view the source code for our site here, or view any of our other public repositories over on our GitHub page.

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/terminal-labs/terminal-labs-clients.png b/showcase/terminal-labs/terminal-labs-clients.png new file mode 100644 index 00000000..4fd7d02d Binary files /dev/null and b/showcase/terminal-labs/terminal-labs-clients.png differ diff --git a/showcase/terminal-labs/terminal-labs-homepage.png b/showcase/terminal-labs/terminal-labs-homepage.png new file mode 100644 index 00000000..effb9c50 Binary files /dev/null and b/showcase/terminal-labs/terminal-labs-homepage.png differ diff --git a/showcase/terminal-labs/terminal-labs-homepage@480.png b/showcase/terminal-labs/terminal-labs-homepage@480.png new file mode 100644 index 00000000..a66ace27 Binary files /dev/null and b/showcase/terminal-labs/terminal-labs-homepage@480.png differ diff --git a/showcase/tracetronic/1-homepage.png b/showcase/tracetronic/1-homepage.png new file mode 100644 index 00000000..98555e3a Binary files /dev/null and b/showcase/tracetronic/1-homepage.png differ diff --git a/showcase/tracetronic/1-homepage@480.png b/showcase/tracetronic/1-homepage@480.png new file mode 100644 index 00000000..bb5b2ea2 Binary files /dev/null and b/showcase/tracetronic/1-homepage@480.png differ diff --git a/showcase/tracetronic/2-menu-and-content.png b/showcase/tracetronic/2-menu-and-content.png new file mode 100644 index 00000000..b5463c29 Binary files /dev/null and b/showcase/tracetronic/2-menu-and-content.png differ diff --git a/showcase/tracetronic/index.html b/showcase/tracetronic/index.html new file mode 100644 index 00000000..5fdd4c31 --- /dev/null +++ b/showcase/tracetronic/index.html @@ -0,0 +1,158 @@ + + + + + + + + + + TraceTronic | Lektor Static Content Management System + + + + +
+ +
+
+ +

TraceTronic

+
+
+
+

We wanted to redesign our website and chose Lektor because it combines the ease of use for regular content editors with the strengths of static site generators. Also we like Python ;)

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/xinfengtv-website/index.html b/showcase/xinfengtv-website/index.html new file mode 100644 index 00000000..45ce1e15 --- /dev/null +++ b/showcase/xinfengtv-website/index.html @@ -0,0 +1,185 @@ + + + + + + + + + + XinFengTv Website | Lektor Static Content Management System + + + + +
+ +
+
+ +

XinFengTv Website

+
+
+
+

This project is a news and magazine website talking about AI / smart home and robots. We build this project's front with Lektor to speed it up and make it faster than ever to visit.

+

The difficulty during building this project is that we have to make every page match the MIP rulers - which is the alternative mobile website standard to Google's AMP provide by Baidu.

+

Before Lektor, we tried several tools; WordPress, Hugo, Hexo, and even Forestry. Finally we met Lektor. It is very powerful and now we love it. We will use it to build more projects and we are starting to make some plugins for it.

+

Thanks again!

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/showcase/xinfengtv-website/xinfengtv-com-category-hotline.jpg b/showcase/xinfengtv-website/xinfengtv-com-category-hotline.jpg new file mode 100644 index 00000000..77dc704f Binary files /dev/null and b/showcase/xinfengtv-website/xinfengtv-com-category-hotline.jpg differ diff --git a/showcase/xinfengtv-website/xinfengtv-com-category.jpg b/showcase/xinfengtv-website/xinfengtv-com-category.jpg new file mode 100644 index 00000000..a2a330a9 Binary files /dev/null and b/showcase/xinfengtv-website/xinfengtv-com-category.jpg differ diff --git a/showcase/xinfengtv-website/xinfengtv-com-cover-1.jpg b/showcase/xinfengtv-website/xinfengtv-com-cover-1.jpg new file mode 100644 index 00000000..bc991469 Binary files /dev/null and b/showcase/xinfengtv-website/xinfengtv-com-cover-1.jpg differ diff --git a/showcase/xinfengtv-website/xinfengtv-com-cover-tags.jpg b/showcase/xinfengtv-website/xinfengtv-com-cover-tags.jpg new file mode 100644 index 00000000..0c5f04f8 Binary files /dev/null and b/showcase/xinfengtv-website/xinfengtv-com-cover-tags.jpg differ diff --git a/showcase/xinfengtv-website/xinfengtv-com-cover.jpg b/showcase/xinfengtv-website/xinfengtv-com-cover.jpg new file mode 100644 index 00000000..e9aa232a Binary files /dev/null and b/showcase/xinfengtv-website/xinfengtv-com-cover.jpg differ diff --git a/showcase/xinfengtv-website/xinfengtv-com-cover@480.jpg b/showcase/xinfengtv-website/xinfengtv-com-cover@480.jpg new file mode 100644 index 00000000..cf9f7347 Binary files /dev/null and b/showcase/xinfengtv-website/xinfengtv-com-cover@480.jpg differ diff --git a/showcase/yargies/1-home.png b/showcase/yargies/1-home.png new file mode 100644 index 00000000..08839adc Binary files /dev/null and b/showcase/yargies/1-home.png differ diff --git a/showcase/yargies/1-home@480.png b/showcase/yargies/1-home@480.png new file mode 100644 index 00000000..b1ccfb00 Binary files /dev/null and b/showcase/yargies/1-home@480.png differ diff --git a/showcase/yargies/2-blog.png b/showcase/yargies/2-blog.png new file mode 100644 index 00000000..b8b097ca Binary files /dev/null and b/showcase/yargies/2-blog.png differ diff --git a/showcase/yargies/3-product.png b/showcase/yargies/3-product.png new file mode 100644 index 00000000..a3bd789d Binary files /dev/null and b/showcase/yargies/3-product.png differ diff --git a/showcase/yargies/index.html b/showcase/yargies/index.html new file mode 100644 index 00000000..2ffaf653 --- /dev/null +++ b/showcase/yargies/index.html @@ -0,0 +1,166 @@ + + + + + + + + + + Yargies Games | Lektor Static Content Management System + + + + +
+ +
+
+ +

Yargies Games

+
+
+
+

Yargies Games is where I showcase my mobile games and blog. I knew I wanted to use a static site generator to build the site and I chose Lektor because of it's flexibility. I deploy to S3 and Cloudfront using the lektor-s3 plugin. Hosting is fast, cheap and worry-free with Lektor.

+ +
+
+
+
+
+
+ +
+
+
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + + diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 00000000..ca56403c --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,413 @@ + + + https://www.getlektor.com/ + https://www.getlektor.com/404.html + https://www.getlektor.com/blog/ + https://www.getlektor.com/blog/2020/8/lektor-32-released/ + https://www.getlektor.com/blog/2018/5/plugin-play/ + https://www.getlektor.com/blog/2018/1/lektor-31-released/ + https://www.getlektor.com/blog/2016/4/lektor-2-released/ + https://www.getlektor.com/blog/2016/3/lektor-at-rails-girls-summer-of-code/ + https://www.getlektor.com/blog/2016/3/road-to-lektor-2/ + https://www.getlektor.com/blog/2015/12/travis-and-ghpages/ + https://www.getlektor.com/blog/2015/12/hello-lektor/ + https://www.getlektor.com/community/ + https://www.getlektor.com/contact/ + https://www.getlektor.com/docs/ + https://www.getlektor.com/docs/what/ + https://www.getlektor.com/docs/installation/ + https://www.getlektor.com/docs/quickstart/ + https://www.getlektor.com/docs/project/ + https://www.getlektor.com/docs/project/structure/ + https://www.getlektor.com/docs/project/file/ + https://www.getlektor.com/docs/content/ + https://www.getlektor.com/docs/content/alts/ + https://www.getlektor.com/docs/content/attachments/ + https://www.getlektor.com/docs/content/databags/ + https://www.getlektor.com/docs/content/flow/ + https://www.getlektor.com/docs/content/paths/ + https://www.getlektor.com/docs/content/system-fields/ + https://www.getlektor.com/docs/content/urls/ + https://www.getlektor.com/docs/templates/ + https://www.getlektor.com/docs/templates/urls/ + https://www.getlektor.com/docs/templates/navigation/ + https://www.getlektor.com/docs/templates/imageops/ + https://www.getlektor.com/docs/templates/videoops/ + https://www.getlektor.com/docs/themes/ + https://www.getlektor.com/docs/themes/installing/ + https://www.getlektor.com/docs/themes/customizing/ + https://www.getlektor.com/docs/themes/creating/ + https://www.getlektor.com/docs/themes/packages/ + https://www.getlektor.com/docs/guides/ + https://www.getlektor.com/docs/guides/blog/ + https://www.getlektor.com/docs/guides/categories/ + https://www.getlektor.com/docs/guides/disqus/ + https://www.getlektor.com/docs/guides/error-pages/ + https://www.getlektor.com/docs/guides/page-order/ + https://www.getlektor.com/docs/guides/pagination/ + https://www.getlektor.com/docs/guides/portfolio/ + https://www.getlektor.com/docs/guides/redirects/ + https://www.getlektor.com/docs/guides/single-page/ + https://www.getlektor.com/docs/guides/sitemap/ + https://www.getlektor.com/docs/guides/webpack/ + https://www.getlektor.com/docs/deployment/ + https://www.getlektor.com/docs/deployment/ftp/ + https://www.getlektor.com/docs/deployment/ghpages/ + https://www.getlektor.com/docs/deployment/glpages/ + https://www.getlektor.com/docs/deployment/rsync/ + https://www.getlektor.com/docs/deployment/travisci/ + https://www.getlektor.com/docs/plugins/ + https://www.getlektor.com/docs/plugins/dev/ + https://www.getlektor.com/docs/plugins/howto/ + https://www.getlektor.com/docs/plugins/publishing/ + https://www.getlektor.com/docs/models/ + https://www.getlektor.com/docs/models/attachments/ + https://www.getlektor.com/docs/models/children/ + https://www.getlektor.com/docs/models/selection/ + https://www.getlektor.com/docs/models/flow/ + https://www.getlektor.com/docs/cli/ + https://www.getlektor.com/docs/cli/build/ + https://www.getlektor.com/docs/cli/clean/ + https://www.getlektor.com/docs/cli/content-file-info/ + https://www.getlektor.com/docs/cli/deploy/ + https://www.getlektor.com/docs/cli/dev/ + https://www.getlektor.com/docs/cli/dev/new-plugin/ + https://www.getlektor.com/docs/cli/dev/publish-plugin/ + https://www.getlektor.com/docs/cli/dev/shell/ + https://www.getlektor.com/docs/cli/plugins/ + https://www.getlektor.com/docs/cli/plugins/add/ + https://www.getlektor.com/docs/cli/plugins/flush-cache/ + https://www.getlektor.com/docs/cli/plugins/list/ + https://www.getlektor.com/docs/cli/plugins/reinstall/ + https://www.getlektor.com/docs/cli/plugins/remove/ + https://www.getlektor.com/docs/cli/project-info/ + https://www.getlektor.com/docs/cli/quickstart/ + https://www.getlektor.com/docs/cli/server/ + https://www.getlektor.com/docs/api/ + https://www.getlektor.com/docs/api/build/ + https://www.getlektor.com/docs/api/build/artifact/ + https://www.getlektor.com/docs/api/build/artifact/artifact-name/ + https://www.getlektor.com/docs/api/build/artifact/is-current/ + https://www.getlektor.com/docs/api/build/artifact/open/ + https://www.getlektor.com/docs/api/build/artifact/render-template-into/ + https://www.getlektor.com/docs/api/build/artifact/replace-with-file/ + https://www.getlektor.com/docs/api/build/artifact/source-obj/ + https://www.getlektor.com/docs/api/build/program/ + https://www.getlektor.com/docs/api/build/program/build-artifact/ + https://www.getlektor.com/docs/api/build/program/declare-artifact/ + https://www.getlektor.com/docs/api/build/program/iter-child-sources/ + https://www.getlektor.com/docs/api/build/program/produce-artifacts/ + https://www.getlektor.com/docs/api/build/program/source/ + https://www.getlektor.com/docs/api/build/context/ + https://www.getlektor.com/docs/api/build/context/changed-base-url/ + https://www.getlektor.com/docs/api/build/context/gather-dependencies/ + https://www.getlektor.com/docs/api/build/context/locale/ + https://www.getlektor.com/docs/api/build/context/pad/ + https://www.getlektor.com/docs/api/build/context/record/ + https://www.getlektor.com/docs/api/build/context/record-dependency/ + https://www.getlektor.com/docs/api/build/context/source/ + https://www.getlektor.com/docs/api/build/context/sub-artifact/ + https://www.getlektor.com/docs/api/build/get-ctx/ + https://www.getlektor.com/docs/api/databags/ + https://www.getlektor.com/docs/api/databags/get-bag/ + https://www.getlektor.com/docs/api/databags/lookup/ + https://www.getlektor.com/docs/api/db/ + https://www.getlektor.com/docs/api/db/types/ + https://www.getlektor.com/docs/api/db/types/boolean/ + https://www.getlektor.com/docs/api/db/types/checkboxes/ + https://www.getlektor.com/docs/api/db/types/date/ + https://www.getlektor.com/docs/api/db/types/datetime/ + https://www.getlektor.com/docs/api/db/types/float/ + https://www.getlektor.com/docs/api/db/types/flow/ + https://www.getlektor.com/docs/api/db/types/html/ + https://www.getlektor.com/docs/api/db/types/integer/ + https://www.getlektor.com/docs/api/db/types/markdown/ + https://www.getlektor.com/docs/api/db/types/select/ + https://www.getlektor.com/docs/api/db/types/sort-key/ + https://www.getlektor.com/docs/api/db/types/string/ + https://www.getlektor.com/docs/api/db/types/strings/ + https://www.getlektor.com/docs/api/db/types/text/ + https://www.getlektor.com/docs/api/db/types/url/ + https://www.getlektor.com/docs/api/db/expression/ + https://www.getlektor.com/docs/api/db/expression/ne/ + https://www.getlektor.com/docs/api/db/expression/lt/ + https://www.getlektor.com/docs/api/db/expression/le/ + https://www.getlektor.com/docs/api/db/expression/eq/ + https://www.getlektor.com/docs/api/db/expression/gt/ + https://www.getlektor.com/docs/api/db/expression/ge/ + https://www.getlektor.com/docs/api/db/expression/and/ + https://www.getlektor.com/docs/api/db/expression/contains/ + https://www.getlektor.com/docs/api/db/expression/endswith/ + https://www.getlektor.com/docs/api/db/expression/endswith-cs/ + https://www.getlektor.com/docs/api/db/expression/or/ + https://www.getlektor.com/docs/api/db/expression/startswith/ + https://www.getlektor.com/docs/api/db/expression/startswith-cs/ + https://www.getlektor.com/docs/api/db/f/ + https://www.getlektor.com/docs/api/db/get-alts/ + https://www.getlektor.com/docs/api/db/pad/ + https://www.getlektor.com/docs/api/db/pad/databags/ + https://www.getlektor.com/docs/api/db/pad/get/ + https://www.getlektor.com/docs/api/db/pad/get-root/ + https://www.getlektor.com/docs/api/db/pad/query/ + https://www.getlektor.com/docs/api/db/pad/resolve-url-path/ + https://www.getlektor.com/docs/api/db/pad/root/ + https://www.getlektor.com/docs/api/db/query/ + https://www.getlektor.com/docs/api/db/query/all/ + https://www.getlektor.com/docs/api/db/query/count/ + https://www.getlektor.com/docs/api/db/query/distinct/ + https://www.getlektor.com/docs/api/db/query/filter/ + https://www.getlektor.com/docs/api/db/query/first/ + https://www.getlektor.com/docs/api/db/query/get/ + https://www.getlektor.com/docs/api/db/query/include-hidden/ + https://www.getlektor.com/docs/api/db/query/include-undiscoverable/ + https://www.getlektor.com/docs/api/db/query/limit/ + https://www.getlektor.com/docs/api/db/query/offset/ + https://www.getlektor.com/docs/api/db/query/order-by/ + https://www.getlektor.com/docs/api/db/query/request-page/ + https://www.getlektor.com/docs/api/db/query/self/ + https://www.getlektor.com/docs/api/db/record/ + https://www.getlektor.com/docs/api/db/record/getitem/ + https://www.getlektor.com/docs/api/db/record/attachments/ + https://www.getlektor.com/docs/api/db/record/children/ + https://www.getlektor.com/docs/api/db/record/contents/ + https://www.getlektor.com/docs/api/db/record/exif/ + https://www.getlektor.com/docs/api/db/record/format/ + https://www.getlektor.com/docs/api/db/record/get_siblings/ + https://www.getlektor.com/docs/api/db/record/has_next/ + https://www.getlektor.com/docs/api/db/record/has_prev/ + https://www.getlektor.com/docs/api/db/record/height/ + https://www.getlektor.com/docs/api/db/record/is-attachment/ + https://www.getlektor.com/docs/api/db/record/pagination/ + https://www.getlektor.com/docs/api/db/record/record-label/ + https://www.getlektor.com/docs/api/db/record/thumbnail/ + https://www.getlektor.com/docs/api/db/record/width/ + https://www.getlektor.com/docs/api/db/obj/ + https://www.getlektor.com/docs/api/db/obj/alt/ + https://www.getlektor.com/docs/api/db/obj/is-child-of/ + https://www.getlektor.com/docs/api/db/obj/is-discoverable/ + https://www.getlektor.com/docs/api/db/obj/is-hidden/ + https://www.getlektor.com/docs/api/db/obj/is-undiscoverable/ + https://www.getlektor.com/docs/api/db/obj/is-visible/ + https://www.getlektor.com/docs/api/db/obj/parent/ + https://www.getlektor.com/docs/api/db/obj/path/ + https://www.getlektor.com/docs/api/db/obj/record/ + https://www.getlektor.com/docs/api/db/obj/source-filename/ + https://www.getlektor.com/docs/api/db/obj/url-path/ + https://www.getlektor.com/docs/api/db/obj/url-to/ + https://www.getlektor.com/docs/api/db/system-fields/ + https://www.getlektor.com/docs/api/db/system-fields/alt/ + https://www.getlektor.com/docs/api/db/system-fields/attachment-type/ + https://www.getlektor.com/docs/api/db/system-fields/discoverable/ + https://www.getlektor.com/docs/api/db/system-fields/gid/ + https://www.getlektor.com/docs/api/db/system-fields/hidden/ + https://www.getlektor.com/docs/api/db/system-fields/id/ + https://www.getlektor.com/docs/api/db/system-fields/model/ + https://www.getlektor.com/docs/api/db/system-fields/path/ + https://www.getlektor.com/docs/api/db/system-fields/slug/ + https://www.getlektor.com/docs/api/db/system-fields/source-alt/ + https://www.getlektor.com/docs/api/db/system-fields/template/ + https://www.getlektor.com/docs/api/db/type/ + https://www.getlektor.com/docs/api/db/type/to-json/ + https://www.getlektor.com/docs/api/db/type/value-from-raw/ + https://www.getlektor.com/docs/api/db/type/widget/ + https://www.getlektor.com/docs/api/environment/ + https://www.getlektor.com/docs/api/environment/add-build-program/ + https://www.getlektor.com/docs/api/environment/add-publisher/ + https://www.getlektor.com/docs/api/environment/add-type/ + https://www.getlektor.com/docs/api/environment/generator/ + https://www.getlektor.com/docs/api/environment/jinja-env/ + https://www.getlektor.com/docs/api/environment/load-config/ + https://www.getlektor.com/docs/api/environment/load-plugins/ + https://www.getlektor.com/docs/api/environment/new-pad/ + https://www.getlektor.com/docs/api/environment/render-template/ + https://www.getlektor.com/docs/api/environment/urlresolver/ + https://www.getlektor.com/docs/api/environment/virtualpathresolver/ + https://www.getlektor.com/docs/api/plugins/ + https://www.getlektor.com/docs/api/plugins/events/ + https://www.getlektor.com/docs/api/plugins/events/after-build/ + https://www.getlektor.com/docs/api/plugins/events/after-build-all/ + https://www.getlektor.com/docs/api/plugins/events/after-prune/ + https://www.getlektor.com/docs/api/plugins/events/before-build/ + https://www.getlektor.com/docs/api/plugins/events/before-build-all/ + https://www.getlektor.com/docs/api/plugins/events/before-prune/ + https://www.getlektor.com/docs/api/plugins/events/markdown-config/ + https://www.getlektor.com/docs/api/plugins/events/markdown-lexer-config/ + https://www.getlektor.com/docs/api/plugins/events/markdown-meta-init/ + https://www.getlektor.com/docs/api/plugins/events/markdown-meta-postprocess/ + https://www.getlektor.com/docs/api/plugins/events/process-template-context/ + https://www.getlektor.com/docs/api/plugins/events/server-spawn/ + https://www.getlektor.com/docs/api/plugins/events/server-stop/ + https://www.getlektor.com/docs/api/plugins/events/setup-env/ + https://www.getlektor.com/docs/api/plugins/get-plugin/ + https://www.getlektor.com/docs/api/plugins/plugin/ + https://www.getlektor.com/docs/api/plugins/plugin/config-filename/ + https://www.getlektor.com/docs/api/plugins/plugin/description/ + https://www.getlektor.com/docs/api/plugins/plugin/emit/ + https://www.getlektor.com/docs/api/plugins/plugin/env/ + https://www.getlektor.com/docs/api/plugins/plugin/get-config/ + https://www.getlektor.com/docs/api/plugins/plugin/name/ + https://www.getlektor.com/docs/api/project/ + https://www.getlektor.com/docs/api/project/discover/ + https://www.getlektor.com/docs/api/project/from-file/ + https://www.getlektor.com/docs/api/project/make-env/ + https://www.getlektor.com/docs/api/publisher/ + https://www.getlektor.com/docs/api/publisher/env/ + https://www.getlektor.com/docs/api/publisher/fail/ + https://www.getlektor.com/docs/api/publisher/output-path/ + https://www.getlektor.com/docs/api/publisher/publish/ + https://www.getlektor.com/docs/api/templates/ + https://www.getlektor.com/docs/api/templates/filters/ + https://www.getlektor.com/docs/api/templates/filters/asseturl/ + https://www.getlektor.com/docs/api/templates/filters/dateformat/ + https://www.getlektor.com/docs/api/templates/filters/datetimeformat/ + https://www.getlektor.com/docs/api/templates/filters/latformat/ + https://www.getlektor.com/docs/api/templates/filters/latlongformat/ + https://www.getlektor.com/docs/api/templates/filters/longformat/ + https://www.getlektor.com/docs/api/templates/filters/markdown/ + https://www.getlektor.com/docs/api/templates/filters/tojson/ + https://www.getlektor.com/docs/api/templates/filters/url/ + https://www.getlektor.com/docs/api/templates/globals/ + https://www.getlektor.com/docs/api/templates/globals/bag/ + https://www.getlektor.com/docs/api/templates/globals/f/ + https://www.getlektor.com/docs/api/templates/globals/get-random-id/ + https://www.getlektor.com/docs/api/templates/globals/site/ + https://www.getlektor.com/docs/api/utils/ + https://www.getlektor.com/docs/api/utils/build-url/ + https://www.getlektor.com/docs/api/utils/get-structure-hash/ + https://www.getlektor.com/docs/api/utils/join-path/ + https://www.getlektor.com/docs/api/utils/parse-path/ + https://www.getlektor.com/docs/api/utils/process-image/ + https://www.getlektor.com/docs/api/utils/url-to/ + https://www.getlektor.com/docs/search/ + https://www.getlektor.com/downloads/ + https://www.getlektor.com/license/ + https://www.getlektor.com/plugins/categories/ + https://www.getlektor.com/plugins/categories/build/ + https://www.getlektor.com/plugins/lektor-gulp/ + https://www.getlektor.com/plugins/lektor-htmlmin/ + https://www.getlektor.com/plugins/lektor-i18n/ + https://www.getlektor.com/plugins/lektor-make/ + https://www.getlektor.com/plugins/lektor-minify/ + https://www.getlektor.com/plugins/lektor-npm-support/ + https://www.getlektor.com/plugins/lektor-scss/ + https://www.getlektor.com/plugins/lektor-scsscompile/ + https://www.getlektor.com/plugins/lektor-webpack-html-helper/ + https://www.getlektor.com/plugins/lektor-webpack-support/ + https://www.getlektor.com/plugins/lektor-git-timestamp/ + https://www.getlektor.com/plugins/lektor-limit-dependencies/ + https://www.getlektor.com/plugins/categories/content/ + https://www.getlektor.com/plugins/lektor-asciidoc/ + https://www.getlektor.com/plugins/lektor-asciidoctor/ + https://www.getlektor.com/plugins/lektor-bibtex-support/ + https://www.getlektor.com/plugins/lektor-jinja-content/ + https://www.getlektor.com/plugins/lektor-markdown-admonition/ + https://www.getlektor.com/plugins/lektor-markdown-header-anchors/ + https://www.getlektor.com/plugins/lektor-markdown-highlighter/ + https://www.getlektor.com/plugins/lektor-nofollow/ + https://www.getlektor.com/plugins/lektor-pythonmarkdown/ + https://www.getlektor.com/plugins/lektor-read-full-post/ + https://www.getlektor.com/plugins/lektor-rst/ + https://www.getlektor.com/plugins/lektor-tags/ + https://www.getlektor.com/plugins/lektor-expression-type/ + https://www.getlektor.com/plugins/lektor-index-pages/ + https://www.getlektor.com/plugins/lektor-polymorphic-type/ + https://www.getlektor.com/plugins/lektor-citation/ + https://www.getlektor.com/plugins/categories/deploy/ + https://www.getlektor.com/plugins/lektor-netlify/ + https://www.getlektor.com/plugins/lektor-s3/ + https://www.getlektor.com/plugins/lektor-surge/ + https://www.getlektor.com/plugins/lektor-qiniu/ + https://www.getlektor.com/plugins/categories/templates/ + https://www.getlektor.com/plugins/lektor-atom/ + https://www.getlektor.com/plugins/lektor-creative-commons/ + https://www.getlektor.com/plugins/lektor-disqus-comments/ + https://www.getlektor.com/plugins/lektor-github-repos/ + https://www.getlektor.com/plugins/lektor-google-analytics/ + https://www.getlektor.com/plugins/lektor-markdown-excerpt/ + https://www.getlektor.com/plugins/lektor-natural-language/ + https://www.getlektor.com/plugins/lektor-root-relative-path/ + https://www.getlektor.com/plugins/lektor-shortcodes/ + https://www.getlektor.com/plugins/lektor-slugify/ + https://www.getlektor.com/plugins/lektor-strip-html-tags/ + https://www.getlektor.com/plugins/lektor-thumbnail-generator/ + https://www.getlektor.com/plugins/lektor-webdav/ + https://www.getlektor.com/plugins/lektor-yandex-metrica/ + https://www.getlektor.com/plugins/lektor-image-resize/ + https://www.getlektor.com/plugins/lektor-tawk/ + https://www.getlektor.com/plugins/lektor-google-search/ + https://www.getlektor.com/plugins/ + https://www.getlektor.com/plugins/lektor-asciidoc/ + https://www.getlektor.com/plugins/lektor-asciidoctor/ + https://www.getlektor.com/plugins/lektor-atom/ + https://www.getlektor.com/plugins/lektor-bibtex-support/ + https://www.getlektor.com/plugins/lektor-creative-commons/ + https://www.getlektor.com/plugins/lektor-disqus-comments/ + https://www.getlektor.com/plugins/lektor-github-repos/ + https://www.getlektor.com/plugins/lektor-google-analytics/ + https://www.getlektor.com/plugins/lektor-gulp/ + https://www.getlektor.com/plugins/lektor-htmlmin/ + https://www.getlektor.com/plugins/lektor-i18n/ + https://www.getlektor.com/plugins/lektor-jinja-content/ + https://www.getlektor.com/plugins/lektor-make/ + https://www.getlektor.com/plugins/lektor-markdown-admonition/ + https://www.getlektor.com/plugins/lektor-markdown-excerpt/ + https://www.getlektor.com/plugins/lektor-markdown-header-anchors/ + https://www.getlektor.com/plugins/lektor-markdown-highlighter/ + https://www.getlektor.com/plugins/lektor-minify/ + https://www.getlektor.com/plugins/lektor-natural-language/ + https://www.getlektor.com/plugins/lektor-netlify/ + https://www.getlektor.com/plugins/lektor-nofollow/ + https://www.getlektor.com/plugins/lektor-npm-support/ + https://www.getlektor.com/plugins/lektor-pythonmarkdown/ + https://www.getlektor.com/plugins/lektor-read-full-post/ + https://www.getlektor.com/plugins/lektor-root-relative-path/ + https://www.getlektor.com/plugins/lektor-rst/ + https://www.getlektor.com/plugins/lektor-s3/ + https://www.getlektor.com/plugins/lektor-scss/ + https://www.getlektor.com/plugins/lektor-scsscompile/ + https://www.getlektor.com/plugins/lektor-shortcodes/ + https://www.getlektor.com/plugins/lektor-slugify/ + https://www.getlektor.com/plugins/lektor-strip-html-tags/ + https://www.getlektor.com/plugins/lektor-surge/ + https://www.getlektor.com/plugins/lektor-tags/ + https://www.getlektor.com/plugins/lektor-thumbnail-generator/ + https://www.getlektor.com/plugins/lektor-webdav/ + https://www.getlektor.com/plugins/lektor-webpack-html-helper/ + https://www.getlektor.com/plugins/lektor-webpack-support/ + https://www.getlektor.com/plugins/lektor-yandex-metrica/ + https://www.getlektor.com/plugins/tags/ + https://www.getlektor.com/plugins/lektor-expression-type/ + https://www.getlektor.com/plugins/lektor-git-timestamp/ + https://www.getlektor.com/plugins/lektor-image-resize/ + https://www.getlektor.com/plugins/lektor-index-pages/ + https://www.getlektor.com/plugins/lektor-limit-dependencies/ + https://www.getlektor.com/plugins/lektor-polymorphic-type/ + https://www.getlektor.com/plugins/lektor-qiniu/ + https://www.getlektor.com/plugins/lektor-tawk/ + https://www.getlektor.com/plugins/lektor-citation/ + https://www.getlektor.com/plugins/lektor-google-search/ + https://www.getlektor.com/showcase/ + https://www.getlektor.com/showcase/allnew-selfstudythai/ + https://www.getlektor.com/showcase/amin-mesbah/ + https://www.getlektor.com/showcase/andrew-shay/ + https://www.getlektor.com/showcase/architekten-ronacher/ + https://www.getlektor.com/showcase/atelier-ronacher/ + https://www.getlektor.com/showcase/pybee/ + https://www.getlektor.com/showcase/davidbaumgold/ + https://www.getlektor.com/showcase/eric-ma/ + https://www.getlektor.com/showcase/eswar-malla/ + https://www.getlektor.com/showcase/frank-tisellano/ + https://www.getlektor.com/showcase/freedombox/ + https://www.getlektor.com/showcase/happyhols/ + https://www.getlektor.com/showcase/lektor-website/ + https://www.getlektor.com/showcase/mark-steve-samson/ + https://www.getlektor.com/showcase/pallets-projects/ + https://www.getlektor.com/showcase/playwarwick/ + https://www.getlektor.com/showcase/pycon-colombia-2018/ + https://www.getlektor.com/showcase/pycon-philippines-2016/ + https://www.getlektor.com/showcase/taiga-support/ + https://www.getlektor.com/showcase/terminal-labs/ + https://www.getlektor.com/showcase/tracetronic/ + https://www.getlektor.com/showcase/xinfengtv-website/ + https://www.getlektor.com/showcase/yargies/ + diff --git a/static/060b2710bdbbe3dfe48b.svg b/static/060b2710bdbbe3dfe48b.svg new file mode 100644 index 00000000..94fb5490 --- /dev/null +++ b/static/060b2710bdbbe3dfe48b.svg @@ -0,0 +1,288 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/static/1a36eac81379803edf73.png b/static/1a36eac81379803edf73.png new file mode 100644 index 00000000..2bda3eaa Binary files /dev/null and b/static/1a36eac81379803edf73.png differ diff --git a/static/1e59d2330b4c6deb84b3.ttf b/static/1e59d2330b4c6deb84b3.ttf new file mode 100644 index 00000000..35acda2f Binary files /dev/null and b/static/1e59d2330b4c6deb84b3.ttf differ diff --git a/static/20fd1704ea223900efa9.woff2 b/static/20fd1704ea223900efa9.woff2 new file mode 100644 index 00000000..4d13fc60 Binary files /dev/null and b/static/20fd1704ea223900efa9.woff2 differ diff --git a/static/3443f0c6c8bd59380965.png b/static/3443f0c6c8bd59380965.png new file mode 100644 index 00000000..05825ad0 Binary files /dev/null and b/static/3443f0c6c8bd59380965.png differ diff --git a/static/4692b9ec53fd5972caa2.ttf b/static/4692b9ec53fd5972caa2.ttf new file mode 100644 index 00000000..1413fc60 Binary files /dev/null and b/static/4692b9ec53fd5972caa2.ttf differ diff --git a/static/5be1347c682810f199c7.eot b/static/5be1347c682810f199c7.eot new file mode 100644 index 00000000..b93a4953 Binary files /dev/null and b/static/5be1347c682810f199c7.eot differ diff --git a/static/7cfca10756cf517756d2.png b/static/7cfca10756cf517756d2.png new file mode 100644 index 00000000..d9c6d818 Binary files /dev/null and b/static/7cfca10756cf517756d2.png differ diff --git a/static/82b1212e45a2bc35dd73.woff b/static/82b1212e45a2bc35dd73.woff new file mode 100644 index 00000000..9e612858 Binary files /dev/null and b/static/82b1212e45a2bc35dd73.woff differ diff --git a/static/8b43027f47b20503057d.eot b/static/8b43027f47b20503057d.eot new file mode 100644 index 00000000..e9f60ca9 Binary files /dev/null and b/static/8b43027f47b20503057d.eot differ diff --git a/static/9fb8decbe13fdee2d217.png b/static/9fb8decbe13fdee2d217.png new file mode 100644 index 00000000..6ac86c78 Binary files /dev/null and b/static/9fb8decbe13fdee2d217.png differ diff --git a/static/app.js b/static/app.js new file mode 100644 index 00000000..75928284 --- /dev/null +++ b/static/app.js @@ -0,0 +1,3 @@ +/*! For license information please see app.js.LICENSE.txt */ +(()=>{var t={915:(t,e,n)=>{n(294),n(309),n(929),n(50),n(63),n(737),n(852),n(278),n(927),n(497),n(814),n(377)},377:(t,e,n)=>{!function(t){"use strict";var e=function(n,i){this.options=t.extend({},e.DEFAULTS,i);var r=this.options.target===e.DEFAULTS.target?t(this.options.target):t(document).find(this.options.target);this.$target=r.on("scroll.bs.affix.data-api",t.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",t.proxy(this.checkPositionWithEventLoop,this)),this.$element=t(n),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};function n(n){return this.each((function(){var i=t(this),r=i.data("bs.affix"),o="object"==typeof n&&n;r||i.data("bs.affix",r=new e(this,o)),"string"==typeof n&&r[n]()}))}e.VERSION="3.4.1",e.RESET="affix affix-top affix-bottom",e.DEFAULTS={offset:0,target:window},e.prototype.getState=function(t,e,n,i){var r=this.$target.scrollTop(),o=this.$element.offset(),s=this.$target.height();if(null!=n&&"top"==this.affixed)return r=t-i&&"bottom"},e.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(e.RESET).addClass("affix");var t=this.$target.scrollTop(),n=this.$element.offset();return this.pinnedOffset=n.top-t},e.prototype.checkPositionWithEventLoop=function(){setTimeout(t.proxy(this.checkPosition,this),1)},e.prototype.checkPosition=function(){if(this.$element.is(":visible")){var n=this.$element.height(),i=this.options.offset,r=i.top,o=i.bottom,s=Math.max(t(document).height(),t(document.body).height());"object"!=typeof i&&(o=r=i),"function"==typeof r&&(r=i.top(this.$element)),"function"==typeof o&&(o=i.bottom(this.$element));var a=this.getState(s,n,r,o);if(this.affixed!=a){null!=this.unpin&&this.$element.css("top","");var l="affix"+(a?"-"+a:""),c=t.Event(l+".bs.affix");if(this.$element.trigger(c),c.isDefaultPrevented())return;this.affixed=a,this.unpin="bottom"==a?this.getPinnedOffset():null,this.$element.removeClass(e.RESET).addClass(l).trigger(l.replace("affix","affixed")+".bs.affix")}"bottom"==a&&this.$element.offset({top:s-n-o})}};var i=t.fn.affix;t.fn.affix=n,t.fn.affix.Constructor=e,t.fn.affix.noConflict=function(){return t.fn.affix=i,this},t(window).on("load",(function(){t('[data-spy="affix"]').each((function(){var e=t(this),i=e.data();i.offset=i.offset||{},null!=i.offsetBottom&&(i.offset.bottom=i.offsetBottom),null!=i.offsetTop&&(i.offset.top=i.offsetTop),n.call(e,i)}))}))}(n(755))},309:(t,e,n)=>{!function(t){"use strict";var e='[data-dismiss="alert"]',n=function(n){t(n).on("click",e,this.close)};n.VERSION="3.4.1",n.TRANSITION_DURATION=150,n.prototype.close=function(e){var i=t(this),r=i.attr("data-target");r||(r=(r=i.attr("href"))&&r.replace(/.*(?=#[^\s]*$)/,"")),r="#"===r?[]:r;var o=t(document).find(r);function s(){o.detach().trigger("closed.bs.alert").remove()}e&&e.preventDefault(),o.length||(o=i.closest(".alert")),o.trigger(e=t.Event("close.bs.alert")),e.isDefaultPrevented()||(o.removeClass("in"),t.support.transition&&o.hasClass("fade")?o.one("bsTransitionEnd",s).emulateTransitionEnd(n.TRANSITION_DURATION):s())};var i=t.fn.alert;t.fn.alert=function(e){return this.each((function(){var i=t(this),r=i.data("bs.alert");r||i.data("bs.alert",r=new n(this)),"string"==typeof e&&r[e].call(i)}))},t.fn.alert.Constructor=n,t.fn.alert.noConflict=function(){return t.fn.alert=i,this},t(document).on("click.bs.alert.data-api",e,n.prototype.close)}(n(755))},929:(t,e,n)=>{!function(t){"use strict";var e=function(n,i){this.$element=t(n),this.options=t.extend({},e.DEFAULTS,i),this.isLoading=!1};function n(n){return this.each((function(){var i=t(this),r=i.data("bs.button"),o="object"==typeof n&&n;r||i.data("bs.button",r=new e(this,o)),"toggle"==n?r.toggle():n&&r.setState(n)}))}e.VERSION="3.4.1",e.DEFAULTS={loadingText:"loading..."},e.prototype.setState=function(e){var n="disabled",i=this.$element,r=i.is("input")?"val":"html",o=i.data();e+="Text",null==o.resetText&&i.data("resetText",i[r]()),setTimeout(t.proxy((function(){i[r](null==o[e]?this.options[e]:o[e]),"loadingText"==e?(this.isLoading=!0,i.addClass(n).attr(n,n).prop(n,!0)):this.isLoading&&(this.isLoading=!1,i.removeClass(n).removeAttr(n).prop(n,!1))}),this),0)},e.prototype.toggle=function(){var t=!0,e=this.$element.closest('[data-toggle="buttons"]');if(e.length){var n=this.$element.find("input");"radio"==n.prop("type")?(n.prop("checked")&&(t=!1),e.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==n.prop("type")&&(n.prop("checked")!==this.$element.hasClass("active")&&(t=!1),this.$element.toggleClass("active")),n.prop("checked",this.$element.hasClass("active")),t&&n.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var i=t.fn.button;t.fn.button=n,t.fn.button.Constructor=e,t.fn.button.noConflict=function(){return t.fn.button=i,this},t(document).on("click.bs.button.data-api",'[data-toggle^="button"]',(function(e){var i=t(e.target).closest(".btn");n.call(i,"toggle"),t(e.target).is('input[type="radio"], input[type="checkbox"]')||(e.preventDefault(),i.is("input,button")?i.trigger("focus"):i.find("input:visible,button:visible").first().trigger("focus"))})).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',(function(e){t(e.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(e.type))}))}(n(755))},50:(t,e,n)=>{!function(t){"use strict";var e=function(e,n){this.$element=t(e),this.$indicators=this.$element.find(".carousel-indicators"),this.options=n,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",t.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",t.proxy(this.pause,this)).on("mouseleave.bs.carousel",t.proxy(this.cycle,this))};function n(n){return this.each((function(){var i=t(this),r=i.data("bs.carousel"),o=t.extend({},e.DEFAULTS,i.data(),"object"==typeof n&&n),s="string"==typeof n?n:o.slide;r||i.data("bs.carousel",r=new e(this,o)),"number"==typeof n?r.to(n):s?r[s]():o.interval&&r.pause().cycle()}))}e.VERSION="3.4.1",e.TRANSITION_DURATION=600,e.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},e.prototype.keydown=function(t){if(!/input|textarea/i.test(t.target.tagName)){switch(t.which){case 37:this.prev();break;case 39:this.next();break;default:return}t.preventDefault()}},e.prototype.cycle=function(e){return e||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(t.proxy(this.next,this),this.options.interval)),this},e.prototype.getItemIndex=function(t){return this.$items=t.parent().children(".item"),this.$items.index(t||this.$active)},e.prototype.getItemForDirection=function(t,e){var n=this.getItemIndex(e);if(("prev"==t&&0===n||"next"==t&&n==this.$items.length-1)&&!this.options.wrap)return e;var i=(n+("prev"==t?-1:1))%this.$items.length;return this.$items.eq(i)},e.prototype.to=function(t){var e=this,n=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(t>this.$items.length-1||t<0))return this.sliding?this.$element.one("slid.bs.carousel",(function(){e.to(t)})):n==t?this.pause().cycle():this.slide(t>n?"next":"prev",this.$items.eq(t))},e.prototype.pause=function(e){return e||(this.paused=!0),this.$element.find(".next, .prev").length&&t.support.transition&&(this.$element.trigger(t.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},e.prototype.next=function(){if(!this.sliding)return this.slide("next")},e.prototype.prev=function(){if(!this.sliding)return this.slide("prev")},e.prototype.slide=function(n,i){var r=this.$element.find(".item.active"),o=i||this.getItemForDirection(n,r),s=this.interval,a="next"==n?"left":"right",l=this;if(o.hasClass("active"))return this.sliding=!1;var c=o[0],u=t.Event("slide.bs.carousel",{relatedTarget:c,direction:a});if(this.$element.trigger(u),!u.isDefaultPrevented()){if(this.sliding=!0,s&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var p=t(this.$indicators.children()[this.getItemIndex(o)]);p&&p.addClass("active")}var f=t.Event("slid.bs.carousel",{relatedTarget:c,direction:a});return t.support.transition&&this.$element.hasClass("slide")?(o.addClass(n),"object"==typeof o&&o.length&&o[0].offsetWidth,r.addClass(a),o.addClass(a),r.one("bsTransitionEnd",(function(){o.removeClass([n,a].join(" ")).addClass("active"),r.removeClass(["active",a].join(" ")),l.sliding=!1,setTimeout((function(){l.$element.trigger(f)}),0)})).emulateTransitionEnd(e.TRANSITION_DURATION)):(r.removeClass("active"),o.addClass("active"),this.sliding=!1,this.$element.trigger(f)),s&&this.cycle(),this}};var i=t.fn.carousel;t.fn.carousel=n,t.fn.carousel.Constructor=e,t.fn.carousel.noConflict=function(){return t.fn.carousel=i,this};var r=function(e){var i=t(this),r=i.attr("href");r&&(r=r.replace(/.*(?=#[^\s]+$)/,""));var o=i.attr("data-target")||r,s=t(document).find(o);if(s.hasClass("carousel")){var a=t.extend({},s.data(),i.data()),l=i.attr("data-slide-to");l&&(a.interval=!1),n.call(s,a),l&&s.data("bs.carousel").to(l),e.preventDefault()}};t(document).on("click.bs.carousel.data-api","[data-slide]",r).on("click.bs.carousel.data-api","[data-slide-to]",r),t(window).on("load",(function(){t('[data-ride="carousel"]').each((function(){var e=t(this);n.call(e,e.data())}))}))}(n(755))},63:(t,e,n)=>{!function(t){"use strict";var e=function(n,i){this.$element=t(n),this.options=t.extend({},e.DEFAULTS,i),this.$trigger=t('[data-toggle="collapse"][href="#'+n.id+'"],[data-toggle="collapse"][data-target="#'+n.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};function n(e){var n,i=e.attr("data-target")||(n=e.attr("href"))&&n.replace(/.*(?=#[^\s]+$)/,"");return t(document).find(i)}function i(n){return this.each((function(){var i=t(this),r=i.data("bs.collapse"),o=t.extend({},e.DEFAULTS,i.data(),"object"==typeof n&&n);!r&&o.toggle&&/show|hide/.test(n)&&(o.toggle=!1),r||i.data("bs.collapse",r=new e(this,o)),"string"==typeof n&&r[n]()}))}e.VERSION="3.4.1",e.TRANSITION_DURATION=350,e.DEFAULTS={toggle:!0},e.prototype.dimension=function(){return this.$element.hasClass("width")?"width":"height"},e.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var n,r=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(r&&r.length&&(n=r.data("bs.collapse"))&&n.transitioning)){var o=t.Event("show.bs.collapse");if(this.$element.trigger(o),!o.isDefaultPrevented()){r&&r.length&&(i.call(r,"hide"),n||r.data("bs.collapse",null));var s=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[s](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var a=function(){this.$element.removeClass("collapsing").addClass("collapse in")[s](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!t.support.transition)return a.call(this);var l=t.camelCase(["scroll",s].join("-"));this.$element.one("bsTransitionEnd",t.proxy(a,this)).emulateTransitionEnd(e.TRANSITION_DURATION)[s](this.$element[0][l])}}}},e.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var n=t.Event("hide.bs.collapse");if(this.$element.trigger(n),!n.isDefaultPrevented()){var i=this.dimension();this.$element[i](this.$element[i]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var r=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};if(!t.support.transition)return r.call(this);this.$element[i](0).one("bsTransitionEnd",t.proxy(r,this)).emulateTransitionEnd(e.TRANSITION_DURATION)}}},e.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},e.prototype.getParent=function(){return t(document).find(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(t.proxy((function(e,i){var r=t(i);this.addAriaAndCollapsedClass(n(r),r)}),this)).end()},e.prototype.addAriaAndCollapsedClass=function(t,e){var n=t.hasClass("in");t.attr("aria-expanded",n),e.toggleClass("collapsed",!n).attr("aria-expanded",n)};var r=t.fn.collapse;t.fn.collapse=i,t.fn.collapse.Constructor=e,t.fn.collapse.noConflict=function(){return t.fn.collapse=r,this},t(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',(function(e){var r=t(this);r.attr("data-target")||e.preventDefault();var o=n(r),s=o.data("bs.collapse")?"toggle":r.data();i.call(o,s)}))}(n(755))},737:(t,e,n)=>{!function(t){"use strict";var e='[data-toggle="dropdown"]',n=function(e){t(e).on("click.bs.dropdown",this.toggle)};function i(e){var n=e.attr("data-target");n||(n=(n=e.attr("href"))&&/#[A-Za-z]/.test(n)&&n.replace(/.*(?=#[^\s]*$)/,""));var i="#"!==n?t(document).find(n):null;return i&&i.length?i:e.parent()}function r(n){n&&3===n.which||(t(".dropdown-backdrop").remove(),t(e).each((function(){var e=t(this),r=i(e),o={relatedTarget:this};r.hasClass("open")&&(n&&"click"==n.type&&/input|textarea/i.test(n.target.tagName)&&t.contains(r[0],n.target)||(r.trigger(n=t.Event("hide.bs.dropdown",o)),n.isDefaultPrevented()||(e.attr("aria-expanded","false"),r.removeClass("open").trigger(t.Event("hidden.bs.dropdown",o)))))})))}n.VERSION="3.4.1",n.prototype.toggle=function(e){var n=t(this);if(!n.is(".disabled, :disabled")){var o=i(n),s=o.hasClass("open");if(r(),!s){"ontouchstart"in document.documentElement&&!o.closest(".navbar-nav").length&&t(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(t(this)).on("click",r);var a={relatedTarget:this};if(o.trigger(e=t.Event("show.bs.dropdown",a)),e.isDefaultPrevented())return;n.trigger("focus").attr("aria-expanded","true"),o.toggleClass("open").trigger(t.Event("shown.bs.dropdown",a))}return!1}},n.prototype.keydown=function(n){if(/(38|40|27|32)/.test(n.which)&&!/input|textarea/i.test(n.target.tagName)){var r=t(this);if(n.preventDefault(),n.stopPropagation(),!r.is(".disabled, :disabled")){var o=i(r),s=o.hasClass("open");if(!s&&27!=n.which||s&&27==n.which)return 27==n.which&&o.find(e).trigger("focus"),r.trigger("click");var a=o.find(".dropdown-menu li:not(.disabled):visible a");if(a.length){var l=a.index(n.target);38==n.which&&l>0&&l--,40==n.which&&l{!function(t){"use strict";var e=function(e,n){this.options=n,this.$body=t(document.body),this.$element=t(e),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.fixedContent=".navbar-fixed-top, .navbar-fixed-bottom",this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,t.proxy((function(){this.$element.trigger("loaded.bs.modal")}),this))};function n(n,i){return this.each((function(){var r=t(this),o=r.data("bs.modal"),s=t.extend({},e.DEFAULTS,r.data(),"object"==typeof n&&n);o||r.data("bs.modal",o=new e(this,s)),"string"==typeof n?o[n](i):s.show&&o.show(i)}))}e.VERSION="3.4.1",e.TRANSITION_DURATION=300,e.BACKDROP_TRANSITION_DURATION=150,e.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},e.prototype.toggle=function(t){return this.isShown?this.hide():this.show(t)},e.prototype.show=function(n){var i=this,r=t.Event("show.bs.modal",{relatedTarget:n});this.$element.trigger(r),this.isShown||r.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',t.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",(function(){i.$element.one("mouseup.dismiss.bs.modal",(function(e){t(e.target).is(i.$element)&&(i.ignoreBackdropClick=!0)}))})),this.backdrop((function(){var r=t.support.transition&&i.$element.hasClass("fade");i.$element.parent().length||i.$element.appendTo(i.$body),i.$element.show().scrollTop(0),i.adjustDialog(),r&&i.$element[0].offsetWidth,i.$element.addClass("in"),i.enforceFocus();var o=t.Event("shown.bs.modal",{relatedTarget:n});r?i.$dialog.one("bsTransitionEnd",(function(){i.$element.trigger("focus").trigger(o)})).emulateTransitionEnd(e.TRANSITION_DURATION):i.$element.trigger("focus").trigger(o)})))},e.prototype.hide=function(n){n&&n.preventDefault(),n=t.Event("hide.bs.modal"),this.$element.trigger(n),this.isShown&&!n.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),t(document).off("focusin.bs.modal"),this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),t.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",t.proxy(this.hideModal,this)).emulateTransitionEnd(e.TRANSITION_DURATION):this.hideModal())},e.prototype.enforceFocus=function(){t(document).off("focusin.bs.modal").on("focusin.bs.modal",t.proxy((function(t){document===t.target||this.$element[0]===t.target||this.$element.has(t.target).length||this.$element.trigger("focus")}),this))},e.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",t.proxy((function(t){27==t.which&&this.hide()}),this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},e.prototype.resize=function(){this.isShown?t(window).on("resize.bs.modal",t.proxy(this.handleUpdate,this)):t(window).off("resize.bs.modal")},e.prototype.hideModal=function(){var t=this;this.$element.hide(),this.backdrop((function(){t.$body.removeClass("modal-open"),t.resetAdjustments(),t.resetScrollbar(),t.$element.trigger("hidden.bs.modal")}))},e.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},e.prototype.backdrop=function(n){var i=this,r=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var o=t.support.transition&&r;if(this.$backdrop=t(document.createElement("div")).addClass("modal-backdrop "+r).appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",t.proxy((function(t){this.ignoreBackdropClick?this.ignoreBackdropClick=!1:t.target===t.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide())}),this)),o&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!n)return;o?this.$backdrop.one("bsTransitionEnd",n).emulateTransitionEnd(e.BACKDROP_TRANSITION_DURATION):n()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var s=function(){i.removeBackdrop(),n&&n()};t.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",s).emulateTransitionEnd(e.BACKDROP_TRANSITION_DURATION):s()}else n&&n()},e.prototype.handleUpdate=function(){this.adjustDialog()},e.prototype.adjustDialog=function(){var t=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&t?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!t?this.scrollbarWidth:""})},e.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},e.prototype.checkScrollbar=function(){var t=window.innerWidth;if(!t){var e=document.documentElement.getBoundingClientRect();t=e.right-Math.abs(e.left)}this.bodyIsOverflowing=document.body.clientWidth{!function(t){"use strict";var e=function(t,e){this.init("popover",t,e)};if(!t.fn.tooltip)throw new Error("Popover requires tooltip.js");e.VERSION="3.4.1",e.DEFAULTS=t.extend({},t.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),(e.prototype=t.extend({},t.fn.tooltip.Constructor.prototype)).constructor=e,e.prototype.getDefaults=function(){return e.DEFAULTS},e.prototype.setContent=function(){var t=this.tip(),e=this.getTitle(),n=this.getContent();if(this.options.html){var i=typeof n;this.options.sanitize&&(e=this.sanitizeHtml(e),"string"===i&&(n=this.sanitizeHtml(n))),t.find(".popover-title").html(e),t.find(".popover-content").children().detach().end()["string"===i?"html":"append"](n)}else t.find(".popover-title").text(e),t.find(".popover-content").children().detach().end().text(n);t.removeClass("fade top bottom left right in"),t.find(".popover-title").html()||t.find(".popover-title").hide()},e.prototype.hasContent=function(){return this.getTitle()||this.getContent()},e.prototype.getContent=function(){var t=this.$element,e=this.options;return t.attr("data-content")||("function"==typeof e.content?e.content.call(t[0]):e.content)},e.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var n=t.fn.popover;t.fn.popover=function(n){return this.each((function(){var i=t(this),r=i.data("bs.popover"),o="object"==typeof n&&n;!r&&/destroy|hide/.test(n)||(r||i.data("bs.popover",r=new e(this,o)),"string"==typeof n&&r[n]())}))},t.fn.popover.Constructor=e,t.fn.popover.noConflict=function(){return t.fn.popover=n,this}}(n(755))},497:(t,e,n)=>{!function(t){"use strict";function e(n,i){this.$body=t(document.body),this.$scrollElement=t(n).is(document.body)?t(window):t(n),this.options=t.extend({},e.DEFAULTS,i),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",t.proxy(this.process,this)),this.refresh(),this.process()}function n(n){return this.each((function(){var i=t(this),r=i.data("bs.scrollspy"),o="object"==typeof n&&n;r||i.data("bs.scrollspy",r=new e(this,o)),"string"==typeof n&&r[n]()}))}e.VERSION="3.4.1",e.DEFAULTS={offset:10},e.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},e.prototype.refresh=function(){var e=this,n="offset",i=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),t.isWindow(this.$scrollElement[0])||(n="position",i=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map((function(){var e=t(this),r=e.data("target")||e.attr("href"),o=/^#./.test(r)&&t(r);return o&&o.length&&o.is(":visible")&&[[o[n]().top+i,r]]||null})).sort((function(t,e){return t[0]-e[0]})).each((function(){e.offsets.push(this[0]),e.targets.push(this[1])}))},e.prototype.process=function(){var t,e=this.$scrollElement.scrollTop()+this.options.offset,n=this.getScrollHeight(),i=this.options.offset+n-this.$scrollElement.height(),r=this.offsets,o=this.targets,s=this.activeTarget;if(this.scrollHeight!=n&&this.refresh(),e>=i)return s!=(t=o[o.length-1])&&this.activate(t);if(s&&e=r[t]&&(void 0===r[t+1]||e{!function(t){"use strict";var e=function(e){this.element=t(e)};function n(n){return this.each((function(){var i=t(this),r=i.data("bs.tab");r||i.data("bs.tab",r=new e(this)),"string"==typeof n&&r[n]()}))}e.VERSION="3.4.1",e.TRANSITION_DURATION=150,e.prototype.show=function(){var e=this.element,n=e.closest("ul:not(.dropdown-menu)"),i=e.data("target");if(i||(i=(i=e.attr("href"))&&i.replace(/.*(?=#[^\s]*$)/,"")),!e.parent("li").hasClass("active")){var r=n.find(".active:last a"),o=t.Event("hide.bs.tab",{relatedTarget:e[0]}),s=t.Event("show.bs.tab",{relatedTarget:r[0]});if(r.trigger(o),e.trigger(s),!s.isDefaultPrevented()&&!o.isDefaultPrevented()){var a=t(document).find(i);this.activate(e.closest("li"),n),this.activate(a,a.parent(),(function(){r.trigger({type:"hidden.bs.tab",relatedTarget:e[0]}),e.trigger({type:"shown.bs.tab",relatedTarget:r[0]})}))}}},e.prototype.activate=function(n,i,r){var o=i.find("> .active"),s=r&&t.support.transition&&(o.length&&o.hasClass("fade")||!!i.find("> .fade").length);function a(){o.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),n.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),s?(n[0].offsetWidth,n.addClass("in")):n.removeClass("fade"),n.parent(".dropdown-menu").length&&n.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),r&&r()}o.length&&s?o.one("bsTransitionEnd",a).emulateTransitionEnd(e.TRANSITION_DURATION):a(),o.removeClass("in")};var i=t.fn.tab;t.fn.tab=n,t.fn.tab.Constructor=e,t.fn.tab.noConflict=function(){return t.fn.tab=i,this};var r=function(e){e.preventDefault(),n.call(t(this),"show")};t(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',r).on("click.bs.tab.data-api",'[data-toggle="pill"]',r)}(n(755))},278:(t,e,n)=>{!function(t){"use strict";var e=["sanitize","whiteList","sanitizeFn"],n=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],i=/^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi,r=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i;function o(e,o){var s=e.nodeName.toLowerCase();if(-1!==t.inArray(s,o))return-1===t.inArray(s,n)||Boolean(e.nodeValue.match(i)||e.nodeValue.match(r));for(var a=t(o).filter((function(t,e){return e instanceof RegExp})),l=0,c=a.length;l
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0},sanitize:!0,sanitizeFn:null,whiteList:{"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]}},a.prototype.init=function(e,n,i){if(this.enabled=!0,this.type=e,this.$element=t(n),this.options=this.getOptions(i),this.$viewport=this.options.viewport&&t(document).find(t.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var r=this.options.trigger.split(" "),o=r.length;o--;){var s=r[o];if("click"==s)this.$element.on("click."+this.type,this.options.selector,t.proxy(this.toggle,this));else if("manual"!=s){var a="hover"==s?"mouseenter":"focusin",l="hover"==s?"mouseleave":"focusout";this.$element.on(a+"."+this.type,this.options.selector,t.proxy(this.enter,this)),this.$element.on(l+"."+this.type,this.options.selector,t.proxy(this.leave,this))}}this.options.selector?this._options=t.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},a.prototype.getDefaults=function(){return a.DEFAULTS},a.prototype.getOptions=function(n){var i=this.$element.data();for(var r in i)i.hasOwnProperty(r)&&-1!==t.inArray(r,e)&&delete i[r];return(n=t.extend({},this.getDefaults(),i,n)).delay&&"number"==typeof n.delay&&(n.delay={show:n.delay,hide:n.delay}),n.sanitize&&(n.template=s(n.template,n.whiteList,n.sanitizeFn)),n},a.prototype.getDelegateOptions=function(){var e={},n=this.getDefaults();return this._options&&t.each(this._options,(function(t,i){n[t]!=i&&(e[t]=i)})),e},a.prototype.enter=function(e){var n=e instanceof this.constructor?e:t(e.currentTarget).data("bs."+this.type);if(n||(n=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,n)),e instanceof t.Event&&(n.inState["focusin"==e.type?"focus":"hover"]=!0),n.tip().hasClass("in")||"in"==n.hoverState)n.hoverState="in";else{if(clearTimeout(n.timeout),n.hoverState="in",!n.options.delay||!n.options.delay.show)return n.show();n.timeout=setTimeout((function(){"in"==n.hoverState&&n.show()}),n.options.delay.show)}},a.prototype.isInStateTrue=function(){for(var t in this.inState)if(this.inState[t])return!0;return!1},a.prototype.leave=function(e){var n=e instanceof this.constructor?e:t(e.currentTarget).data("bs."+this.type);if(n||(n=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,n)),e instanceof t.Event&&(n.inState["focusout"==e.type?"focus":"hover"]=!1),!n.isInStateTrue()){if(clearTimeout(n.timeout),n.hoverState="out",!n.options.delay||!n.options.delay.hide)return n.hide();n.timeout=setTimeout((function(){"out"==n.hoverState&&n.hide()}),n.options.delay.hide)}},a.prototype.show=function(){var e=t.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(e);var n=t.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(e.isDefaultPrevented()||!n)return;var i=this,r=this.tip(),o=this.getUID(this.type);this.setContent(),r.attr("id",o),this.$element.attr("aria-describedby",o),this.options.animation&&r.addClass("fade");var s="function"==typeof this.options.placement?this.options.placement.call(this,r[0],this.$element[0]):this.options.placement,l=/\s?auto?\s?/i,c=l.test(s);c&&(s=s.replace(l,"")||"top"),r.detach().css({top:0,left:0,display:"block"}).addClass(s).data("bs."+this.type,this),this.options.container?r.appendTo(t(document).find(this.options.container)):r.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var u=this.getPosition(),p=r[0].offsetWidth,f=r[0].offsetHeight;if(c){var d=s,h=this.getPosition(this.$viewport);s="bottom"==s&&u.bottom+f>h.bottom?"top":"top"==s&&u.top-fh.width?"left":"left"==s&&u.left-ps.top+s.height&&(r.top=s.top+s.height-l)}else{var c=e.left-o,u=e.left+o+n;cs.right&&(r.left=s.left+s.width-u)}return r},a.prototype.getTitle=function(){var t=this.$element,e=this.options;return t.attr("data-original-title")||("function"==typeof e.title?e.title.call(t[0]):e.title)},a.prototype.getUID=function(t){do{t+=~~(1e6*Math.random())}while(document.getElementById(t));return t},a.prototype.tip=function(){if(!this.$tip&&(this.$tip=t(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},a.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},a.prototype.enable=function(){this.enabled=!0},a.prototype.disable=function(){this.enabled=!1},a.prototype.toggleEnabled=function(){this.enabled=!this.enabled},a.prototype.toggle=function(e){var n=this;e&&((n=t(e.currentTarget).data("bs."+this.type))||(n=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,n))),e?(n.inState.click=!n.inState.click,n.isInStateTrue()?n.enter(n):n.leave(n)):n.tip().hasClass("in")?n.leave(n):n.enter(n)},a.prototype.destroy=function(){var t=this;clearTimeout(this.timeout),this.hide((function(){t.$element.off("."+t.type).removeData("bs."+t.type),t.$tip&&t.$tip.detach(),t.$tip=null,t.$arrow=null,t.$viewport=null,t.$element=null}))},a.prototype.sanitizeHtml=function(t){return s(t,this.options.whiteList,this.options.sanitizeFn)};var l=t.fn.tooltip;t.fn.tooltip=function(e){return this.each((function(){var n=t(this),i=n.data("bs.tooltip"),r="object"==typeof e&&e;!i&&/destroy|hide/.test(e)||(i||n.data("bs.tooltip",i=new a(this,r)),"string"==typeof e&&i[e]())}))},t.fn.tooltip.Constructor=a,t.fn.tooltip.noConflict=function(){return t.fn.tooltip=l,this}}(n(755))},294:(t,e,n)=>{!function(t){"use strict";t.fn.emulateTransitionEnd=function(e){var n=!1,i=this;return t(this).one("bsTransitionEnd",(function(){n=!0})),setTimeout((function(){n||t(i).trigger(t.support.transition.end)}),e),this},t((function(){t.support.transition=function(){var t=document.createElement("bootstrap"),e={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var n in e)if(void 0!==t.style[n])return{end:e[n]};return!1}(),t.support.transition&&(t.event.special.bsTransitionEnd={bindType:t.support.transition.end,delegateType:t.support.transition.end,handle:function(e){if(t(e.target).is(this))return e.handleObj.handler.apply(this,arguments)}})}))}(n(755))},20:t=>{"use strict";var e="%[a-f0-9]{2}",n=new RegExp(e,"gi"),i=new RegExp("("+e+")+","gi");function r(t,e){try{return decodeURIComponent(t.join(""))}catch(t){}if(1===t.length)return t;e=e||1;var n=t.slice(0,e),i=t.slice(e);return Array.prototype.concat.call([],r(n),r(i))}function o(t){try{return decodeURIComponent(t)}catch(o){for(var e=t.match(n),i=1;i{"use strict";t.exports=function(t,e){for(var n={},i=Object.keys(t),r=Array.isArray(e),o=0;o0&&e-1 in t)}E.fn=E.prototype={jquery:C,constructor:E,length:0,toArray:function(){return a.call(this)},get:function(t){return null==t?a.call(this):t<0?this[t+this.length]:this[t]},pushStack:function(t){var e=E.merge(this.constructor(),t);return e.prevObject=this,e},each:function(t){return E.each(this,t)},map:function(t){return this.pushStack(E.map(this,(function(e,n){return t.call(e,n,e)})))},slice:function(){return this.pushStack(a.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(E.grep(this,(function(t,e){return(e+1)%2})))},odd:function(){return this.pushStack(E.grep(this,(function(t,e){return e%2})))},eq:function(t){var e=this.length,n=+t+(t<0?e:0);return this.pushStack(n>=0&&n+~]|[\\x20\\t\\r\\n\\f])[\\x20\\t\\r\\n\\f]*"),z=new RegExp(H+"|>"),V=new RegExp(U),X=new RegExp("^"+P+"$"),G={ID:new RegExp("^#("+P+")"),CLASS:new RegExp("^\\.("+P+")"),TAG:new RegExp("^("+P+"|[*])"),ATTR:new RegExp("^"+F),PSEUDO:new RegExp("^"+U),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\([\\x20\\t\\r\\n\\f]*(even|odd|(([+-]|)(\\d*)n|)[\\x20\\t\\r\\n\\f]*(?:([+-]|)[\\x20\\t\\r\\n\\f]*(\\d+)|))[\\x20\\t\\r\\n\\f]*\\)|)","i"),bool:new RegExp("^(?:"+q+")$","i"),needsContext:new RegExp("^[\\x20\\t\\r\\n\\f]*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\([\\x20\\t\\r\\n\\f]*((?:-\\d)?\\d*)[\\x20\\t\\r\\n\\f]*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,K=/^h\d$/i,J=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,tt=/[+~]/,et=new RegExp("\\\\[\\da-fA-F]{1,6}[\\x20\\t\\r\\n\\f]?|\\\\([^\\r\\n\\f])","g"),nt=function(t,e){var n="0x"+t.slice(1)-65536;return e||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},it=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,rt=function(t,e){return e?"\0"===t?"�":t.slice(0,-1)+"\\"+t.charCodeAt(t.length-1).toString(16)+" ":"\\"+t},ot=function(){f()},st=xt((function(t){return!0===t.disabled&&"fieldset"===t.nodeName.toLowerCase()}),{dir:"parentNode",next:"legend"});try{I.apply(D=L.call(w.childNodes),w.childNodes),D[w.childNodes.length].nodeType}catch(t){I={apply:D.length?function(t,e){O.apply(t,L.call(e))}:function(t,e){for(var n=t.length,i=0;t[n++]=e[i++];);t.length=n-1}}}function at(t,e,i,r){var o,a,c,u,p,h,v,y=e&&e.ownerDocument,w=e?e.nodeType:9;if(i=i||[],"string"!=typeof t||!t||1!==w&&9!==w&&11!==w)return i;if(!r&&(f(e),e=e||d,g)){if(11!==w&&(p=Z.exec(t)))if(o=p[1]){if(9===w){if(!(c=e.getElementById(o)))return i;if(c.id===o)return i.push(c),i}else if(y&&(c=y.getElementById(o))&&b(e,c)&&c.id===o)return i.push(c),i}else{if(p[2])return I.apply(i,e.getElementsByTagName(t)),i;if((o=p[3])&&n.getElementsByClassName&&e.getElementsByClassName)return I.apply(i,e.getElementsByClassName(o)),i}if(n.qsa&&!$[t+" "]&&(!m||!m.test(t))&&(1!==w||"object"!==e.nodeName.toLowerCase())){if(v=t,y=e,1===w&&(z.test(t)||_.test(t))){for((y=tt.test(t)&&vt(e.parentNode)||e)===e&&n.scope||((u=e.getAttribute("id"))?u=u.replace(it,rt):e.setAttribute("id",u=x)),a=(h=s(t)).length;a--;)h[a]=(u?"#"+u:":scope")+" "+bt(h[a]);v=h.join(",")}try{return I.apply(i,y.querySelectorAll(v)),i}catch(e){$(t,!0)}finally{u===x&&e.removeAttribute("id")}}}return l(t.replace(W,"$1"),e,i,r)}function lt(){var t=[];return function e(n,r){return t.push(n+" ")>i.cacheLength&&delete e[t.shift()],e[n+" "]=r}}function ct(t){return t[x]=!0,t}function ut(t){var e=d.createElement("fieldset");try{return!!t(e)}catch(t){return!1}finally{e.parentNode&&e.parentNode.removeChild(e),e=null}}function pt(t,e){for(var n=t.split("|"),r=n.length;r--;)i.attrHandle[n[r]]=e}function ft(t,e){var n=e&&t,i=n&&1===t.nodeType&&1===e.nodeType&&t.sourceIndex-e.sourceIndex;if(i)return i;if(n)for(;n=n.nextSibling;)if(n===e)return-1;return t?1:-1}function dt(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function ht(t){return function(e){var n=e.nodeName.toLowerCase();return("input"===n||"button"===n)&&e.type===t}}function gt(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&st(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function mt(t){return ct((function(e){return e=+e,ct((function(n,i){for(var r,o=t([],n.length,e),s=o.length;s--;)n[r=o[s]]&&(n[r]=!(i[r]=n[r]))}))}))}function vt(t){return t&&void 0!==t.getElementsByTagName&&t}for(e in n=at.support={},o=at.isXML=function(t){var e=t&&t.namespaceURI,n=t&&(t.ownerDocument||t).documentElement;return!Y.test(e||n&&n.nodeName||"HTML")},f=at.setDocument=function(t){var e,r,s=t?t.ownerDocument||t:w;return s!=d&&9===s.nodeType&&s.documentElement?(h=(d=s).documentElement,g=!o(d),w!=d&&(r=d.defaultView)&&r.top!==r&&(r.addEventListener?r.addEventListener("unload",ot,!1):r.attachEvent&&r.attachEvent("onunload",ot)),n.scope=ut((function(t){return h.appendChild(t).appendChild(d.createElement("div")),void 0!==t.querySelectorAll&&!t.querySelectorAll(":scope fieldset div").length})),n.attributes=ut((function(t){return t.className="i",!t.getAttribute("className")})),n.getElementsByTagName=ut((function(t){return t.appendChild(d.createComment("")),!t.getElementsByTagName("*").length})),n.getElementsByClassName=J.test(d.getElementsByClassName),n.getById=ut((function(t){return h.appendChild(t).id=x,!d.getElementsByName||!d.getElementsByName(x).length})),n.getById?(i.filter.ID=function(t){var e=t.replace(et,nt);return function(t){return t.getAttribute("id")===e}},i.find.ID=function(t,e){if(void 0!==e.getElementById&&g){var n=e.getElementById(t);return n?[n]:[]}}):(i.filter.ID=function(t){var e=t.replace(et,nt);return function(t){var n=void 0!==t.getAttributeNode&&t.getAttributeNode("id");return n&&n.value===e}},i.find.ID=function(t,e){if(void 0!==e.getElementById&&g){var n,i,r,o=e.getElementById(t);if(o){if((n=o.getAttributeNode("id"))&&n.value===t)return[o];for(r=e.getElementsByName(t),i=0;o=r[i++];)if((n=o.getAttributeNode("id"))&&n.value===t)return[o]}return[]}}),i.find.TAG=n.getElementsByTagName?function(t,e){return void 0!==e.getElementsByTagName?e.getElementsByTagName(t):n.qsa?e.querySelectorAll(t):void 0}:function(t,e){var n,i=[],r=0,o=e.getElementsByTagName(t);if("*"===t){for(;n=o[r++];)1===n.nodeType&&i.push(n);return i}return o},i.find.CLASS=n.getElementsByClassName&&function(t,e){if(void 0!==e.getElementsByClassName&&g)return e.getElementsByClassName(t)},v=[],m=[],(n.qsa=J.test(d.querySelectorAll))&&(ut((function(t){var e;h.appendChild(t).innerHTML="",t.querySelectorAll("[msallowcapture^='']").length&&m.push("[*^$]=[\\x20\\t\\r\\n\\f]*(?:''|\"\")"),t.querySelectorAll("[selected]").length||m.push("\\[[\\x20\\t\\r\\n\\f]*(?:value|"+q+")"),t.querySelectorAll("[id~="+x+"-]").length||m.push("~="),(e=d.createElement("input")).setAttribute("name",""),t.appendChild(e),t.querySelectorAll("[name='']").length||m.push("\\[[\\x20\\t\\r\\n\\f]*name[\\x20\\t\\r\\n\\f]*=[\\x20\\t\\r\\n\\f]*(?:''|\"\")"),t.querySelectorAll(":checked").length||m.push(":checked"),t.querySelectorAll("a#"+x+"+*").length||m.push(".#.+[+~]"),t.querySelectorAll("\\\f"),m.push("[\\r\\n\\f]")})),ut((function(t){t.innerHTML="";var e=d.createElement("input");e.setAttribute("type","hidden"),t.appendChild(e).setAttribute("name","D"),t.querySelectorAll("[name=d]").length&&m.push("name[\\x20\\t\\r\\n\\f]*[*^$|!~]?="),2!==t.querySelectorAll(":enabled").length&&m.push(":enabled",":disabled"),h.appendChild(t).disabled=!0,2!==t.querySelectorAll(":disabled").length&&m.push(":enabled",":disabled"),t.querySelectorAll("*,:x"),m.push(",.*:")}))),(n.matchesSelector=J.test(y=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ut((function(t){n.disconnectedMatch=y.call(t,"*"),y.call(t,"[s!='']:x"),v.push("!=",U)})),m=m.length&&new RegExp(m.join("|")),v=v.length&&new RegExp(v.join("|")),e=J.test(h.compareDocumentPosition),b=e||J.test(h.contains)?function(t,e){var n=9===t.nodeType?t.documentElement:t,i=e&&e.parentNode;return t===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):t.compareDocumentPosition&&16&t.compareDocumentPosition(i)))}:function(t,e){if(e)for(;e=e.parentNode;)if(e===t)return!0;return!1},A=e?function(t,e){if(t===e)return p=!0,0;var i=!t.compareDocumentPosition-!e.compareDocumentPosition;return i||(1&(i=(t.ownerDocument||t)==(e.ownerDocument||e)?t.compareDocumentPosition(e):1)||!n.sortDetached&&e.compareDocumentPosition(t)===i?t==d||t.ownerDocument==w&&b(w,t)?-1:e==d||e.ownerDocument==w&&b(w,e)?1:u?R(u,t)-R(u,e):0:4&i?-1:1)}:function(t,e){if(t===e)return p=!0,0;var n,i=0,r=t.parentNode,o=e.parentNode,s=[t],a=[e];if(!r||!o)return t==d?-1:e==d?1:r?-1:o?1:u?R(u,t)-R(u,e):0;if(r===o)return ft(t,e);for(n=t;n=n.parentNode;)s.unshift(n);for(n=e;n=n.parentNode;)a.unshift(n);for(;s[i]===a[i];)i++;return i?ft(s[i],a[i]):s[i]==w?-1:a[i]==w?1:0},d):d},at.matches=function(t,e){return at(t,null,null,e)},at.matchesSelector=function(t,e){if(f(t),n.matchesSelector&&g&&!$[e+" "]&&(!v||!v.test(e))&&(!m||!m.test(e)))try{var i=y.call(t,e);if(i||n.disconnectedMatch||t.document&&11!==t.document.nodeType)return i}catch(t){$(e,!0)}return at(e,d,null,[t]).length>0},at.contains=function(t,e){return(t.ownerDocument||t)!=d&&f(t),b(t,e)},at.attr=function(t,e){(t.ownerDocument||t)!=d&&f(t);var r=i.attrHandle[e.toLowerCase()],o=r&&N.call(i.attrHandle,e.toLowerCase())?r(t,e,!g):void 0;return void 0!==o?o:n.attributes||!g?t.getAttribute(e):(o=t.getAttributeNode(e))&&o.specified?o.value:null},at.escape=function(t){return(t+"").replace(it,rt)},at.error=function(t){throw new Error("Syntax error, unrecognized expression: "+t)},at.uniqueSort=function(t){var e,i=[],r=0,o=0;if(p=!n.detectDuplicates,u=!n.sortStable&&t.slice(0),t.sort(A),p){for(;e=t[o++];)e===t[o]&&(r=i.push(o));for(;r--;)t.splice(i[r],1)}return u=null,t},r=at.getText=function(t){var e,n="",i=0,o=t.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof t.textContent)return t.textContent;for(t=t.firstChild;t;t=t.nextSibling)n+=r(t)}else if(3===o||4===o)return t.nodeValue}else for(;e=t[i++];)n+=r(e);return n},i=at.selectors={cacheLength:50,createPseudo:ct,match:G,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(t){return t[1]=t[1].replace(et,nt),t[3]=(t[3]||t[4]||t[5]||"").replace(et,nt),"~="===t[2]&&(t[3]=" "+t[3]+" "),t.slice(0,4)},CHILD:function(t){return t[1]=t[1].toLowerCase(),"nth"===t[1].slice(0,3)?(t[3]||at.error(t[0]),t[4]=+(t[4]?t[5]+(t[6]||1):2*("even"===t[3]||"odd"===t[3])),t[5]=+(t[7]+t[8]||"odd"===t[3])):t[3]&&at.error(t[0]),t},PSEUDO:function(t){var e,n=!t[6]&&t[2];return G.CHILD.test(t[0])?null:(t[3]?t[2]=t[4]||t[5]||"":n&&V.test(n)&&(e=s(n,!0))&&(e=n.indexOf(")",n.length-e)-n.length)&&(t[0]=t[0].slice(0,e),t[2]=n.slice(0,e)),t.slice(0,3))}},filter:{TAG:function(t){var e=t.replace(et,nt).toLowerCase();return"*"===t?function(){return!0}:function(t){return t.nodeName&&t.nodeName.toLowerCase()===e}},CLASS:function(t){var e=E[t+" "];return e||(e=new RegExp("(^|[\\x20\\t\\r\\n\\f])"+t+"("+H+"|$)"))&&E(t,(function(t){return e.test("string"==typeof t.className&&t.className||void 0!==t.getAttribute&&t.getAttribute("class")||"")}))},ATTR:function(t,e,n){return function(i){var r=at.attr(i,t);return null==r?"!="===e:!e||(r+="","="===e?r===n:"!="===e?r!==n:"^="===e?n&&0===r.indexOf(n):"*="===e?n&&r.indexOf(n)>-1:"$="===e?n&&r.slice(-n.length)===n:"~="===e?(" "+r.replace(M," ")+" ").indexOf(n)>-1:"|="===e&&(r===n||r.slice(0,n.length+1)===n+"-"))}},CHILD:function(t,e,n,i,r){var o="nth"!==t.slice(0,3),s="last"!==t.slice(-4),a="of-type"===e;return 1===i&&0===r?function(t){return!!t.parentNode}:function(e,n,l){var c,u,p,f,d,h,g=o!==s?"nextSibling":"previousSibling",m=e.parentNode,v=a&&e.nodeName.toLowerCase(),y=!l&&!a,b=!1;if(m){if(o){for(;g;){for(f=e;f=f[g];)if(a?f.nodeName.toLowerCase()===v:1===f.nodeType)return!1;h=g="only"===t&&!h&&"nextSibling"}return!0}if(h=[s?m.firstChild:m.lastChild],s&&y){for(b=(d=(c=(u=(p=(f=m)[x]||(f[x]={}))[f.uniqueID]||(p[f.uniqueID]={}))[t]||[])[0]===T&&c[1])&&c[2],f=d&&m.childNodes[d];f=++d&&f&&f[g]||(b=d=0)||h.pop();)if(1===f.nodeType&&++b&&f===e){u[t]=[T,d,b];break}}else if(y&&(b=d=(c=(u=(p=(f=e)[x]||(f[x]={}))[f.uniqueID]||(p[f.uniqueID]={}))[t]||[])[0]===T&&c[1]),!1===b)for(;(f=++d&&f&&f[g]||(b=d=0)||h.pop())&&((a?f.nodeName.toLowerCase()!==v:1!==f.nodeType)||!++b||(y&&((u=(p=f[x]||(f[x]={}))[f.uniqueID]||(p[f.uniqueID]={}))[t]=[T,b]),f!==e)););return(b-=r)===i||b%i==0&&b/i>=0}}},PSEUDO:function(t,e){var n,r=i.pseudos[t]||i.setFilters[t.toLowerCase()]||at.error("unsupported pseudo: "+t);return r[x]?r(e):r.length>1?(n=[t,t,"",e],i.setFilters.hasOwnProperty(t.toLowerCase())?ct((function(t,n){for(var i,o=r(t,e),s=o.length;s--;)t[i=R(t,o[s])]=!(n[i]=o[s])})):function(t){return r(t,0,n)}):r}},pseudos:{not:ct((function(t){var e=[],n=[],i=a(t.replace(W,"$1"));return i[x]?ct((function(t,e,n,r){for(var o,s=i(t,null,r,[]),a=t.length;a--;)(o=s[a])&&(t[a]=!(e[a]=o))})):function(t,r,o){return e[0]=t,i(e,null,o,n),e[0]=null,!n.pop()}})),has:ct((function(t){return function(e){return at(t,e).length>0}})),contains:ct((function(t){return t=t.replace(et,nt),function(e){return(e.textContent||r(e)).indexOf(t)>-1}})),lang:ct((function(t){return X.test(t||"")||at.error("unsupported lang: "+t),t=t.replace(et,nt).toLowerCase(),function(e){var n;do{if(n=g?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(n=n.toLowerCase())===t||0===n.indexOf(t+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}})),target:function(e){var n=t.location&&t.location.hash;return n&&n.slice(1)===e.id},root:function(t){return t===h},focus:function(t){return t===d.activeElement&&(!d.hasFocus||d.hasFocus())&&!!(t.type||t.href||~t.tabIndex)},enabled:gt(!1),disabled:gt(!0),checked:function(t){var e=t.nodeName.toLowerCase();return"input"===e&&!!t.checked||"option"===e&&!!t.selected},selected:function(t){return t.parentNode&&t.parentNode.selectedIndex,!0===t.selected},empty:function(t){for(t=t.firstChild;t;t=t.nextSibling)if(t.nodeType<6)return!1;return!0},parent:function(t){return!i.pseudos.empty(t)},header:function(t){return K.test(t.nodeName)},input:function(t){return Q.test(t.nodeName)},button:function(t){var e=t.nodeName.toLowerCase();return"input"===e&&"button"===t.type||"button"===e},text:function(t){var e;return"input"===t.nodeName.toLowerCase()&&"text"===t.type&&(null==(e=t.getAttribute("type"))||"text"===e.toLowerCase())},first:mt((function(){return[0]})),last:mt((function(t,e){return[e-1]})),eq:mt((function(t,e,n){return[n<0?n+e:n]})),even:mt((function(t,e){for(var n=0;ne?e:n;--i>=0;)t.push(i);return t})),gt:mt((function(t,e,n){for(var i=n<0?n+e:n;++i1?function(e,n,i){for(var r=t.length;r--;)if(!t[r](e,n,i))return!1;return!0}:t[0]}function Tt(t,e,n,i,r){for(var o,s=[],a=0,l=t.length,c=null!=e;a-1&&(o[c]=!(s[c]=p))}}else v=Tt(v===s?v.splice(h,v.length):v),r?r(null,s,v,l):I.apply(s,v)}))}function Et(t){for(var e,n,r,o=t.length,s=i.relative[t[0].type],a=s||i.relative[" "],l=s?1:0,u=xt((function(t){return t===e}),a,!0),p=xt((function(t){return R(e,t)>-1}),a,!0),f=[function(t,n,i){var r=!s&&(i||n!==c)||((e=n).nodeType?u(t,n,i):p(t,n,i));return e=null,r}];l1&&wt(f),l>1&&bt(t.slice(0,l-1).concat({value:" "===t[l-2].type?"*":""})).replace(W,"$1"),n,l0,r=t.length>0,o=function(o,s,a,l,u){var p,h,m,v=0,y="0",b=o&&[],x=[],w=c,C=o||r&&i.find.TAG("*",u),E=T+=null==w?1:Math.random()||.1,S=C.length;for(u&&(c=s==d||s||u);y!==S&&null!=(p=C[y]);y++){if(r&&p){for(h=0,s||p.ownerDocument==d||(f(p),a=!g);m=t[h++];)if(m(p,s||d,a)){l.push(p);break}u&&(T=E)}n&&((p=!m&&p)&&v--,o&&b.push(p))}if(v+=y,n&&y!==v){for(h=0;m=e[h++];)m(b,x,s,a);if(o){if(v>0)for(;y--;)b[y]||x[y]||(x[y]=j.call(l));x=Tt(x)}I.apply(l,x),u&&!o&&x.length>0&&v+e.length>1&&at.uniqueSort(l)}return u&&(T=E,c=w),b};return n?ct(o):o}(o,r)),a.selector=t}return a},l=at.select=function(t,e,n,r){var o,l,c,u,p,f="function"==typeof t&&t,d=!r&&s(t=f.selector||t);if(n=n||[],1===d.length){if((l=d[0]=d[0].slice(0)).length>2&&"ID"===(c=l[0]).type&&9===e.nodeType&&g&&i.relative[l[1].type]){if(!(e=(i.find.ID(c.matches[0].replace(et,nt),e)||[])[0]))return n;f&&(e=e.parentNode),t=t.slice(l.shift().value.length)}for(o=G.needsContext.test(t)?0:l.length;o--&&(c=l[o],!i.relative[u=c.type]);)if((p=i.find[u])&&(r=p(c.matches[0].replace(et,nt),tt.test(l[0].type)&&vt(e.parentNode)||e))){if(l.splice(o,1),!(t=r.length&&bt(l)))return I.apply(n,r),n;break}}return(f||a(t,d))(r,e,!g,n,!e||tt.test(t)&&vt(e.parentNode)||e),n},n.sortStable=x.split("").sort(A).join("")===x,n.detectDuplicates=!!p,f(),n.sortDetached=ut((function(t){return 1&t.compareDocumentPosition(d.createElement("fieldset"))})),ut((function(t){return t.innerHTML="","#"===t.firstChild.getAttribute("href")}))||pt("type|href|height|width",(function(t,e,n){if(!n)return t.getAttribute(e,"type"===e.toLowerCase()?1:2)})),n.attributes&&ut((function(t){return t.innerHTML="",t.firstChild.setAttribute("value",""),""===t.firstChild.getAttribute("value")}))||pt("value",(function(t,e,n){if(!n&&"input"===t.nodeName.toLowerCase())return t.defaultValue})),ut((function(t){return null==t.getAttribute("disabled")}))||pt(q,(function(t,e,n){var i;if(!n)return!0===t[e]?e.toLowerCase():(i=t.getAttributeNode(e))&&i.specified?i.value:null})),at}(i);E.find=k,E.expr=k.selectors,E.expr[":"]=E.expr.pseudos,E.uniqueSort=E.unique=k.uniqueSort,E.text=k.getText,E.isXMLDoc=k.isXML,E.contains=k.contains,E.escapeSelector=k.escape;var $=function(t,e,n){for(var i=[],r=void 0!==n;(t=t[e])&&9!==t.nodeType;)if(1===t.nodeType){if(r&&E(t).is(n))break;i.push(t)}return i},A=function(t,e){for(var n=[];t;t=t.nextSibling)1===t.nodeType&&t!==e&&n.push(t);return n},N=E.expr.match.needsContext;function D(t,e){return t.nodeName&&t.nodeName.toLowerCase()===e.toLowerCase()}var j=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function O(t,e,n){return v(e)?E.grep(t,(function(t,i){return!!e.call(t,i,t)!==n})):e.nodeType?E.grep(t,(function(t){return t===e!==n})):"string"!=typeof e?E.grep(t,(function(t){return u.call(e,t)>-1!==n})):E.filter(e,t,n)}E.filter=function(t,e,n){var i=e[0];return n&&(t=":not("+t+")"),1===e.length&&1===i.nodeType?E.find.matchesSelector(i,t)?[i]:[]:E.find.matches(t,E.grep(e,(function(t){return 1===t.nodeType})))},E.fn.extend({find:function(t){var e,n,i=this.length,r=this;if("string"!=typeof t)return this.pushStack(E(t).filter((function(){for(e=0;e1?E.uniqueSort(n):n},filter:function(t){return this.pushStack(O(this,t||[],!1))},not:function(t){return this.pushStack(O(this,t||[],!0))},is:function(t){return!!O(this,"string"==typeof t&&N.test(t)?E(t):t||[],!1).length}});var I,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(E.fn.init=function(t,e,n){var i,r;if(!t)return this;if(n=n||I,"string"==typeof t){if(!(i="<"===t[0]&&">"===t[t.length-1]&&t.length>=3?[null,t,null]:L.exec(t))||!i[1]&&e)return!e||e.jquery?(e||n).find(t):this.constructor(e).find(t);if(i[1]){if(e=e instanceof E?e[0]:e,E.merge(this,E.parseHTML(i[1],e&&e.nodeType?e.ownerDocument||e:b,!0)),j.test(i[1])&&E.isPlainObject(e))for(i in e)v(this[i])?this[i](e[i]):this.attr(i,e[i]);return this}return(r=b.getElementById(i[2]))&&(this[0]=r,this.length=1),this}return t.nodeType?(this[0]=t,this.length=1,this):v(t)?void 0!==n.ready?n.ready(t):t(E):E.makeArray(t,this)}).prototype=E.fn,I=E(b);var R=/^(?:parents|prev(?:Until|All))/,q={children:!0,contents:!0,next:!0,prev:!0};function H(t,e){for(;(t=t[e])&&1!==t.nodeType;);return t}E.fn.extend({has:function(t){var e=E(t,this),n=e.length;return this.filter((function(){for(var t=0;t-1:1===n.nodeType&&E.find.matchesSelector(n,t))){o.push(n);break}return this.pushStack(o.length>1?E.uniqueSort(o):o)},index:function(t){return t?"string"==typeof t?u.call(E(t),this[0]):u.call(this,t.jquery?t[0]:t):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(t,e){return this.pushStack(E.uniqueSort(E.merge(this.get(),E(t,e))))},addBack:function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}}),E.each({parent:function(t){var e=t.parentNode;return e&&11!==e.nodeType?e:null},parents:function(t){return $(t,"parentNode")},parentsUntil:function(t,e,n){return $(t,"parentNode",n)},next:function(t){return H(t,"nextSibling")},prev:function(t){return H(t,"previousSibling")},nextAll:function(t){return $(t,"nextSibling")},prevAll:function(t){return $(t,"previousSibling")},nextUntil:function(t,e,n){return $(t,"nextSibling",n)},prevUntil:function(t,e,n){return $(t,"previousSibling",n)},siblings:function(t){return A((t.parentNode||{}).firstChild,t)},children:function(t){return A(t.firstChild)},contents:function(t){return null!=t.contentDocument&&s(t.contentDocument)?t.contentDocument:(D(t,"template")&&(t=t.content||t),E.merge([],t.childNodes))}},(function(t,e){E.fn[t]=function(n,i){var r=E.map(this,e,n);return"Until"!==t.slice(-5)&&(i=n),i&&"string"==typeof i&&(r=E.filter(i,r)),this.length>1&&(q[t]||E.uniqueSort(r),R.test(t)&&r.reverse()),this.pushStack(r)}}));var P=/[^\x20\t\r\n\f]+/g;function F(t){return t}function U(t){throw t}function M(t,e,n,i){var r;try{t&&v(r=t.promise)?r.call(t).done(e).fail(n):t&&v(r=t.then)?r.call(t,e,n):e.apply(void 0,[t].slice(i))}catch(t){n.apply(void 0,[t])}}E.Callbacks=function(t){t="string"==typeof t?function(t){var e={};return E.each(t.match(P)||[],(function(t,n){e[n]=!0})),e}(t):E.extend({},t);var e,n,i,r,o=[],s=[],a=-1,l=function(){for(r=r||t.once,i=e=!0;s.length;a=-1)for(n=s.shift();++a-1;)o.splice(n,1),n<=a&&a--})),this},has:function(t){return t?E.inArray(t,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return r=s=[],o=n="",this},disabled:function(){return!o},lock:function(){return r=s=[],n||e||(o=n=""),this},locked:function(){return!!r},fireWith:function(t,n){return r||(n=[t,(n=n||[]).slice?n.slice():n],s.push(n),e||l()),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!i}};return c},E.extend({Deferred:function(t){var e=[["notify","progress",E.Callbacks("memory"),E.Callbacks("memory"),2],["resolve","done",E.Callbacks("once memory"),E.Callbacks("once memory"),0,"resolved"],["reject","fail",E.Callbacks("once memory"),E.Callbacks("once memory"),1,"rejected"]],n="pending",r={state:function(){return n},always:function(){return o.done(arguments).fail(arguments),this},catch:function(t){return r.then(null,t)},pipe:function(){var t=arguments;return E.Deferred((function(n){E.each(e,(function(e,i){var r=v(t[i[4]])&&t[i[4]];o[i[1]]((function(){var t=r&&r.apply(this,arguments);t&&v(t.promise)?t.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[i[0]+"With"](this,r?[t]:arguments)}))})),t=null})).promise()},then:function(t,n,r){var o=0;function s(t,e,n,r){return function(){var a=this,l=arguments,c=function(){var i,c;if(!(t=o&&(n!==U&&(a=void 0,l=[i]),e.rejectWith(a,l))}};t?u():(E.Deferred.getStackHook&&(u.stackTrace=E.Deferred.getStackHook()),i.setTimeout(u))}}return E.Deferred((function(i){e[0][3].add(s(0,i,v(r)?r:F,i.notifyWith)),e[1][3].add(s(0,i,v(t)?t:F)),e[2][3].add(s(0,i,v(n)?n:U))})).promise()},promise:function(t){return null!=t?E.extend(t,r):r}},o={};return E.each(e,(function(t,i){var s=i[2],a=i[5];r[i[1]]=s.add,a&&s.add((function(){n=a}),e[3-t][2].disable,e[3-t][3].disable,e[0][2].lock,e[0][3].lock),s.add(i[3].fire),o[i[0]]=function(){return o[i[0]+"With"](this===o?void 0:this,arguments),this},o[i[0]+"With"]=s.fireWith})),r.promise(o),t&&t.call(o,o),o},when:function(t){var e=arguments.length,n=e,i=Array(n),r=a.call(arguments),o=E.Deferred(),s=function(t){return function(n){i[t]=this,r[t]=arguments.length>1?a.call(arguments):n,--e||o.resolveWith(i,r)}};if(e<=1&&(M(t,o.done(s(n)).resolve,o.reject,!e),"pending"===o.state()||v(r[n]&&r[n].then)))return o.then();for(;n--;)M(r[n],s(n),o.reject);return o.promise()}});var W=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;E.Deferred.exceptionHook=function(t,e){i.console&&i.console.warn&&t&&W.test(t.name)&&i.console.warn("jQuery.Deferred exception: "+t.message,t.stack,e)},E.readyException=function(t){i.setTimeout((function(){throw t}))};var B=E.Deferred();function _(){b.removeEventListener("DOMContentLoaded",_),i.removeEventListener("load",_),E.ready()}E.fn.ready=function(t){return B.then(t).catch((function(t){E.readyException(t)})),this},E.extend({isReady:!1,readyWait:1,ready:function(t){(!0===t?--E.readyWait:E.isReady)||(E.isReady=!0,!0!==t&&--E.readyWait>0||B.resolveWith(b,[E]))}}),E.ready.then=B.then,"complete"===b.readyState||"loading"!==b.readyState&&!b.documentElement.doScroll?i.setTimeout(E.ready):(b.addEventListener("DOMContentLoaded",_),i.addEventListener("load",_));var z=function(t,e,n,i,r,o,s){var a=0,l=t.length,c=null==n;if("object"===T(n))for(a in r=!0,n)z(t,e,a,n[a],!0,o,s);else if(void 0!==i&&(r=!0,v(i)||(s=!0),c&&(s?(e.call(t,i),e=null):(c=e,e=function(t,e,n){return c.call(E(t),n)})),e))for(;a1,null,!0)},removeData:function(t){return this.each((function(){Z.remove(this,t)}))}}),E.extend({queue:function(t,e,n){var i;if(t)return e=(e||"fx")+"queue",i=J.get(t,e),n&&(!i||Array.isArray(n)?i=J.access(t,e,E.makeArray(n)):i.push(n)),i||[]},dequeue:function(t,e){e=e||"fx";var n=E.queue(t,e),i=n.length,r=n.shift(),o=E._queueHooks(t,e);"inprogress"===r&&(r=n.shift(),i--),r&&("fx"===e&&n.unshift("inprogress"),delete o.stop,r.call(t,(function(){E.dequeue(t,e)}),o)),!i&&o&&o.empty.fire()},_queueHooks:function(t,e){var n=e+"queueHooks";return J.get(t,n)||J.access(t,n,{empty:E.Callbacks("once memory").add((function(){J.remove(t,[e+"queue",n])}))})}}),E.fn.extend({queue:function(t,e){var n=2;return"string"!=typeof t&&(e=t,t="fx",n--),arguments.length\x20\t\r\n\f]*)/i,yt=/^$|^module$|\/(?:java|ecma)script/i;ht=b.createDocumentFragment().appendChild(b.createElement("div")),(gt=b.createElement("input")).setAttribute("type","radio"),gt.setAttribute("checked","checked"),gt.setAttribute("name","t"),ht.appendChild(gt),m.checkClone=ht.cloneNode(!0).cloneNode(!0).lastChild.checked,ht.innerHTML="",m.noCloneChecked=!!ht.cloneNode(!0).lastChild.defaultValue,ht.innerHTML="",m.option=!!ht.lastChild;var bt={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function xt(t,e){var n;return n=void 0!==t.getElementsByTagName?t.getElementsByTagName(e||"*"):void 0!==t.querySelectorAll?t.querySelectorAll(e||"*"):[],void 0===e||e&&D(t,e)?E.merge([t],n):n}function wt(t,e){for(var n=0,i=t.length;n",""]);var Tt=/<|&#?\w+;/;function Ct(t,e,n,i,r){for(var o,s,a,l,c,u,p=e.createDocumentFragment(),f=[],d=0,h=t.length;d-1)r&&r.push(o);else if(c=at(o),s=xt(p.appendChild(o),"script"),c&&wt(s),n)for(u=0;o=s[u++];)yt.test(o.type||"")&&n.push(o);return p}var Et=/^([^.]*)(?:\.(.+)|)/;function St(){return!0}function kt(){return!1}function $t(t,e){return t===function(){try{return b.activeElement}catch(t){}}()==("focus"===e)}function At(t,e,n,i,r,o){var s,a;if("object"==typeof e){for(a in"string"!=typeof n&&(i=i||n,n=void 0),e)At(t,a,n,i,e[a],o);return t}if(null==i&&null==r?(r=n,i=n=void 0):null==r&&("string"==typeof n?(r=i,i=void 0):(r=i,i=n,n=void 0)),!1===r)r=kt;else if(!r)return t;return 1===o&&(s=r,r=function(t){return E().off(t),s.apply(this,arguments)},r.guid=s.guid||(s.guid=E.guid++)),t.each((function(){E.event.add(this,e,r,i,n)}))}function Nt(t,e,n){n?(J.set(t,e,!1),E.event.add(t,e,{namespace:!1,handler:function(t){var i,r,o=J.get(this,e);if(1&t.isTrigger&&this[e]){if(o.length)(E.event.special[e]||{}).delegateType&&t.stopPropagation();else if(o=a.call(arguments),J.set(this,e,o),i=n(this,e),this[e](),o!==(r=J.get(this,e))||i?J.set(this,e,!1):r={},o!==r)return t.stopImmediatePropagation(),t.preventDefault(),r&&r.value}else o.length&&(J.set(this,e,{value:E.event.trigger(E.extend(o[0],E.Event.prototype),o.slice(1),this)}),t.stopImmediatePropagation())}})):void 0===J.get(t,e)&&E.event.add(t,e,St)}E.event={global:{},add:function(t,e,n,i,r){var o,s,a,l,c,u,p,f,d,h,g,m=J.get(t);if(Q(t))for(n.handler&&(n=(o=n).handler,r=o.selector),r&&E.find.matchesSelector(st,r),n.guid||(n.guid=E.guid++),(l=m.events)||(l=m.events=Object.create(null)),(s=m.handle)||(s=m.handle=function(e){return void 0!==E&&E.event.triggered!==e.type?E.event.dispatch.apply(t,arguments):void 0}),c=(e=(e||"").match(P)||[""]).length;c--;)d=g=(a=Et.exec(e[c])||[])[1],h=(a[2]||"").split(".").sort(),d&&(p=E.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,p=E.event.special[d]||{},u=E.extend({type:d,origType:g,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&E.expr.match.needsContext.test(r),namespace:h.join(".")},o),(f=l[d])||((f=l[d]=[]).delegateCount=0,p.setup&&!1!==p.setup.call(t,i,h,s)||t.addEventListener&&t.addEventListener(d,s)),p.add&&(p.add.call(t,u),u.handler.guid||(u.handler.guid=n.guid)),r?f.splice(f.delegateCount++,0,u):f.push(u),E.event.global[d]=!0)},remove:function(t,e,n,i,r){var o,s,a,l,c,u,p,f,d,h,g,m=J.hasData(t)&&J.get(t);if(m&&(l=m.events)){for(c=(e=(e||"").match(P)||[""]).length;c--;)if(d=g=(a=Et.exec(e[c])||[])[1],h=(a[2]||"").split(".").sort(),d){for(p=E.event.special[d]||{},f=l[d=(i?p.delegateType:p.bindType)||d]||[],a=a[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=o=f.length;o--;)u=f[o],!r&&g!==u.origType||n&&n.guid!==u.guid||a&&!a.test(u.namespace)||i&&i!==u.selector&&("**"!==i||!u.selector)||(f.splice(o,1),u.selector&&f.delegateCount--,p.remove&&p.remove.call(t,u));s&&!f.length&&(p.teardown&&!1!==p.teardown.call(t,h,m.handle)||E.removeEvent(t,d,m.handle),delete l[d])}else for(d in l)E.event.remove(t,d+e[c],n,i,!0);E.isEmptyObject(l)&&J.remove(t,"handle events")}},dispatch:function(t){var e,n,i,r,o,s,a=new Array(arguments.length),l=E.event.fix(t),c=(J.get(this,"events")||Object.create(null))[l.type]||[],u=E.event.special[l.type]||{};for(a[0]=l,e=1;e=1))for(;c!==this;c=c.parentNode||this)if(1===c.nodeType&&("click"!==t.type||!0!==c.disabled)){for(o=[],s={},n=0;n-1:E.find(r,this,null,[c]).length),s[r]&&o.push(i);o.length&&a.push({elem:c,handlers:o})}return c=this,l\s*$/g;function It(t,e){return D(t,"table")&&D(11!==e.nodeType?e:e.firstChild,"tr")&&E(t).children("tbody")[0]||t}function Lt(t){return t.type=(null!==t.getAttribute("type"))+"/"+t.type,t}function Rt(t){return"true/"===(t.type||"").slice(0,5)?t.type=t.type.slice(5):t.removeAttribute("type"),t}function qt(t,e){var n,i,r,o,s,a;if(1===e.nodeType){if(J.hasData(t)&&(a=J.get(t).events))for(r in J.remove(e,"handle events"),a)for(n=0,i=a[r].length;n1&&"string"==typeof h&&!m.checkClone&&jt.test(h))return t.each((function(r){var o=t.eq(r);g&&(e[0]=h.call(this,r,o.html())),Pt(o,e,n,i)}));if(f&&(o=(r=Ct(e,t[0].ownerDocument,!1,t,i)).firstChild,1===r.childNodes.length&&(r=o),o||i)){for(a=(s=E.map(xt(r,"script"),Lt)).length;p0&&wt(s,!l&&xt(t,"script")),a},cleanData:function(t){for(var e,n,i,r=E.event.special,o=0;void 0!==(n=t[o]);o++)if(Q(n)){if(e=n[J.expando]){if(e.events)for(i in e.events)r[i]?E.event.remove(n,i):E.removeEvent(n,i,e.handle);n[J.expando]=void 0}n[Z.expando]&&(n[Z.expando]=void 0)}}}),E.fn.extend({detach:function(t){return Ft(this,t,!0)},remove:function(t){return Ft(this,t)},text:function(t){return z(this,(function(t){return void 0===t?E.text(this):this.empty().each((function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=t)}))}),null,t,arguments.length)},append:function(){return Pt(this,arguments,(function(t){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||It(this,t).appendChild(t)}))},prepend:function(){return Pt(this,arguments,(function(t){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var e=It(this,t);e.insertBefore(t,e.firstChild)}}))},before:function(){return Pt(this,arguments,(function(t){this.parentNode&&this.parentNode.insertBefore(t,this)}))},after:function(){return Pt(this,arguments,(function(t){this.parentNode&&this.parentNode.insertBefore(t,this.nextSibling)}))},empty:function(){for(var t,e=0;null!=(t=this[e]);e++)1===t.nodeType&&(E.cleanData(xt(t,!1)),t.textContent="");return this},clone:function(t,e){return t=null!=t&&t,e=null==e?t:e,this.map((function(){return E.clone(this,t,e)}))},html:function(t){return z(this,(function(t){var e=this[0]||{},n=0,i=this.length;if(void 0===t&&1===e.nodeType)return e.innerHTML;if("string"==typeof t&&!Dt.test(t)&&!bt[(vt.exec(t)||["",""])[1].toLowerCase()]){t=E.htmlPrefilter(t);try{for(;n=0&&(l+=Math.max(0,Math.ceil(t["offset"+e[0].toUpperCase()+e.slice(1)]-o-l-a-.5))||0),l}function ne(t,e,n){var i=Mt(t),r=(!m.boxSizingReliable()||n)&&"border-box"===E.css(t,"boxSizing",!1,i),o=r,s=_t(t,e,i),a="offset"+e[0].toUpperCase()+e.slice(1);if(Ut.test(s)){if(!n)return s;s="auto"}return(!m.boxSizingReliable()&&r||!m.reliableTrDimensions()&&D(t,"tr")||"auto"===s||!parseFloat(s)&&"inline"===E.css(t,"display",!1,i))&&t.getClientRects().length&&(r="border-box"===E.css(t,"boxSizing",!1,i),(o=a in t)&&(s=t[a])),(s=parseFloat(s)||0)+ee(t,e,n||(r?"border":"content"),o,i,s)+"px"}function ie(t,e,n,i,r){return new ie.prototype.init(t,e,n,i,r)}E.extend({cssHooks:{opacity:{get:function(t,e){if(e){var n=_t(t,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(t,e,n,i){if(t&&3!==t.nodeType&&8!==t.nodeType&&t.style){var r,o,s,a=Y(e),l=Kt.test(e),c=t.style;if(l||(e=Yt(a)),s=E.cssHooks[e]||E.cssHooks[a],void 0===n)return s&&"get"in s&&void 0!==(r=s.get(t,!1,i))?r:c[e];"string"==(o=typeof n)&&(r=rt.exec(n))&&r[1]&&(n=ut(t,e,r),o="number"),null!=n&&n==n&&("number"!==o||l||(n+=r&&r[3]||(E.cssNumber[a]?"":"px")),m.clearCloneStyle||""!==n||0!==e.indexOf("background")||(c[e]="inherit"),s&&"set"in s&&void 0===(n=s.set(t,n,i))||(l?c.setProperty(e,n):c[e]=n))}},css:function(t,e,n,i){var r,o,s,a=Y(e);return Kt.test(e)||(e=Yt(a)),(s=E.cssHooks[e]||E.cssHooks[a])&&"get"in s&&(r=s.get(t,!0,n)),void 0===r&&(r=_t(t,e,i)),"normal"===r&&e in Zt&&(r=Zt[e]),""===n||n?(o=parseFloat(r),!0===n||isFinite(o)?o||0:r):r}}),E.each(["height","width"],(function(t,e){E.cssHooks[e]={get:function(t,n,i){if(n)return!Qt.test(E.css(t,"display"))||t.getClientRects().length&&t.getBoundingClientRect().width?ne(t,e,i):Wt(t,Jt,(function(){return ne(t,e,i)}))},set:function(t,n,i){var r,o=Mt(t),s=!m.scrollboxSize()&&"absolute"===o.position,a=(s||i)&&"border-box"===E.css(t,"boxSizing",!1,o),l=i?ee(t,e,i,a,o):0;return a&&s&&(l-=Math.ceil(t["offset"+e[0].toUpperCase()+e.slice(1)]-parseFloat(o[e])-ee(t,e,"border",!1,o)-.5)),l&&(r=rt.exec(n))&&"px"!==(r[3]||"px")&&(t.style[e]=n,n=E.css(t,e)),te(0,n,l)}}})),E.cssHooks.marginLeft=zt(m.reliableMarginLeft,(function(t,e){if(e)return(parseFloat(_t(t,"marginLeft"))||t.getBoundingClientRect().left-Wt(t,{marginLeft:0},(function(){return t.getBoundingClientRect().left})))+"px"})),E.each({margin:"",padding:"",border:"Width"},(function(t,e){E.cssHooks[t+e]={expand:function(n){for(var i=0,r={},o="string"==typeof n?n.split(" "):[n];i<4;i++)r[t+ot[i]+e]=o[i]||o[i-2]||o[0];return r}},"margin"!==t&&(E.cssHooks[t+e].set=te)})),E.fn.extend({css:function(t,e){return z(this,(function(t,e,n){var i,r,o={},s=0;if(Array.isArray(e)){for(i=Mt(t),r=e.length;s1)}}),E.Tween=ie,ie.prototype={constructor:ie,init:function(t,e,n,i,r,o){this.elem=t,this.prop=n,this.easing=r||E.easing._default,this.options=e,this.start=this.now=this.cur(),this.end=i,this.unit=o||(E.cssNumber[n]?"":"px")},cur:function(){var t=ie.propHooks[this.prop];return t&&t.get?t.get(this):ie.propHooks._default.get(this)},run:function(t){var e,n=ie.propHooks[this.prop];return this.options.duration?this.pos=e=E.easing[this.easing](t,this.options.duration*t,0,1,this.options.duration):this.pos=e=t,this.now=(this.end-this.start)*e+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):ie.propHooks._default.set(this),this}},ie.prototype.init.prototype=ie.prototype,ie.propHooks={_default:{get:function(t){var e;return 1!==t.elem.nodeType||null!=t.elem[t.prop]&&null==t.elem.style[t.prop]?t.elem[t.prop]:(e=E.css(t.elem,t.prop,""))&&"auto"!==e?e:0},set:function(t){E.fx.step[t.prop]?E.fx.step[t.prop](t):1!==t.elem.nodeType||!E.cssHooks[t.prop]&&null==t.elem.style[Yt(t.prop)]?t.elem[t.prop]=t.now:E.style(t.elem,t.prop,t.now+t.unit)}}},ie.propHooks.scrollTop=ie.propHooks.scrollLeft={set:function(t){t.elem.nodeType&&t.elem.parentNode&&(t.elem[t.prop]=t.now)}},E.easing={linear:function(t){return t},swing:function(t){return.5-Math.cos(t*Math.PI)/2},_default:"swing"},E.fx=ie.prototype.init,E.fx.step={};var re,oe,se=/^(?:toggle|show|hide)$/,ae=/queueHooks$/;function le(){oe&&(!1===b.hidden&&i.requestAnimationFrame?i.requestAnimationFrame(le):i.setTimeout(le,E.fx.interval),E.fx.tick())}function ce(){return i.setTimeout((function(){re=void 0})),re=Date.now()}function ue(t,e){var n,i=0,r={height:t};for(e=e?1:0;i<4;i+=2-e)r["margin"+(n=ot[i])]=r["padding"+n]=t;return e&&(r.opacity=r.width=t),r}function pe(t,e,n){for(var i,r=(fe.tweeners[e]||[]).concat(fe.tweeners["*"]),o=0,s=r.length;o1)},removeAttr:function(t){return this.each((function(){E.removeAttr(this,t)}))}}),E.extend({attr:function(t,e,n){var i,r,o=t.nodeType;if(3!==o&&8!==o&&2!==o)return void 0===t.getAttribute?E.prop(t,e,n):(1===o&&E.isXMLDoc(t)||(r=E.attrHooks[e.toLowerCase()]||(E.expr.match.bool.test(e)?de:void 0)),void 0!==n?null===n?void E.removeAttr(t,e):r&&"set"in r&&void 0!==(i=r.set(t,n,e))?i:(t.setAttribute(e,n+""),n):r&&"get"in r&&null!==(i=r.get(t,e))?i:null==(i=E.find.attr(t,e))?void 0:i)},attrHooks:{type:{set:function(t,e){if(!m.radioValue&&"radio"===e&&D(t,"input")){var n=t.value;return t.setAttribute("type",e),n&&(t.value=n),e}}}},removeAttr:function(t,e){var n,i=0,r=e&&e.match(P);if(r&&1===t.nodeType)for(;n=r[i++];)t.removeAttribute(n)}}),de={set:function(t,e,n){return!1===e?E.removeAttr(t,n):t.setAttribute(n,n),n}},E.each(E.expr.match.bool.source.match(/\w+/g),(function(t,e){var n=he[e]||E.find.attr;he[e]=function(t,e,i){var r,o,s=e.toLowerCase();return i||(o=he[s],he[s]=r,r=null!=n(t,e,i)?s:null,he[s]=o),r}}));var ge=/^(?:input|select|textarea|button)$/i,me=/^(?:a|area)$/i;function ve(t){return(t.match(P)||[]).join(" ")}function ye(t){return t.getAttribute&&t.getAttribute("class")||""}function be(t){return Array.isArray(t)?t:"string"==typeof t&&t.match(P)||[]}E.fn.extend({prop:function(t,e){return z(this,E.prop,t,e,arguments.length>1)},removeProp:function(t){return this.each((function(){delete this[E.propFix[t]||t]}))}}),E.extend({prop:function(t,e,n){var i,r,o=t.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&E.isXMLDoc(t)||(e=E.propFix[e]||e,r=E.propHooks[e]),void 0!==n?r&&"set"in r&&void 0!==(i=r.set(t,n,e))?i:t[e]=n:r&&"get"in r&&null!==(i=r.get(t,e))?i:t[e]},propHooks:{tabIndex:{get:function(t){var e=E.find.attr(t,"tabindex");return e?parseInt(e,10):ge.test(t.nodeName)||me.test(t.nodeName)&&t.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),m.optSelected||(E.propHooks.selected={get:function(t){var e=t.parentNode;return e&&e.parentNode&&e.parentNode.selectedIndex,null},set:function(t){var e=t.parentNode;e&&(e.selectedIndex,e.parentNode&&e.parentNode.selectedIndex)}}),E.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],(function(){E.propFix[this.toLowerCase()]=this})),E.fn.extend({addClass:function(t){var e,n,i,r,o,s,a,l=0;if(v(t))return this.each((function(e){E(this).addClass(t.call(this,e,ye(this)))}));if((e=be(t)).length)for(;n=this[l++];)if(r=ye(n),i=1===n.nodeType&&" "+ve(r)+" "){for(s=0;o=e[s++];)i.indexOf(" "+o+" ")<0&&(i+=o+" ");r!==(a=ve(i))&&n.setAttribute("class",a)}return this},removeClass:function(t){var e,n,i,r,o,s,a,l=0;if(v(t))return this.each((function(e){E(this).removeClass(t.call(this,e,ye(this)))}));if(!arguments.length)return this.attr("class","");if((e=be(t)).length)for(;n=this[l++];)if(r=ye(n),i=1===n.nodeType&&" "+ve(r)+" "){for(s=0;o=e[s++];)for(;i.indexOf(" "+o+" ")>-1;)i=i.replace(" "+o+" "," ");r!==(a=ve(i))&&n.setAttribute("class",a)}return this},toggleClass:function(t,e){var n=typeof t,i="string"===n||Array.isArray(t);return"boolean"==typeof e&&i?e?this.addClass(t):this.removeClass(t):v(t)?this.each((function(n){E(this).toggleClass(t.call(this,n,ye(this),e),e)})):this.each((function(){var e,r,o,s;if(i)for(r=0,o=E(this),s=be(t);e=s[r++];)o.hasClass(e)?o.removeClass(e):o.addClass(e);else void 0!==t&&"boolean"!==n||((e=ye(this))&&J.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",e||!1===t?"":J.get(this,"__className__")||""))}))},hasClass:function(t){var e,n,i=0;for(e=" "+t+" ";n=this[i++];)if(1===n.nodeType&&(" "+ve(ye(n))+" ").indexOf(e)>-1)return!0;return!1}});var xe=/\r/g;E.fn.extend({val:function(t){var e,n,i,r=this[0];return arguments.length?(i=v(t),this.each((function(n){var r;1===this.nodeType&&(null==(r=i?t.call(this,n,E(this).val()):t)?r="":"number"==typeof r?r+="":Array.isArray(r)&&(r=E.map(r,(function(t){return null==t?"":t+""}))),(e=E.valHooks[this.type]||E.valHooks[this.nodeName.toLowerCase()])&&"set"in e&&void 0!==e.set(this,r,"value")||(this.value=r))}))):r?(e=E.valHooks[r.type]||E.valHooks[r.nodeName.toLowerCase()])&&"get"in e&&void 0!==(n=e.get(r,"value"))?n:"string"==typeof(n=r.value)?n.replace(xe,""):null==n?"":n:void 0}}),E.extend({valHooks:{option:{get:function(t){var e=E.find.attr(t,"value");return null!=e?e:ve(E.text(t))}},select:{get:function(t){var e,n,i,r=t.options,o=t.selectedIndex,s="select-one"===t.type,a=s?null:[],l=s?o+1:r.length;for(i=o<0?l:s?o:0;i-1)&&(n=!0);return n||(t.selectedIndex=-1),o}}}}),E.each(["radio","checkbox"],(function(){E.valHooks[this]={set:function(t,e){if(Array.isArray(e))return t.checked=E.inArray(E(t).val(),e)>-1}},m.checkOn||(E.valHooks[this].get=function(t){return null===t.getAttribute("value")?"on":t.value})})),m.focusin="onfocusin"in i;var we=/^(?:focusinfocus|focusoutblur)$/,Te=function(t){t.stopPropagation()};E.extend(E.event,{trigger:function(t,e,n,r){var o,s,a,l,c,u,p,f,h=[n||b],g=d.call(t,"type")?t.type:t,m=d.call(t,"namespace")?t.namespace.split("."):[];if(s=f=a=n=n||b,3!==n.nodeType&&8!==n.nodeType&&!we.test(g+E.event.triggered)&&(g.indexOf(".")>-1&&(m=g.split("."),g=m.shift(),m.sort()),c=g.indexOf(":")<0&&"on"+g,(t=t[E.expando]?t:new E.Event(g,"object"==typeof t&&t)).isTrigger=r?2:3,t.namespace=m.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=n),e=null==e?[t]:E.makeArray(e,[t]),p=E.event.special[g]||{},r||!p.trigger||!1!==p.trigger.apply(n,e))){if(!r&&!p.noBubble&&!y(n)){for(l=p.delegateType||g,we.test(l+g)||(s=s.parentNode);s;s=s.parentNode)h.push(s),a=s;a===(n.ownerDocument||b)&&h.push(a.defaultView||a.parentWindow||i)}for(o=0;(s=h[o++])&&!t.isPropagationStopped();)f=s,t.type=o>1?l:p.bindType||g,(u=(J.get(s,"events")||Object.create(null))[t.type]&&J.get(s,"handle"))&&u.apply(s,e),(u=c&&s[c])&&u.apply&&Q(s)&&(t.result=u.apply(s,e),!1===t.result&&t.preventDefault());return t.type=g,r||t.isDefaultPrevented()||p._default&&!1!==p._default.apply(h.pop(),e)||!Q(n)||c&&v(n[g])&&!y(n)&&((a=n[c])&&(n[c]=null),E.event.triggered=g,t.isPropagationStopped()&&f.addEventListener(g,Te),n[g](),t.isPropagationStopped()&&f.removeEventListener(g,Te),E.event.triggered=void 0,a&&(n[c]=a)),t.result}},simulate:function(t,e,n){var i=E.extend(new E.Event,n,{type:t,isSimulated:!0});E.event.trigger(i,null,e)}}),E.fn.extend({trigger:function(t,e){return this.each((function(){E.event.trigger(t,e,this)}))},triggerHandler:function(t,e){var n=this[0];if(n)return E.event.trigger(t,e,n,!0)}}),m.focusin||E.each({focus:"focusin",blur:"focusout"},(function(t,e){var n=function(t){E.event.simulate(e,t.target,E.event.fix(t))};E.event.special[e]={setup:function(){var i=this.ownerDocument||this.document||this,r=J.access(i,e);r||i.addEventListener(t,n,!0),J.access(i,e,(r||0)+1)},teardown:function(){var i=this.ownerDocument||this.document||this,r=J.access(i,e)-1;r?J.access(i,e,r):(i.removeEventListener(t,n,!0),J.remove(i,e))}}}));var Ce=i.location,Ee={guid:Date.now()},Se=/\?/;E.parseXML=function(t){var e,n;if(!t||"string"!=typeof t)return null;try{e=(new i.DOMParser).parseFromString(t,"text/xml")}catch(t){}return n=e&&e.getElementsByTagName("parsererror")[0],e&&!n||E.error("Invalid XML: "+(n?E.map(n.childNodes,(function(t){return t.textContent})).join("\n"):t)),e};var ke=/\[\]$/,$e=/\r?\n/g,Ae=/^(?:submit|button|image|reset|file)$/i,Ne=/^(?:input|select|textarea|keygen)/i;function De(t,e,n,i){var r;if(Array.isArray(e))E.each(e,(function(e,r){n||ke.test(t)?i(t,r):De(t+"["+("object"==typeof r&&null!=r?e:"")+"]",r,n,i)}));else if(n||"object"!==T(e))i(t,e);else for(r in e)De(t+"["+r+"]",e[r],n,i)}E.param=function(t,e){var n,i=[],r=function(t,e){var n=v(e)?e():e;i[i.length]=encodeURIComponent(t)+"="+encodeURIComponent(null==n?"":n)};if(null==t)return"";if(Array.isArray(t)||t.jquery&&!E.isPlainObject(t))E.each(t,(function(){r(this.name,this.value)}));else for(n in t)De(n,t[n],e,r);return i.join("&")},E.fn.extend({serialize:function(){return E.param(this.serializeArray())},serializeArray:function(){return this.map((function(){var t=E.prop(this,"elements");return t?E.makeArray(t):this})).filter((function(){var t=this.type;return this.name&&!E(this).is(":disabled")&&Ne.test(this.nodeName)&&!Ae.test(t)&&(this.checked||!mt.test(t))})).map((function(t,e){var n=E(this).val();return null==n?null:Array.isArray(n)?E.map(n,(function(t){return{name:e.name,value:t.replace($e,"\r\n")}})):{name:e.name,value:n.replace($e,"\r\n")}})).get()}});var je=/%20/g,Oe=/#.*$/,Ie=/([?&])_=[^&]*/,Le=/^(.*?):[ \t]*([^\r\n]*)$/gm,Re=/^(?:GET|HEAD)$/,qe=/^\/\//,He={},Pe={},Fe="*/".concat("*"),Ue=b.createElement("a");function Me(t){return function(e,n){"string"!=typeof e&&(n=e,e="*");var i,r=0,o=e.toLowerCase().match(P)||[];if(v(n))for(;i=o[r++];)"+"===i[0]?(i=i.slice(1)||"*",(t[i]=t[i]||[]).unshift(n)):(t[i]=t[i]||[]).push(n)}}function We(t,e,n,i){var r={},o=t===Pe;function s(a){var l;return r[a]=!0,E.each(t[a]||[],(function(t,a){var c=a(e,n,i);return"string"!=typeof c||o||r[c]?o?!(l=c):void 0:(e.dataTypes.unshift(c),s(c),!1)})),l}return s(e.dataTypes[0])||!r["*"]&&s("*")}function Be(t,e){var n,i,r=E.ajaxSettings.flatOptions||{};for(n in e)void 0!==e[n]&&((r[n]?t:i||(i={}))[n]=e[n]);return i&&E.extend(!0,t,i),t}Ue.href=Ce.href,E.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ce.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Ce.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Fe,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":E.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(t,e){return e?Be(Be(t,E.ajaxSettings),e):Be(E.ajaxSettings,t)},ajaxPrefilter:Me(He),ajaxTransport:Me(Pe),ajax:function(t,e){"object"==typeof t&&(e=t,t=void 0),e=e||{};var n,r,o,s,a,l,c,u,p,f,d=E.ajaxSetup({},e),h=d.context||d,g=d.context&&(h.nodeType||h.jquery)?E(h):E.event,m=E.Deferred(),v=E.Callbacks("once memory"),y=d.statusCode||{},x={},w={},T="canceled",C={readyState:0,getResponseHeader:function(t){var e;if(c){if(!s)for(s={};e=Le.exec(o);)s[e[1].toLowerCase()+" "]=(s[e[1].toLowerCase()+" "]||[]).concat(e[2]);e=s[t.toLowerCase()+" "]}return null==e?null:e.join(", ")},getAllResponseHeaders:function(){return c?o:null},setRequestHeader:function(t,e){return null==c&&(t=w[t.toLowerCase()]=w[t.toLowerCase()]||t,x[t]=e),this},overrideMimeType:function(t){return null==c&&(d.mimeType=t),this},statusCode:function(t){var e;if(t)if(c)C.always(t[C.status]);else for(e in t)y[e]=[y[e],t[e]];return this},abort:function(t){var e=t||T;return n&&n.abort(e),S(0,e),this}};if(m.promise(C),d.url=((t||d.url||Ce.href)+"").replace(qe,Ce.protocol+"//"),d.type=e.method||e.type||d.method||d.type,d.dataTypes=(d.dataType||"*").toLowerCase().match(P)||[""],null==d.crossDomain){l=b.createElement("a");try{l.href=d.url,l.href=l.href,d.crossDomain=Ue.protocol+"//"+Ue.host!=l.protocol+"//"+l.host}catch(t){d.crossDomain=!0}}if(d.data&&d.processData&&"string"!=typeof d.data&&(d.data=E.param(d.data,d.traditional)),We(He,d,e,C),c)return C;for(p in(u=E.event&&d.global)&&0==E.active++&&E.event.trigger("ajaxStart"),d.type=d.type.toUpperCase(),d.hasContent=!Re.test(d.type),r=d.url.replace(Oe,""),d.hasContent?d.data&&d.processData&&0===(d.contentType||"").indexOf("application/x-www-form-urlencoded")&&(d.data=d.data.replace(je,"+")):(f=d.url.slice(r.length),d.data&&(d.processData||"string"==typeof d.data)&&(r+=(Se.test(r)?"&":"?")+d.data,delete d.data),!1===d.cache&&(r=r.replace(Ie,"$1"),f=(Se.test(r)?"&":"?")+"_="+Ee.guid+++f),d.url=r+f),d.ifModified&&(E.lastModified[r]&&C.setRequestHeader("If-Modified-Since",E.lastModified[r]),E.etag[r]&&C.setRequestHeader("If-None-Match",E.etag[r])),(d.data&&d.hasContent&&!1!==d.contentType||e.contentType)&&C.setRequestHeader("Content-Type",d.contentType),C.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+("*"!==d.dataTypes[0]?", "+Fe+"; q=0.01":""):d.accepts["*"]),d.headers)C.setRequestHeader(p,d.headers[p]);if(d.beforeSend&&(!1===d.beforeSend.call(h,C,d)||c))return C.abort();if(T="abort",v.add(d.complete),C.done(d.success),C.fail(d.error),n=We(Pe,d,e,C)){if(C.readyState=1,u&&g.trigger("ajaxSend",[C,d]),c)return C;d.async&&d.timeout>0&&(a=i.setTimeout((function(){C.abort("timeout")}),d.timeout));try{c=!1,n.send(x,S)}catch(t){if(c)throw t;S(-1,t)}}else S(-1,"No Transport");function S(t,e,s,l){var p,f,b,x,w,T=e;c||(c=!0,a&&i.clearTimeout(a),n=void 0,o=l||"",C.readyState=t>0?4:0,p=t>=200&&t<300||304===t,s&&(x=function(t,e,n){for(var i,r,o,s,a=t.contents,l=t.dataTypes;"*"===l[0];)l.shift(),void 0===i&&(i=t.mimeType||e.getResponseHeader("Content-Type"));if(i)for(r in a)if(a[r]&&a[r].test(i)){l.unshift(r);break}if(l[0]in n)o=l[0];else{for(r in n){if(!l[0]||t.converters[r+" "+l[0]]){o=r;break}s||(s=r)}o=o||s}if(o)return o!==l[0]&&l.unshift(o),n[o]}(d,C,s)),!p&&E.inArray("script",d.dataTypes)>-1&&E.inArray("json",d.dataTypes)<0&&(d.converters["text script"]=function(){}),x=function(t,e,n,i){var r,o,s,a,l,c={},u=t.dataTypes.slice();if(u[1])for(s in t.converters)c[s.toLowerCase()]=t.converters[s];for(o=u.shift();o;)if(t.responseFields[o]&&(n[t.responseFields[o]]=e),!l&&i&&t.dataFilter&&(e=t.dataFilter(e,t.dataType)),l=o,o=u.shift())if("*"===o)o=l;else if("*"!==l&&l!==o){if(!(s=c[l+" "+o]||c["* "+o]))for(r in c)if((a=r.split(" "))[1]===o&&(s=c[l+" "+a[0]]||c["* "+a[0]])){!0===s?s=c[r]:!0!==c[r]&&(o=a[0],u.unshift(a[1]));break}if(!0!==s)if(s&&t.throws)e=s(e);else try{e=s(e)}catch(t){return{state:"parsererror",error:s?t:"No conversion from "+l+" to "+o}}}return{state:"success",data:e}}(d,x,C,p),p?(d.ifModified&&((w=C.getResponseHeader("Last-Modified"))&&(E.lastModified[r]=w),(w=C.getResponseHeader("etag"))&&(E.etag[r]=w)),204===t||"HEAD"===d.type?T="nocontent":304===t?T="notmodified":(T=x.state,f=x.data,p=!(b=x.error))):(b=T,!t&&T||(T="error",t<0&&(t=0))),C.status=t,C.statusText=(e||T)+"",p?m.resolveWith(h,[f,T,C]):m.rejectWith(h,[C,T,b]),C.statusCode(y),y=void 0,u&&g.trigger(p?"ajaxSuccess":"ajaxError",[C,d,p?f:b]),v.fireWith(h,[C,T]),u&&(g.trigger("ajaxComplete",[C,d]),--E.active||E.event.trigger("ajaxStop")))}return C},getJSON:function(t,e,n){return E.get(t,e,n,"json")},getScript:function(t,e){return E.get(t,void 0,e,"script")}}),E.each(["get","post"],(function(t,e){E[e]=function(t,n,i,r){return v(n)&&(r=r||i,i=n,n=void 0),E.ajax(E.extend({url:t,type:e,dataType:r,data:n,success:i},E.isPlainObject(t)&&t))}})),E.ajaxPrefilter((function(t){var e;for(e in t.headers)"content-type"===e.toLowerCase()&&(t.contentType=t.headers[e]||"")})),E._evalUrl=function(t,e,n){return E.ajax({url:t,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(t){E.globalEval(t,e,n)}})},E.fn.extend({wrapAll:function(t){var e;return this[0]&&(v(t)&&(t=t.call(this[0])),e=E(t,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&e.insertBefore(this[0]),e.map((function(){for(var t=this;t.firstElementChild;)t=t.firstElementChild;return t})).append(this)),this},wrapInner:function(t){return v(t)?this.each((function(e){E(this).wrapInner(t.call(this,e))})):this.each((function(){var e=E(this),n=e.contents();n.length?n.wrapAll(t):e.append(t)}))},wrap:function(t){var e=v(t);return this.each((function(n){E(this).wrapAll(e?t.call(this,n):t)}))},unwrap:function(t){return this.parent(t).not("body").each((function(){E(this).replaceWith(this.childNodes)})),this}}),E.expr.pseudos.hidden=function(t){return!E.expr.pseudos.visible(t)},E.expr.pseudos.visible=function(t){return!!(t.offsetWidth||t.offsetHeight||t.getClientRects().length)},E.ajaxSettings.xhr=function(){try{return new i.XMLHttpRequest}catch(t){}};var _e={0:200,1223:204},ze=E.ajaxSettings.xhr();m.cors=!!ze&&"withCredentials"in ze,m.ajax=ze=!!ze,E.ajaxTransport((function(t){var e,n;if(m.cors||ze&&!t.crossDomain)return{send:function(r,o){var s,a=t.xhr();if(a.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(s in t.xhrFields)a[s]=t.xhrFields[s];for(s in t.mimeType&&a.overrideMimeType&&a.overrideMimeType(t.mimeType),t.crossDomain||r["X-Requested-With"]||(r["X-Requested-With"]="XMLHttpRequest"),r)a.setRequestHeader(s,r[s]);e=function(t){return function(){e&&(e=n=a.onload=a.onerror=a.onabort=a.ontimeout=a.onreadystatechange=null,"abort"===t?a.abort():"error"===t?"number"!=typeof a.status?o(0,"error"):o(a.status,a.statusText):o(_e[a.status]||a.status,a.statusText,"text"!==(a.responseType||"text")||"string"!=typeof a.responseText?{binary:a.response}:{text:a.responseText},a.getAllResponseHeaders()))}},a.onload=e(),n=a.onerror=a.ontimeout=e("error"),void 0!==a.onabort?a.onabort=n:a.onreadystatechange=function(){4===a.readyState&&i.setTimeout((function(){e&&n()}))},e=e("abort");try{a.send(t.hasContent&&t.data||null)}catch(t){if(e)throw t}},abort:function(){e&&e()}}})),E.ajaxPrefilter((function(t){t.crossDomain&&(t.contents.script=!1)})),E.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(t){return E.globalEval(t),t}}}),E.ajaxPrefilter("script",(function(t){void 0===t.cache&&(t.cache=!1),t.crossDomain&&(t.type="GET")})),E.ajaxTransport("script",(function(t){var e,n;if(t.crossDomain||t.scriptAttrs)return{send:function(i,r){e=E("