Merge pull request #68 from ajdavis/update-plugin-howto
Update the "Adding Field Type" howto.
This commit is contained in:
commit
b9f7854f7c
|
@ -41,3 +41,6 @@ def setup_env(self, **extra):
|
|||
```
|
||||
|
||||
For more information see [value_from_raw :ref](value-from-raw/).
|
||||
|
||||
There is a more complete example in the
|
||||
[Plugin How To :ref](../../../plugins/howto/#adding-new-field-types).
|
||||
|
|
|
@ -114,64 +114,76 @@ 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 a "datetime" type to the set of
|
||||
[field types :ref](../../api/db/types/) used in your models, because the
|
||||
built-in "date" type has no time component. You might update `blog-post.ini`
|
||||
from the [blog guide :ref](../../guides/blog) like so:
|
||||
Let's say you want to add an "asciidoc"
|
||||
[field type :ref](../../api/db/types/) so you can write with [AsciiDoc](http://www.methods.co.nz/asciidoc) markup.
|
||||
|
||||
First [install AsciiDoc](http://www.methods.co.nz/asciidoc/INSTALL.html) so its command-line program is available. Then update `blog-post.ini` from the [blog guide :ref](../../guides/blog) like so:
|
||||
|
||||
```ini
|
||||
[fields.pub_date]
|
||||
label = Publication date
|
||||
type = datetime # Custom "datetime" type.
|
||||
[fields.body]
|
||||
label = Body
|
||||
type = asciidoc # Custom type.
|
||||
```
|
||||
|
||||
In a blog post's `contents.lr`, specify its publication date like:
|
||||
In a blog post's `contents.lr`, write some AsciiDoc like:
|
||||
|
||||
```
|
||||
pub_date: 2016-01-02 12:34:56
|
||||
body:
|
||||
|
||||
== Header 1
|
||||
|
||||
Some text.
|
||||
|
||||
-----
|
||||
code here
|
||||
-----
|
||||
```
|
||||
|
||||
You can add your "datetime" type to Lektor with a plugin:
|
||||
You can add your "asciidoc" type to Lektor with a plugin:
|
||||
|
||||
```python
|
||||
from datetime import datetime
|
||||
from subprocess import PIPE, Popen
|
||||
|
||||
from lektor.pluginsystem import Plugin
|
||||
from lektor.types import Type
|
||||
|
||||
class DatetimeType(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 datetime.strptime(raw.value, '%Y-%m-%d %H:%M:%S')
|
||||
return HTML(asciidoc_to_html(raw.value or u''))
|
||||
|
||||
def strftime_filter(dt, fmt='%B %-d, %Y'):
|
||||
return dt.strftime(fmt)
|
||||
|
||||
class DatetimeTypePlugin(Plugin):
|
||||
name = u'datetime type'
|
||||
description = u'Adds a new field type, "datetime".'
|
||||
class AsciiDocPlugin(Plugin):
|
||||
name = u'AsciiDoc'
|
||||
description = u'Adds AsciiDoc field type to Lektor.'
|
||||
|
||||
def on_setup_env(self, **extra):
|
||||
self.env.types['datetime'] = DatetimeType
|
||||
self.env.jinja_env.filters['strftime'] = strftime_filter
|
||||
```
|
||||
|
||||
This plugin also adds a `strftime` filter to Jinja.
|
||||
Render a datetime with the default format in a template like:
|
||||
|
||||
```html+jinja
|
||||
Published on {{ this.pub_date|strftime }}
|
||||
```
|
||||
|
||||
Or a custom format:
|
||||
|
||||
```html+jinja
|
||||
Published on {{ this.pub_date|strftime('%Y-%m-%d') }}
|
||||
```
|
||||
|
||||
Python datetime objects implement the standard comparison protocol, so
|
||||
ordering still works without modifying `blog.ini`:
|
||||
|
||||
```ini
|
||||
[children]
|
||||
model = blog-post
|
||||
order_by = -pub_date, title
|
||||
# Derives type name "asciidoc" from class name.
|
||||
self.env.add_type(AsciiDocType)
|
||||
```
|
||||
|
|
Loading…
Reference in New Issue