[pluginlist-update] Rerunning webpack, adding section to plugins/publishing explaining how to get your plugin listed, adding custom summary field to plugin model, adding Disqus to plugin pages, finishing project_data plugin and using it to fill out plugin page, finishing plugin page.

This commit is contained in:
Joseph Nix 2018-05-03 15:51:52 -05:00
parent 56dc0ae10a
commit ae9e7090eb
12 changed files with 197 additions and 39 deletions

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":""}

File diff suppressed because one or more lines are too long

View File

@ -8,7 +8,7 @@ body:
Once you are happy with a plugin you can publish it so that other people Once you are happy with a plugin you can publish it so that other people
can use it. Publishing of plugins happens through the 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. automatically done with the help of the lektor shell command.
## Enhance your setup.py ## Enhance your setup.py
@ -21,6 +21,8 @@ set. Here is a basic example of doing this:
```python ```python
from setuptools import setup from setuptools import setup
with open('README.md', encoding="utf8") as f:
readme = f.read()
setup( setup(
name='lektor-your-plugin', name='lektor-your-plugin',
@ -31,6 +33,12 @@ setup(
license='MIT', license='MIT',
packages=['lektor_your_plugin'], packages=['lektor_your_plugin'],
description='Basic description goes here', description='Basic description goes here',
long_description=readme,
long_description_content_type='text/markdown',
classifiers=[
'Framework :: Lektor',
'Environment :: Plugins',
],
entry_points={ entry_points={
'lektor.plugins': [ 'lektor.plugins': [
'hello-world = lektor_hello_world:HelloWorldPlugin', 'hello-world = lektor_hello_world:HelloWorldPlugin',
@ -55,3 +63,15 @@ $ lektor dev publish-plugin
When you use this for the first time it will prompt you for your login 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. 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](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, including
* long_description and long_description_content_type
* author and author_email
* classifiers, such as
* `Framework :: Lektor`
* `Environment :: Plugins`
* keywords

View File

@ -10,5 +10,7 @@ text:
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. 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. 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.
If you want to make or publish your own plugin, or see our [docs :ref](/docs/plugins).
---- ----
class: default class: default

View File

@ -1,3 +1,5 @@
name: flask name: flask
--- ---
categories: content categories: content
---
summary:

View File

@ -10,11 +10,24 @@ label = Plugin Name (as it appears when you install it)
type = string type = string
size = large 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] [fields.official]
label = Official label = Official
type = boolean type = boolean
checkbox_label = If true, then the plugin will be marked as official. checkbox_label = If true, then the plugin will be marked as official.
default = false 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] [fields.categories]
label = Categories label = Categories

View File

@ -1,27 +1,75 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from qypi.api import QyPI import cgi
import pkg_resources
import readme_renderer.markdown
import readme_renderer.rst
import readme_renderer.txt
import requests
from lektor.pluginsystem import Plugin 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): class ProjectDataPlugin(Plugin):
name = 'Project Data' name = 'Project Data'
description = u'Retrieve project information from PyPI.' description = u'Retrieve project information from PyPI.'
data = {} 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): def package_data(self, name, entry_point=None):
if not entry_point: if not entry_point:
entry_point = 'https://pypi.org/pypi' entry_point = 'https://pypi.org/pypi'
url = '{}/{}/json'.format(entry_point, name)
q = QyPI(entry_point) resp = requests.get(url)
pkg = q.get_package(name) pkg = resp.json()
self.data.update(pkg['info']) self.data.update(pkg['info'])
# rewrite description as rendered description
self.data['description'] = self.render(
self.data['description'], self.data['description_content_type'])
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): def project_data(self, name):
self.package_data(name) self.package_data(name)
# self.github_data if 'github' in self.data.get('home_page'):
# self.bitbucket_data 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 return self.data
def on_setup_env(self, **extra): def on_setup_env(self, **extra):
self.env.jinja_env.globals['project_data'] = self.project_data self.env.jinja_env.globals['project_data'] = self.project_data

View File

@ -8,7 +8,8 @@ setup(
license='MIT', license='MIT',
py_modules=['lektor_project_data'], py_modules=['lektor_project_data'],
install_requires=[ install_requires=[
'qypi==0.4.1', 'requests',
'readme_renderer==0.20',
], ],
entry_points={ entry_points={
'lektor.plugins': [ 'lektor.plugins': [

View File

@ -10,15 +10,22 @@
{% macro render_plugin_list(category) %} {% macro render_plugin_list(category) %}
<ul> <ul>
{% for plugin in category.children.order_by('-official', 'title') %} {% for plugin in category.children.order_by('-official', 'title') %}
{% set pd = project_data(plugin.name) %}
{% if plugin.summary %}
{% set summary = plugin.summary %}
{% elif pd.summary %}
{% set summary = pd.summary %}
{% endif %}
{% if plugin.official %} {% if plugin.official %}
<li><a href="{{ plugin|url }}">* {{ plugin.name }}</a></li> <li><a href="{{ plugin|url }}">* {{ plugin.name }}</a>: {{ summary }}</li>
{% if loop.nextitem %} {% if loop.nextitem %}
{% if not loop.nextitem.official %} {% if not loop.nextitem.official %}
--- ---
{% endif %} {% endif %}
{% endif %} {% endif %}
{% else %} {% else %}
<li><a href="{{ plugin|url }}">{{ plugin.name }}</a></li> <li><a href="{{ plugin|url }}">{{ plugin.name }}</a>: {{ summary }}</li>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</ul> </ul>

View File

@ -1,15 +1,69 @@
{% extends "plugins.html" %} {% extends "plugins.html" %}
{% from "macros/docs.html" import get_doc_icon, get_doc_link %}
{% block body %} {% block body %}
<h1>{{ this.name }}</h1>
{% set pd = project_data(this.name) %} {% set pd = project_data(this.name) %}
{{ pd }}<br> {% if this.summary %}
111<br> {% set summary = this.summary %}
{{ pd.author }}<br> {% elif pd.summary %}
{{ pd.version }}<br> {% set summary = pd.summary %}
{{ pd.home_page }}<br> {% endif %}
{{ pd.summary }}<br>
<br> <!-- Place this tag in your head or just before your close body tag. -->
{{ pd.description|markdown }} {# <script async defer src="https://buttons.github.io/buttons.js"></script>#}
<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" style="padding-top: 25px;">
<div>
<h4>Project links</h4>
<ul class="tree-nav">
<li><a href="{{ pd.home_page }}">Homepage</a></li>
</ul>
</div>
{% if 'github' in pd.home_page %}
<div>
<h4>GitHub statistics</h4>
<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">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">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">Open Issues</a></p></li>
</ul>
</div>
{% endif %}
<h4>Meta</h4>
<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>
<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>
{% endblock %} {% endblock %}

View File

@ -592,6 +592,12 @@ p.meta {
color: lighten($gray, 30); color: lighten($gray, 30);
} }
ul.button-nav {
margin: 25px 0;
padding-left: 10px;
list-style: none;
}
ul.toc, ul.toc ul { ul.toc, ul.toc ul {
font-size: 14px; font-size: 14px;
padding-left: 25px; padding-left: 25px;