Merge pull request #194 from lektor/pluginlist-update

Pluginlist update
This commit is contained in:
Joseph Nix 2018-05-15 09:43:06 -05:00 committed by GitHub
commit fabbc0f691
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
71 changed files with 3653 additions and 105 deletions

2
.gitignore vendored
View File

@ -5,3 +5,5 @@
packages/*/build
packages/*/dist
webpack/node_modules
*~
*#

View File

@ -16,3 +16,4 @@ lektor-markdown-header-anchors = 0.1
lektor-markdown-highlighter = 0.1
lektor-markdown-admonition = 0.1
lektor-atom = 0.2
lektor-tags = 0.1

Binary file not shown.

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 434 KiB

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"version":3,"file":"app.js","sources":["webpack:///app.js","webpack:///"],"mappings":"AAAA;;;;;;;;;;;;;ACyMA;;;;;;;;;;AA4hBA;AAqoIA;AAo3IA;AA47EA","sourceRoot":""}
{"version":3,"file":"app.js","sources":["webpack:///app.js"],"mappings":"AAAA;;;;;;;;;;;;;AAwMA;;;;;;;;;;AAgfA;AA6uIA;AA8iJA;AA46EA;;;;;AAs1BA","sourceRoot":""}

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

2
configs/tags.ini Normal file
View File

@ -0,0 +1,2 @@
parent = /plugins
template = plugin-tag.html

View File

@ -0,0 +1,42 @@
title: Plugin Play
---
author: Joseph Nix
---
pub_date: 2018-05-15
---
summary: Discovering and learning about plugins just got easier.
---
twitter_handle: nixjdm
---
body:
#### banner ####
image: spices.jpg
----
height: 300
----
contents:
#### text-block ####
text:
## 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](/plugins/tag/before-build-all/). 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](/plugins)!
----
class: default

Binary file not shown.

After

Width:  |  Height:  |  Size: 759 KiB

View File

@ -10,19 +10,9 @@ 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.
## 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.
2. 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.
## Installing Plugins
## Installing Published Plugins
Lektor can find and install plugins that have been published to [PyPI :ext](https://pypi.org/) 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`:
@ -34,7 +24,20 @@ lektor-other-plugin = 1.2
```
It's also possible to use the [plugins add :ref](../cli/plugins/add/) command
to automatically add the latest version of a plugin to the project file.
`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. 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.

View File

@ -1,67 +1,5 @@
title: List
_model: redirect
---
summary: A list of known plugins.
target: /plugins
---
body:
Lektor is a young project but it has a growing list of both official and community supported plugins.
Official plugins were developed by the authors of 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.
This is a list of currently known plugins. Official plugins are prefixed with as asterisk (*) and are listed first in each section and separated by an underline.
## Build
* *[webpack-support :ext](https://github.com/lektor/lektor-webpack-support):
adds support for building websites with webpack.
___
* [htmlmin :ext](https://github.com/vesuvium/lektor-htmlmin): Automatically minifies .html files in build directory
* [i18n :ext](https://github.com/numericube/lektor-i18n-plugin): Use GetText .PO files to translate your site **content**.
* [make :ext](https://github.com/BarnabyShearer/lektor-make): Run `make lektor` for custom build systems
* [minify :ext](https://github.com/pietroalbini/lektor-minify): Minify changed files automatically during the build
* [npm-support :ext](https://github.com/sterin/lektor-npm-support): adds support for using npm/yarn to build assets in Lektor using tools such as [Parcel](https://parcel.js.org), [webpack](https://webpack.js.org), etc.
## Content
* *[markdown-admonition :ext](https://github.com/lektor/lektor-markdown-admonition):
adds admonition block support to Markdown.
* *[markdown-header-anchors :ext](https://github.com/lektor/lektor-markdown-header-anchors):
adds support for header anchors and table of contents to Markdown.
* *[markdown-highlighter :ext](https://github.com/lektor/lektor-markdown-highlighter):
adds support for syntax highlighting to markdown code snippets.
___
* [asciidoc :ext](https://github.com/ajdavis/lektor-asciidoc/): Add asciidoc field type
* [jinja-content :ext](https://github.com/terminal-labs/lektor-jinja-content) Enable Jinja with the [Template Context](https://www.getlektor.com/docs/templates/#template-context) in your content fields, e.g. combining Jinja and Markdown.
* [nofollow :ext](https://github.com/yargies/lektor-nofollow): Easily create nofollow links in markdown
* [rst :ext](https://github.com/fschulze/lektor-rst): A [reStructuredText](http://docutils.sourceforge.net) plugin
* [tags :ext](https://github.com/ajdavis/lektor-tags): For each tag on site, build a list of pages with that tag.
* [read-full-post :ext](https://github.com/Andrew-Shay/lektor-read-full-post): Allows blog listing posts to be shortened with a link to the full post.
## Deploy
* [netlify :ext](https://github.com/ajdavis/lektor-netlify): Publish to [Netlify](https://www.netlify.com/).
* [s3 :ext](https://github.com/spenczar/lektor-s3): Publish to [S3](https://aws.amazon.com/s3/) buckets and [Cloudfront](https://aws.amazon.com/cloudfront/).
* [surge :ext](https://github.com/ajdavis/lektor-surge): Publish to [Surge](https://surge.sh/).
## Templates
* *[disqus-comments :ext](https://github.com/lektor/lektor-disqus-comments): Embed Disqus comments into your website.
___
* [atom :ext](https://github.com/dwt/lektor-atom): Generate Atom feeds for your content.
* [creative-commons :ext](https://github.com/humrochagf/lektor-creative-commons): Add Creative Commons license to your pages.
* [github-repos :ext](https://github.com/marksteve/lektor-github-repos): Fetches your GitHub repos for display in Lektor templates.
* [markdown-excerpt :ext](https://github.com/bancek/lektor-markdown-excerpt): Adds filter for Markdown body excerpt.
* [google-analytics :ext](https://github.com/kmonsoor/lektor-google-analytics): Adds `Google Analytics` support to Lektor-generated site.
* [shortcodes :ext](https://github.com/skorokithakis/lektor-shortcodes): Allows you to use shortcodes (something like tags) in your model fields.
* [slugify :ext](https://github.com/terminal-labs/lektor-slugify) Add a Jinja filter to slugify strings, even Unicode.
* [natural-language :ext](https://github.com/terminal-labs/lektor-natural-language) Add filters to do basic natural language processing with NLTK. Find keywords and sentence structure naturally.
* [strip-html-tags :ext](https://github.com/terminal-labs/lektor-strip-html-tags) Add a filter to transform HTML into simple text by stripping HTML tags.
* [thumbnail-generator :ext](https://github.com/skorokithakis/lektor-thumbnail-generator): Allows you to generate configurable thumbnails for all your attachment images, so you can link them in your pages.
* [webdav :ext](https://github.com/mesbahamin/lektor-webdav): Get a list of files hosted on a WebDAV server.
* [yandex-metrica :ext](https://github.com/gagoman/lektor-yandex-metrica): Adds `Yandex Metrica` support to Lektor-generated site.
! Have your own plugin and you want to see it here? Just [edit this page
on GitHub :ref](https://github.com/lektor/lektor-website/edit/master/content/docs/plugins/list/contents.lr),
add your plugin to the list and send a pull request.
_discoverable: no

View File

@ -8,7 +8,7 @@ body:
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 :ext](https://pypi.python.org/) and can be
[Python Package Index :ext](https://pypi.org/) and can be
automatically done with the help of the lektor shell command.
## Enhance your setup.py
@ -16,29 +16,55 @@ automatically done with the help of the lektor shell command.
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 a basic example of doing this:
set. Here is an example of doing this, largely taken from what is given by
the CLI command `lektor dev new-plugin`:
```python
from setuptools import setup
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(
name='lektor-your-plugin',
author='Your Name',
author_email='your.email@your.domain.invalid',
version='1.0',
url='http://github.com/youruser/lektor-yourplugin',
description=description,
keywords='Lektor plugin static-site blog',
license='MIT',
packages=['lektor_your_plugin'],
description='Basic description goes here',
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
@ -55,3 +81,22 @@ $ 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
We'd love to see your new plugin listed on [our plugins page :ref](/plugins). To do that, submit a pull request to [this repository :ext](https://github.com/lektor/lektor-website) 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 :ext](https://pypi.org/), please [fill out your setup.py :ext](https://packaging.python.org/tutorials/distributing-packages/) completely (as in [the above snippet :ref](/docs/plugins/publishing/#enhance-your-setup.py)), 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
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 nightly. 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.

View File

@ -0,0 +1,12 @@
body:
#### text-block ####
text: These plugins primarily deal with Lektor's [build :ref](/docs/quickstart/#building) process, adding build tools or processes.
----
class: default
---
title: Build
---
_discoverable: yes
---
_hidden: no

View File

@ -0,0 +1,8 @@
title: Content
---
body:
#### text-block ####
text: These plugins primarily deal with adding or modifying available content in Lektor, adding content types, or modifying how content behaves.
----
class: default

View File

@ -0,0 +1,12 @@
_model: plugin-categories
---
_slug: plugins/categories
---
body:
#### text-block ####
text:
----
class: default
---
title: Plugin Categories

View File

@ -0,0 +1,8 @@
body:
#### text-block ####
text: These plugins primarily deal with Lektor's [deployment :ref](/docs/deployment/) abilities. They may add a deployment service or location.
----
class: default
---
title: Deploy

View File

@ -0,0 +1,8 @@
body:
#### text-block ####
text: These plugins primarily deal with Lektor's [Templates :ref](/docs/templates/). They may add or modify [context :ref](docs/templates/#template-context), [api :ref](/docs/api/templates/), [filters :ref](/docs/api/templates/filters/), [globals :ref](/docs/api/templates/globals/), [modify images :ref](/docs/templates/imageops/), [change navigation :ref](/docs/templates/navigation/), or many other functionalities available to templates.
----
class: default
---
title: Templates

View File

@ -0,0 +1,16 @@
_model: plugins
---
title: Lektor Loves Plugins
---
body:
#### text-block ####
text:
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 :ref](/docs/plugins).
(*) Asterisks denote official plugins.
----
class: default

BIN
content/plugins/header.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 KiB

View File

@ -0,0 +1,9 @@
name: lektor-asciidoc
---
categories: content
---
tags:
asciidoc
field type
setup-env

View File

@ -0,0 +1,10 @@
name: lektor-atom
---
categories: templates
---
tags:
Atom
RSS
virtual paths
setup-env

View File

@ -0,0 +1,15 @@
name: lektor-creative-commons
---
categories: templates
---
tags:
Creative Commons
Licensing
jinja globals
multi-language
multilingual
setup-env
translate
translation
setup-env

View File

@ -0,0 +1,15 @@
name: lektor-disqus-comments
---
categories: templates
---
official: yes
---
tags:
official
Disqus
comments
blog
setup-env
---
summary: Embed Disqus comments into your website.

View File

@ -0,0 +1,8 @@
name: lektor-github-repos
---
categories: templates
---
tags:
GitHub
process-template-context

View File

@ -0,0 +1,8 @@
name: lektor-google-analytics
---
tags:
analytics
Google Analytics
jinja globals
setup-env

View File

@ -0,0 +1,11 @@
name: lektor-htmlmin
---
categories: build
---
tags:
html
minify
htmlmin
after-build-all

View File

@ -0,0 +1,22 @@
name: lektor-i18n
---
categories: build
---
summary: Use GetText .PO files to translate your site content.
---
tags:
multilingual
multi-language
language
GetText
translate
translation
alternatives
i18n
babel
setup-env
before-build
after-build
before-build-all
after-build-all

View File

@ -0,0 +1,11 @@
name: lektor-jinja-content
---
categories: content
---
tags:
before-build
jinja
templates
content
markdown

View File

@ -0,0 +1,11 @@
name: lektor-make
---
categories: build
---
tags:
before-build-all
make
makefile
---
summary: Run <code>make lektor</code> for custom build systems.

View File

@ -0,0 +1,12 @@
name: lektor-markdown-admonition
---
categories: content
---
official: yes
---
tags:
official
markdown
admonition
markdown-config

View File

@ -0,0 +1,9 @@
name: lektor-markdown-excerpt
---
categories: templates
---
tags:
markdown
jinja filter
setup-env

View File

@ -0,0 +1,16 @@
name: lektor-markdown-header-anchors
---
categories: content
---
official: yes
---
tags:
official
markdown
headers
anchors
table of contents
markdown-config
makrdown-meta-init
markdown-meta-postprocess

View File

@ -0,0 +1,14 @@
name: lektor-markdown-highlighter
---
categories: content
---
official: yes
---
tags:
official
markdown
syntax highlighting
Pygments
markdown-config
setup-env

View File

@ -0,0 +1,15 @@
name: lektor-minify
---
tags:
django_htmlmin
rcssmin
rjsmin
minify
html
css
js
setup-env
after-build
---
categories: build

View File

@ -0,0 +1,10 @@
name: lektor-natural-language
---
categories: templates
---
tags:
jinja filters
nltk
natural language
setup-env

View File

@ -0,0 +1,11 @@
name: lektor-netlify
---
categories: deploy
---
tags:
Netlify
publisher
setup-env
---
summary: Allows you to generate configurable thumbnails for all your attachment images, so you can link them in your pages.

View File

@ -0,0 +1,11 @@
name: lektor-nofollow
---
categories: content
---
tags:
nofollow links
markdown
markdown-config
---
summary: Easily create nofollow links in markdown

View File

@ -0,0 +1,17 @@
name: lektor-npm-support
---
categories: build
---
tags:
webpack
browserify
Parcel
Babel
Sass
yarn
server-spawn
server-stop
before-build-all
---
summary: Adds support for using npm/yarn to build assets in Lektor using tools such as <a href="https://parceljs.org/" class="ext">Parcel</a>, <a href="https://webpack.js.org/" class="ext">webpack</a>, etc.

View File

@ -0,0 +1,10 @@
name: lektor-read-full-post
---
categories: content
---
tags:
setup-env
jinja globals
blog
markdown

View File

@ -0,0 +1,10 @@
name: lektor-rst
---
categories: content
---
tags:
rst
reStructuredText
field types
setup-env

View File

@ -0,0 +1,13 @@
name: lektor-s3
---
categories: deploy
---
tags:
AWS
S3
Cloudfront
publisher
setup-env
---
summary: Publish to <a href="https://aws.amazon.com/s3/">S3</a> buckets and <a href="https://aws.amazon.com/cloudfront/">Cloudfront</a>.

View File

@ -0,0 +1,13 @@
name: lektor-shortcodes
---
categories: templates
---
tags:
shortcodes
markdown
markdown-config
jinja filters
setup-env
---
summary: Allows you to use shortcodes (something like tags) in your model fields.

View File

@ -0,0 +1,10 @@
name: lektor-slugify
---
categories: templates
---
tags:
slugify
jinja filters
python-slugify
setup-env

View File

@ -0,0 +1,9 @@
name: lektor-strip-html-tags
---
categories: templates
---
tags:
jinja filters
html
setup-env

View File

@ -0,0 +1,9 @@
name: lektor-surge
---
categories: deploy
---
tags:
Surge
publisher
setup-env

View File

@ -0,0 +1,10 @@
name: lektor-tags
---
categories: content
---
tags:
tags
page generation
virtual paths
setup-env

View File

@ -0,0 +1,8 @@
name: lektor-thumbnail-generator
---
categories: templates
---
tags:
images
thumbnails

View File

@ -0,0 +1,12 @@
name: lektor-webdav
---
categories: templates
---
tags:
WebDAV
remote content
jinja globals
jinja filters
setup-env

View File

@ -0,0 +1,17 @@
name: lektor-webpack-support
---
categories: build
---
official: yes
---
tags:
official
webpack
npm
yarn
node
scss
server-spawn
server-stop
before-build-all

View File

@ -0,0 +1,10 @@
name: lektor-yandex-metrica
---
categories: templates
---
tags:
analytics
Yandex Metrica
setup-env
jinja globals

View File

@ -10,6 +10,14 @@ label = Documentation
path = /showcase
label = Showcase
[plugins]
path = /plugins
label = Plugins
# [themes]
# path = /themes
# label = Themes
[community]
path = /community
label = Community

View File

@ -0,0 +1,10 @@
[model]
name = Plugin Categories
inherits = page
label = {{ this.name }}
hidden = yes
protected = yes
[children]
model = plugin-category
order_by = name

View File

@ -0,0 +1,8 @@
[model]
name = Plugin Category
inherits = page
label = {{ this.name }}
hidden = yes
[children]
replaced_with = site.query('/plugins').filter(F.categories.contains(this))

39
models/plugin.ini Normal file
View File

@ -0,0 +1,39 @@
[model]
name = Plugin
label = {{ this.title }}
[children]
enabled = no
[fields.name]
label = Plugin Name (as it appears when you install it)
type = string
size = large
[fields.summary]
label = Summary of the plugin. If not supplied here, it will be pulled from the package data on PyPI.
type = html
size = large
[fields.official]
label = Official
type = boolean
checkbox_label = If true, then the plugin will be marked as official.
default = false
width = 1/4
[fields.allow_comments]
label = Allow Comments
type = boolean
default = yes
checkbox_label = Show comment box
width = 1/4
[fields.categories]
label = Categories
type = select
source = site.query('/plugin-categories')
[fields.tags]
label = Tags used on this site. New line separated. These are not the keywords in setup.py, which are used on PyPI.
type = strings

7
models/plugins.ini Normal file
View File

@ -0,0 +1,7 @@
[model]
name = Plugins
inherits = page
label = {{ this.title }}
[children]
model = plugin

7
models/redirect.ini Normal file
View File

@ -0,0 +1,7 @@
[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.

5
packages/project-data/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
dist
build
*.pyc
*.pyo
*.egg-info

View File

@ -0,0 +1,86 @@
# -*- coding: utf-8 -*-
import cgi
import pkg_resources
import readme_renderer.markdown
import readme_renderer.rst
import readme_renderer.txt
import requests
from lektor.pluginsystem import Plugin
_RENDERERS = {
None: readme_renderer.rst, # Default if description_content_type is None
'': readme_renderer.rst, # Default if description_content_type is None
'text/plain': readme_renderer.txt,
'text/x-rst': readme_renderer.rst,
'text/markdown': readme_renderer.markdown,
}
class ProjectDataPlugin(Plugin):
name = 'Project Data'
description = u'Retrieve project information from PyPI.'
data = {}
def render(self, value, content_type=None):
"""Taken from https://github.com/pypa/warehouse/blob/master/warehouse/filters.py
to ensure compliance and not reinvent the wheel. We don't want to be creative here.
"""
content_type, parameters = cgi.parse_header(content_type or '')
# Get the appropriate renderer
renderer = _RENDERERS.get(content_type, readme_renderer.txt)
# Actually render the given value, this will not only render the value, but
# also ensure that it's had any disallowed markup removed.
rendered = renderer.render(value, **parameters)
# If the content was not rendered, we'll render as plaintext instead. The
# reason it's necessary to do this instead of just accepting plaintext is
# that readme_renderer will deal with sanitizing the content.
if rendered is None:
rendered = readme_renderer.txt.render(value)
return rendered
def package_data(self, name, entry_point=None):
if not entry_point:
entry_point = 'https://pypi.org/pypi'
url = '{}/{}/json'.format(entry_point, name)
resp = requests.get(url)
pkg = resp.json()
self.data.update(pkg['info'])
# Erase bad keys that are sometimes returned from the api
# to handle it in the template.
# To us, unknown is the same as non-existent.
for key in self.data:
val = self.data.get(key)
if type(val) is str and val.strip() == 'UNKNOWN':
self.data[key] = ''
self.data['short_name'] = name.split('lektor-')[1]
# Rewrite description as rendered description.
self.data['description'] = self.render(
self.data['description'], self.data['description_content_type'])
if not self.data.get('home_page'):
self.data['home_page'] = 'https://pypi.org/project/{}/'.format(name)
def github_data(self, owner=None, repo=None):
url = 'https://api.github.com/repos/{}/{}'.format(owner, repo)
response = requests.get(url)
data = response.json()
return data
def project_data(self, name):
self.package_data(name)
# github data not currently used. Commented to save build time.
# if 'github' in self.data.get('home_page'):
# owner = self.data['home_page'].split('/')[-2]
# repo = self.data['home_page'].split('/')[-1]
# self.data['gh'] = self.github_data(owner=owner, repo=repo)
# TODO: support bitbucket
return self.data
def on_setup_env(self, **extra):
self.env.jinja_env.globals['project_data'] = self.project_data

View File

@ -0,0 +1,19 @@
from setuptools import setup
setup(
name='lektor-project-data',
version='0.1',
author='Joseph Nix',
author_email='nixjdm@terminallabs.com',
license='MIT',
py_modules=['lektor_project_data'],
install_requires=[
'requests',
'readme_renderer==20.0',
],
entry_points={
'lektor.plugins': [
'project-data = lektor_project_data:ProjectDataPlugin',
]
}
)

View File

@ -0,0 +1,32 @@
{% macro render_category_nav(active=none) %}
<ul>
{% for category in site.query('/plugin-categories') %}
<li{% if category._id == active %} class="active"{% endif
%}><a href="{{ category|url }}">{{ category.name }}</a></li>
{% endfor %}
</ul>
{% endmacro %}
{% macro render_plugin_list(query) %}
<ul>
{% for plugin in query.order_by('-official', 'name') %}
{% set pd = project_data(plugin.name) %}
{% if plugin.summary %}
{% set summary = plugin.summary %}
{% elif pd.summary %}
{% set summary = pd.summary %}
{% endif %}
{% if plugin.official %}
<li><a href="{{ plugin|url }}">* {{ pd.short_name }}</a>: {{ summary }}</li>
{% if loop.nextitem %}
{% if not loop.nextitem.official %}
---
{% endif %}
{% endif %}
{% else %}
<li><a href="{{ plugin|url }}">{{ pd.short_name }}</a>: {{ summary }}</li>
{% endif %}
{% endfor %}
</ul>
{% endmacro %}

View File

@ -0,0 +1,15 @@
{% extends "plugins.html" %}
{% from "macros/plugins.html" import render_category_nav %}
{% block body %}
<h1>{{ this.title }}</h1>
{% call render_full_width_blocks(this.body.blocks, classes='col-md-12') %}
{% endcall %}
<ul>
{% for category in site.query('/plugin-categories') %}
<li><h3>
<a href="{{ category|url }}">{{ category.title }}</a>
</h3></li>
{% endfor %}
</ul>
{% endblock %}

View File

@ -0,0 +1,8 @@
{% extends "plugins.html" %}
{% block body %}
<h1>{{ this.title }}</h1>
{% call render_full_width_blocks(this.body.blocks, classes='col-md-12') %}
{% endcall %}
{{ render_plugin_list(this.children) }}
{% endblock %}

31
templates/plugin-tag.html Normal file
View File

@ -0,0 +1,31 @@
{% extends "plugins.html" %}
{% from "macros/plugins.html" import render_plugin_list %}
{% block body %}
<h1>Tag: {{ this.tag }}</h1>
{% for event in site.get('/docs/api/plugins/events').children.all() %}
{% if this.tag == event.title %}
<p>
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!
</p>
<p>
<a href="{{ '/docs/plugins'|url }}" class="ref">Intro to Plugins</a>
||
<a href="{{ '/docs/cli/plugins/'|url }}" class="ref">Plugin Commands</a>
||
<a href="{{ '/docs/api/plugins'|url }}" class="ref">Plugin API</a>
||
<a href="{{ event|url }}" class="ref">This Event</a>
</p>
{% endif %}
{% endfor %}
<h2>Plugins:</h2>
<p>(*) Asterisks denote official plugins.</p>
<div class="plugin">
{{ render_plugin_list(this.items) }}
</div>
{% endblock %}

90
templates/plugin.html Normal file
View File

@ -0,0 +1,90 @@
{% extends "plugins.html" %}
{% from "macros/docs.html" import get_doc_icon, get_doc_link %}
{% block body %}
{% set pd = project_data(this.name) %}
{% if this.summary %}
{% set summary = this.summary %}
{% elif pd.summary %}
{% set summary = pd.summary %}
{% endif %}
<!-- Place this tag in your head or just before your close body tag. -->
{# <script async defer src="https://buttons.github.io/buttons.js"></script>#}
<div class="plugin">
<div class="row">
<div class="col-sm-12">
<h1>Plugin &ndash; {{ pd.name }} {{ pd.version }}</h1>
</div>
</div>
<div class="row">
<div class="col-sm-1"></div>
<div class="col-sm-11">
<p>{{ summary }}<p>
</div>
</div>
<div class="row">
<div class="col-sm-3 plugin-margin">
<h4>Project links</h4>
<ul class="tree-nav">
<li><a href="{{ pd.home_page }}" class="ext">Homepage</a></li>
</ul>
{% if 'github' in pd.home_page %}
<div class="separator">
<h4>GitHub Statistics</h4>
</div>
<ul class="button-nav">
<li><p><a class="github-button" href="{{ pd.home_page }}" data-icon="octicon-star" data-size="large" data-show-count="true" aria-label="Star {{ this.name }} on GitHub" target="_blank">Star</a></p></li>
<li><p><a class="github-button" href="{{ pd.home_page }}/fork" data-icon="octicon-repo-forked" data-show-count="true" data-size="large" data-show="true" aria-label="Open Issues" target="_blank">Fork</a></p></li>
<li><p><a class="github-button" href="{{ pd.home_page }}/issues" data-icon="octicon-issue-opened" data-show-count="true" data-size="large" data-show="true" aria-label="Open Issues" target="_blank">Open Issues</a></p></li>
</ul>
{% endif %}
<div class="separator">
<h4>Meta</h4>
</div>
<p><strong>Version:</strong> {{ pd.version }}</p>
<p><strong>Author:</strong>
{% if pd.author_email %}
<a href = "mailto:{{ pd.author_email }}">{{ pd.author }}</a>
{% else %}
{{ pd.author }}
{% endif %}
</p>
<div class="separator">
<h4>Tags</h4>
</div>
{% if this.tags %}
{% for t in this.tags|sort %}
{{ "and " if (loop.last and this.tags|length > 1) }}
<a href="{{ ('/plugins/tag/' ~ t.lower() ~ '/')|url }}">{{ t }}</a>{{ ", " if not loop.last }}
{% endfor %}
{% else %}
<p>Plugin has no tags.</p>
{% endif %}
</div>
<div class="col-sm-9 doc-styling">
<h2>Project Description</h2>
{% if pd.description %}
{{ pd.description|safe }} {# comes out as a text string always #}
{% else %}
<i>Plugin has no long_description</i>
{% endif %}
{% if this.allow_comments %}
<div class="comment-box">
<h2>Comments</h2>
{{ render_disqus_comments() }}
</div>
{% endif %}
</div>
</div>
</div>
{% endblock %}

24
templates/plugins.html Normal file
View File

@ -0,0 +1,24 @@
{% extends "layout.html" %}
{% from "macros/plugins.html" import render_plugin_list %}
{% from 'macros/blocksupport.html' import render_full_width_blocks %}
{% block title %}{{ this.title }}{% endblock %}
{% block outerbody %}
{% set image = site.get('/plugins').attachments.images.first() %}
{% if image %}
<div class="page-banner page-banner-300" style="background-image: url({{ image|url }})"></div>
{% endif %}
{{ super() }}
{% endblock %}
{% block body %}
<h1>{{ this.title }}</h1>
{% call render_full_width_blocks(this.body.blocks, classes='col-md-12') %}
{% endcall %}
{% for category in site.query('/plugin-categories').order_by('title') %}
<h2><a href="{{ category|url }}">{{ category.title }}</a></h2>
<div class="plugin">
{{ render_plugin_list(category.children) }}
</div>
{% endfor %}
{% endblock %}

1
templates/redirect.html Normal file
View File

@ -0,0 +1 @@
<meta http-equiv="refresh" content="0; URL='{{ this.target|url }}'" />

View File

@ -217,7 +217,7 @@ div.blog-snippet {
}
}
div.doc-styling, div.blog-post {
div.doc-styling, div.blog-post, div.plugin {
line-height: 1.75;
a.ref {
@ -225,6 +225,7 @@ div.doc-styling, div.blog-post {
}
a.ext {
white-space: nowrap;
&:before {
@extend .glyphicon;
@extend .glyphicon-link;
@ -592,6 +593,12 @@ p.meta {
color: lighten($gray, 30);
}
ul.button-nav {
margin: 25px 0;
padding-left: 10px;
list-style: none;
}
ul.toc, ul.toc ul {
font-size: 14px;
padding-left: 25px;
@ -665,6 +672,18 @@ ul.tree-nav {
}
}
div.plugin-margin {
h4 {
margin: 25px 0;
}
div.separator {
border-top: 1px solid #ddd;
margin: 25px 0;
}
}
div.comment-box {
border-top: 1px solid #ddd;
margin-top: 35px;