mirror of
https://github.com/vale981/ablog
synced 2025-03-06 09:41:39 -05:00
Enabled multiple posting of a document (issue #4).
This commit is contained in:
parent
68e4f29f27
commit
416d089343
6 changed files with 142 additions and 100 deletions
|
@ -10,12 +10,20 @@ from .post import (PostDirective, PostListDirective,
|
||||||
|
|
||||||
__version__ = '0.1'
|
__version__ = '0.1'
|
||||||
|
|
||||||
|
def anchor(post):
|
||||||
|
|
||||||
|
|
||||||
|
if post.section:
|
||||||
|
return '#' + post.section
|
||||||
|
else:
|
||||||
|
return ''
|
||||||
|
|
||||||
def init_ablog(app):
|
def init_ablog(app):
|
||||||
"""Instantiate ABlog and link from `html_context` so that it can be
|
"""Instantiate ABlog and link from `html_context` so that it can be
|
||||||
reached from templates."""
|
reached from templates."""
|
||||||
|
|
||||||
app.config.html_context['ablog'] = Blog(app)
|
app.config.html_context['ablog'] = Blog(app)
|
||||||
|
app.config.html_context['anchor'] = anchor
|
||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
"""Setup ABlog extension."""
|
"""Setup ABlog extension."""
|
||||||
|
|
|
@ -209,7 +209,7 @@ class Blog(object):
|
||||||
def link_posts(self):
|
def link_posts(self):
|
||||||
"""Link posts after sorting them post by published date."""
|
"""Link posts after sorting them post by published date."""
|
||||||
|
|
||||||
posts = list(self.posts)
|
posts = [post for post in self.posts if post.order == 1]
|
||||||
posts.sort()
|
posts.sort()
|
||||||
posts[0].prev = posts[-1].next = None
|
posts[0].prev = posts[-1].next = None
|
||||||
for i in range(1, len(posts)):
|
for i in range(1, len(posts)):
|
||||||
|
@ -262,6 +262,8 @@ class Post(object):
|
||||||
|
|
||||||
self.ablog = ablog
|
self.ablog = ablog
|
||||||
self.docname = docname
|
self.docname = docname
|
||||||
|
self.section = info['section']
|
||||||
|
self.order = info['order']
|
||||||
self.date = date = info['date']
|
self.date = date = info['date']
|
||||||
self.update = info['update']
|
self.update = info['update']
|
||||||
self.published = date and date < TOMORROW
|
self.published = date and date < TOMORROW
|
||||||
|
@ -465,7 +467,10 @@ class Collection(object):
|
||||||
def add(self, post):
|
def add(self, post):
|
||||||
"""Add post to the collection."""
|
"""Add post to the collection."""
|
||||||
|
|
||||||
self._posts[post.docname] = post
|
post_name = post.docname
|
||||||
|
if post.section:
|
||||||
|
post_name += '#' + post.section
|
||||||
|
self._posts[post_name] = post
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def relsize(self):
|
def relsize(self):
|
||||||
|
|
|
@ -11,7 +11,7 @@ from sphinx.util.compat import Directive
|
||||||
from docutils.parsers.rst import directives
|
from docutils.parsers.rst import directives
|
||||||
|
|
||||||
import ablog
|
import ablog
|
||||||
from .blog import Blog
|
from .blog import Blog, slugify
|
||||||
|
|
||||||
class PostNode(nodes.Element):
|
class PostNode(nodes.Element):
|
||||||
"""Represent ``post`` directive content and options in document tree."""
|
"""Represent ``post`` directive content and options in document tree."""
|
||||||
|
@ -129,18 +129,26 @@ def process_posts(app, doctree):
|
||||||
# "document isn't included in any toctree" warning is not issued
|
# "document isn't included in any toctree" warning is not issued
|
||||||
app.env.metadata[docname]['orphan'] = True
|
app.env.metadata[docname]['orphan'] = True
|
||||||
|
|
||||||
|
blog = Blog(app)
|
||||||
|
multi_post = len(post_nodes) > 1
|
||||||
|
for order, node in enumerate(post_nodes, start=1):
|
||||||
|
|
||||||
node = post_nodes[0]
|
if multi_post:
|
||||||
|
# section title, and first few paragraphs of the section of post
|
||||||
|
# are used when there are more than 1 posts
|
||||||
|
section = node
|
||||||
|
while True:
|
||||||
|
if isinstance(section, nodes.section):
|
||||||
|
break
|
||||||
|
section = node.parent
|
||||||
|
else:
|
||||||
|
section = doctree
|
||||||
|
|
||||||
if len(post_nodes) > 1:
|
|
||||||
env.warn(docname, 'multiple post directives found, '
|
|
||||||
'first one is considered')
|
|
||||||
#from code import interact; interact(local=locals())
|
|
||||||
# Making sure that post has a title because all post titles
|
# Making sure that post has a title because all post titles
|
||||||
# are needed when resolving post lists in documents
|
# are needed when resolving post lists in documents
|
||||||
title = node['title']
|
title = node['title']
|
||||||
if not title:
|
if not title:
|
||||||
for title in doctree.traverse(nodes.title):
|
for title in section.traverse(nodes.title):
|
||||||
break
|
break
|
||||||
# A problem with the following is that title may contain pending
|
# A problem with the following is that title may contain pending
|
||||||
# references, e.g. :ref:`tag-tips`
|
# references, e.g. :ref:`tag-tips`
|
||||||
|
@ -157,7 +165,7 @@ def process_posts(app, doctree):
|
||||||
excerpt.append(child.deepcopy())
|
excerpt.append(child.deepcopy())
|
||||||
else:
|
else:
|
||||||
count = 0
|
count = 0
|
||||||
for nod in doctree.traverse(nodes.paragraph):
|
for nod in section.traverse(nodes.paragraph):
|
||||||
excerpt.append(nod.deepcopy())
|
excerpt.append(nod.deepcopy())
|
||||||
count += 1
|
count += 1
|
||||||
if count >= (node['excerpt'] or 0):
|
if count >= (node['excerpt'] or 0):
|
||||||
|
@ -165,7 +173,7 @@ def process_posts(app, doctree):
|
||||||
node.replace_self([])
|
node.replace_self([])
|
||||||
if node['image']:
|
if node['image']:
|
||||||
count = 0
|
count = 0
|
||||||
for nod in doctree.traverse(nodes.image):
|
for nod in section.traverse(nodes.image):
|
||||||
count += 1
|
count += 1
|
||||||
if count == node['image']:
|
if count == node['image']:
|
||||||
excerpt.append(nod.deepcopy())
|
excerpt.append(nod.deepcopy())
|
||||||
|
@ -189,7 +197,32 @@ def process_posts(app, doctree):
|
||||||
else:
|
else:
|
||||||
update = date
|
update = date
|
||||||
|
|
||||||
env.ablog_posts[docname] = postinfo = {
|
# if docname ends with `index` use folder name to reference the document
|
||||||
|
# a potential problem here is that there may be files/folders with the
|
||||||
|
# same name, so issuing a warning when that's the case may be a good idea
|
||||||
|
folder, label = os.path.split(docname)
|
||||||
|
if label == 'index':
|
||||||
|
folder, label = os.path.split(folder)
|
||||||
|
if not label:
|
||||||
|
label = slugify(title)
|
||||||
|
|
||||||
|
|
||||||
|
post_name = docname
|
||||||
|
section_name = ''
|
||||||
|
|
||||||
|
if multi_post and section.parent is not doctree:
|
||||||
|
section_name = section.attributes['ids'][0]
|
||||||
|
post_name = docname + '#' + section_name
|
||||||
|
label += '-' + section_name
|
||||||
|
|
||||||
|
# create a reference for the post
|
||||||
|
app.env.domains['std'].data['labels'][label] = (docname, label, title)
|
||||||
|
|
||||||
|
|
||||||
|
postinfo = {
|
||||||
|
'docname': docname,
|
||||||
|
'section': section_name,
|
||||||
|
'order': order,
|
||||||
'date': date,
|
'date': date,
|
||||||
'update': update,
|
'update': update,
|
||||||
'title': title,
|
'title': title,
|
||||||
|
@ -202,19 +235,14 @@ def process_posts(app, doctree):
|
||||||
'image': node['image'],
|
'image': node['image'],
|
||||||
'exclude': node['exclude']}
|
'exclude': node['exclude']}
|
||||||
|
|
||||||
# if docname ends with `index` use folder name to reference the document
|
if docname not in env.ablog_posts:
|
||||||
# a potential problem here is that there may be files/folders with the
|
env.ablog_posts[docname] = []
|
||||||
# same name, so issuing a warning when that's the case may be a good idea
|
env.ablog_posts[docname].append(postinfo)
|
||||||
folder, label = os.path.split(docname)
|
|
||||||
if label == 'index':
|
|
||||||
folder, label = os.path.split(folder)
|
|
||||||
app.env.domains['std'].data['labels'][label] = (docname, label, title)
|
|
||||||
|
|
||||||
|
|
||||||
# instantiate catalogs and collections here
|
# instantiate catalogs and collections here
|
||||||
# so that references are created and no warnings are issued
|
# so that references are created and no warnings are issued
|
||||||
|
|
||||||
blog = Blog(app)
|
|
||||||
for key in ['tags', 'author', 'category', 'location']:
|
for key in ['tags', 'author', 'category', 'location']:
|
||||||
catalog = blog.catalogs[key]
|
catalog = blog.catalogs[key]
|
||||||
for label in postinfo[key]:
|
for label in postinfo[key]:
|
||||||
|
@ -346,5 +374,6 @@ def register_posts(app):
|
||||||
"""Register posts found in the Sphinx build environment."""
|
"""Register posts found in the Sphinx build environment."""
|
||||||
|
|
||||||
blog = Blog()
|
blog = Blog()
|
||||||
for docname, postinfo in getattr(app.env, 'ablog_posts', {}).items():
|
for docname, posts in getattr(app.env, 'ablog_posts', {}).items():
|
||||||
|
for postinfo in posts:
|
||||||
blog.register(docname, postinfo)
|
blog.register(docname, postinfo)
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
</h1>
|
</h1>
|
||||||
{% for post in archive %}
|
{% for post in archive %}
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<h2><a href="{{ pathto(post.docname) }}">{{ post.title }}</a></h2>
|
<h2><a href="{{ pathto(post.docname) }}{{ anchor(post) }}">{{ post.title }}</a></h2>
|
||||||
|
|
||||||
<ul class="ablog-archive">
|
<ul class="ablog-archive">
|
||||||
<li>{% if post.published %}
|
<li>{% if post.published %}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<span style="float: left;">
|
<span style="float: left;">
|
||||||
{% if post.prev %}
|
{% if post.prev %}
|
||||||
{% if not ablog.fontawesome %}{{ gettext('Previous') }}: {% endif %}
|
{% if not ablog.fontawesome %}{{ gettext('Previous') }}: {% endif %}
|
||||||
<a href="{{ pathto(post.prev.docname) }}">
|
<a href="{{ pathto(post.prev.docname) }}{{ anchor(post.prev) }}">
|
||||||
{% if ablog.fontawesome %}<i class="fa fa-arrow-circle-left"></i>{% endif %}
|
{% if ablog.fontawesome %}<i class="fa fa-arrow-circle-left"></i>{% endif %}
|
||||||
{{ post.prev.title }}
|
{{ post.prev.title }}
|
||||||
</a>
|
</a>
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
<span style="float: right;">
|
<span style="float: right;">
|
||||||
{% if post.next %}
|
{% if post.next %}
|
||||||
{% if not ablog.fontawesome %}{{ gettext('Next') }}: {% endif %}
|
{% if not ablog.fontawesome %}{{ gettext('Next') }}: {% endif %}
|
||||||
<a href="{{ pathto(post.next.docname) }}">
|
<a href="{{ pathto(post.next.docname) }}{{ anchor(post.next) }}">
|
||||||
{{ post.next.title }}
|
{{ post.next.title }}
|
||||||
{% if ablog.fontawesome %}<i class="fa fa-arrow-circle-right"></i>{% endif %}
|
{% if ablog.fontawesome %}<i class="fa fa-arrow-circle-right"></i>{% endif %}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
{% set pcount = 1 %}
|
{% set pcount = 1 %}
|
||||||
{% for recent in ablog.recent(5, pagename) %}
|
{% for recent in ablog.recent(5, pagename) %}
|
||||||
<li><a href="{{ pathto(recent.docname) }}">{{ recent.title }}</a></li>
|
<li><a href="{{ pathto(recent.docname) }}{{ anchor(recent) }}">{{ recent.title }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
Loading…
Add table
Reference in a new issue