mirror of
https://github.com/getpelican/pelican.git
synced 2025-10-15 20:28:56 +02:00
Theme modifications, add a summary for the articles.
This commit is contained in:
parent
8310ec98c4
commit
62576f91c5
6 changed files with 122 additions and 28 deletions
|
|
@ -13,6 +13,7 @@ from feedgenerator import Atom1Feed
|
|||
|
||||
# import the directives to have pygments support
|
||||
import rstdirectives
|
||||
from utils import truncate_html_words
|
||||
|
||||
## Constants ##########################################################
|
||||
|
||||
|
|
@ -58,6 +59,13 @@ def generate_blog(path=None, theme=None, output_path=None, markup=None,
|
|||
# get the list of files to parse
|
||||
if not path:
|
||||
raise Exception('you need to specify a path to search the docs on !')
|
||||
|
||||
# remove all the existing content from the output folder
|
||||
try:
|
||||
shutil.rmtree(os.path.join(output_path))
|
||||
except:
|
||||
pass
|
||||
|
||||
files = []
|
||||
for root, dirs, temp_files in os.walk(path, followlinks=True):
|
||||
files.extend([os.sep.join((root, f)) for f in temp_files
|
||||
|
|
@ -119,14 +127,9 @@ def generate_blog(path=None, theme=None, output_path=None, markup=None,
|
|||
# copy static paths to output
|
||||
for path in context['STATIC_PATHS']:
|
||||
try:
|
||||
real_output = os.path.join(output_path, path)
|
||||
theme_path = os.path.join(theme, path)
|
||||
|
||||
print "updating %s" % real_output
|
||||
shutil.rmtree(real_output)
|
||||
shutil.copytree(theme_path, real_output)
|
||||
|
||||
except OSError as e:
|
||||
shutil.copytree(os.path.join(theme, path),
|
||||
os.path.join(output_path, path))
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
|
|
@ -304,4 +307,4 @@ class Article(object):
|
|||
|
||||
@property
|
||||
def summary(self):
|
||||
return self.content
|
||||
return truncate_html_words(self.content, 50)
|
||||
|
|
|
|||
67
pelican/utils.py
Normal file
67
pelican/utils.py
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
import re
|
||||
|
||||
def truncate_html_words(s, num, end_text='...'):
|
||||
"""Truncates HTML to a certain number of words (not counting tags and
|
||||
comments). Closes opened tags if they were correctly closed in the given
|
||||
html. Takes an optional argument of what should be used to notify that the
|
||||
string has been truncated, defaulting to ellipsis (...).
|
||||
|
||||
Newlines in the HTML are preserved.
|
||||
From the django framework.
|
||||
"""
|
||||
length = int(num)
|
||||
if length <= 0:
|
||||
return u''
|
||||
html4_singlets = ('br', 'col', 'link', 'base', 'img', 'param', 'area', 'hr', 'input')
|
||||
# Set up regular expressions
|
||||
re_words = re.compile(r'&.*?;|<.*?>|(\w[\w-]*)', re.U)
|
||||
re_tag = re.compile(r'<(/)?([^ ]+?)(?: (/)| .*?)?>')
|
||||
# Count non-HTML words and keep note of open tags
|
||||
pos = 0
|
||||
end_text_pos = 0
|
||||
words = 0
|
||||
open_tags = []
|
||||
while words <= length:
|
||||
m = re_words.search(s, pos)
|
||||
if not m:
|
||||
# Checked through whole string
|
||||
break
|
||||
pos = m.end(0)
|
||||
if m.group(1):
|
||||
# It's an actual non-HTML word
|
||||
words += 1
|
||||
if words == length:
|
||||
end_text_pos = pos
|
||||
continue
|
||||
# Check for tag
|
||||
tag = re_tag.match(m.group(0))
|
||||
if not tag or end_text_pos:
|
||||
# Don't worry about non tags or tags after our truncate point
|
||||
continue
|
||||
closing_tag, tagname, self_closing = tag.groups()
|
||||
tagname = tagname.lower() # Element names are always case-insensitive
|
||||
if self_closing or tagname in html4_singlets:
|
||||
pass
|
||||
elif closing_tag:
|
||||
# Check for match in open tags list
|
||||
try:
|
||||
i = open_tags.index(tagname)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
# SGML: An end tag closes, back to the matching start tag, all unclosed intervening start tags with omitted end tags
|
||||
open_tags = open_tags[i+1:]
|
||||
else:
|
||||
# Add it to the start of the open tags list
|
||||
open_tags.insert(0, tagname)
|
||||
if words <= length:
|
||||
# Don't try to close tags if we don't need to truncate
|
||||
return s
|
||||
out = s[:end_text_pos]
|
||||
if end_text:
|
||||
out += ' ' + end_text
|
||||
# Close any tags still open
|
||||
for tag in open_tags:
|
||||
out += '</%s>' % tag
|
||||
# Return string
|
||||
return out
|
||||
|
|
@ -34,9 +34,12 @@ h2, h3, h4, h5, h6 {
|
|||
font-weight: 400;
|
||||
line-height: 1.1;
|
||||
margin-bottom: .8em;
|
||||
margin-top: .8em;
|
||||
}
|
||||
|
||||
h3, h4, h5, h6 { margin-top: .8em; }
|
||||
|
||||
hr { border: 2px solid #EEEEEE; }
|
||||
|
||||
/* Anchors */
|
||||
a {outline: 0;}
|
||||
a img {border: 0px; text-decoration: none;}
|
||||
|
|
@ -54,7 +57,6 @@ a:hover, a:active {
|
|||
|
||||
/* Paragraphs */
|
||||
p {margin-bottom: 1.143em;}
|
||||
* p:last-child {margin-bottom: 0;}
|
||||
|
||||
strong, b {font-weight: bold;}
|
||||
em, i {font-style: italic;}
|
||||
|
|
@ -73,6 +75,14 @@ ol {
|
|||
margin: 1em 0 1.5em 1.5em;
|
||||
}
|
||||
|
||||
.post-info {
|
||||
float:right;
|
||||
margin:10px;
|
||||
padding:5px;
|
||||
}
|
||||
|
||||
.readmore { float: right }
|
||||
|
||||
dl {margin: 0 0 1.5em 0;}
|
||||
dt {font-weight: bold;}
|
||||
dd {margin-left: 1.5em;}
|
||||
|
|
@ -121,7 +131,7 @@ img.left, figure.left {float: right; margin: 0 0 2em 2em;}
|
|||
}
|
||||
|
||||
/* Banner */
|
||||
#banner h1 {font-size: 3.571em; line-height: .6;}
|
||||
#banner h1 {font-size: 3.571em; line-height: 0;}
|
||||
#banner h1 a:link, #banner h1 a:visited {
|
||||
color: #000305;
|
||||
display: block;
|
||||
|
|
@ -324,7 +334,7 @@ img.left, figure.left {float: right; margin: 0 0 2em 2em;}
|
|||
li:last-child .hentry, #content > .hentry {border: 0; margin: 0;}
|
||||
#content > .hentry {padding: 1em 0;}
|
||||
|
||||
.entry-title {font-size: 1.429em; margin-bottom: 5px; margin-top: 0; }
|
||||
.entry-title {font-size: 2em; margin-bottom: 5px; margin-top: 0; }
|
||||
.entry-title a:link, .entry-title a:visited {text-decoration: none;}
|
||||
|
||||
.hentry .post-info * {font-style: normal;}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<section id="content" class="body">
|
||||
<div class="hentry">
|
||||
<article>
|
||||
<header> <h2 class="entry-title"><a href="{{ article.url }}" rel="bookmark" title="Permalink to {{ article.title}}">{{ article.title }}</a></h2> </header>
|
||||
<div class="entry-content">
|
||||
<footer class="post-info">
|
||||
<abbr class="published" title="{{ article.date.isoformat() }}">
|
||||
{{ article.date.strftime('%Y-%m-%d %H:%M') }}
|
||||
{{ article.date.strftime('%a %d %B %Y') }}
|
||||
</abbr>
|
||||
<address class="vcard author">
|
||||
By <a class="url fn" href="#">{{ article.author }}</a>
|
||||
</address>
|
||||
</address>In <a href="{{ BLOGURL }}/category/{{ article.category }}.html">{{ article.category }}</a>
|
||||
</footer><!-- /.post-info -->
|
||||
{{ article.content }}
|
||||
</div><!-- /.entry-content -->
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
<body id="index" class="home">
|
||||
|
||||
<header id="banner" class="body">
|
||||
<h1><a href="#">{{ BLOGNAME }} <strong>{{ BLOGSUBTITLE }}</strong></a></h1>
|
||||
<h1><a href="{{ BLOGURL }}">{{ BLOGNAME }} {% if BLOGSUBTITLE %} <strong>{{ BLOGSUBTITLE }}</strong>{% endif %}</a></h1>
|
||||
<nav><ul>
|
||||
{% for title, link in MENUITEMS %}
|
||||
<li><a href="{{ link }}">{{ title }}</a></li>
|
||||
|
|
@ -40,7 +40,7 @@
|
|||
<h2>blogroll</h2>
|
||||
<ul>
|
||||
{% for name, link in BLOGROLL %}
|
||||
<li><a href="{{ BLOGURL }}/{{ link }}">{{ name }}</a></li>
|
||||
<li><a href="{{ link }}">{{ name }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div><!-- /.blogroll -->
|
||||
|
|
@ -49,7 +49,7 @@
|
|||
<div class="social">
|
||||
<h2>social</h2>
|
||||
<ul>
|
||||
<li><a href="{{ BLOGURL }}/atom.xml" rel="alternate">atom feed</a></li>
|
||||
<li><a href="{{ BLOGURL }}/feeds/all.atom.xml" rel="alternate">atom feed</a></li>
|
||||
{% for name, link in SOCIAL %}
|
||||
<li><a href="{{ link }}">{{ name }}</a></li>
|
||||
{% endfor %}
|
||||
|
|
@ -63,7 +63,7 @@
|
|||
Proudly powered by <a href="http://hg.lolnet.org/pelican/">pelican</a>, which takes great advantages of <a href="http://python.org">python</a>.
|
||||
</address><!-- /#about -->
|
||||
|
||||
<p>The theme is by<a href="http://smashingmagazine.com">Smashing Magazine</a>, thanks!</p>
|
||||
<p>The theme is by <a href="http://smashingmagazine.com">Smashing Magazine</a>, thanks!</p>
|
||||
</footer><!-- /#contentinfo -->
|
||||
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -4,28 +4,42 @@
|
|||
{% for article in articles %}
|
||||
{% if loop.index == 1 %}
|
||||
<aside id="featured" class="body"><article>
|
||||
<hgroup> <h2>Last article</h2> <h3><a href="{{ BLOGURL }}/{{ article.url }}">{{ article.title }}</a></h3> </hgroup>
|
||||
{{ article.summary }}
|
||||
<h2 class="entry-title"><a href="{{ BLOGURL }}/{{ article.url }}">{{ article.title }}</a></h2>
|
||||
<footer class="post-info">
|
||||
<abbr class="published" title="{{ article.date.isoformat() }}">
|
||||
{{ article.date.strftime('%a %d %B %Y') }}
|
||||
</abbr>
|
||||
|
||||
<address class="vcard author">
|
||||
By <a class="url fn" href="#">{{ article.author }}</a>
|
||||
</address>In <a href="{{ BLOGURL }}/category/{{ article.category }}.html">{{ article.category }}</a>
|
||||
</footer><!-- /.post-info -->
|
||||
{{ article.content }}
|
||||
</article></aside><!-- /#featured -->
|
||||
<section id="content" class="body">
|
||||
<ol id="posts-list" class="hfeed">
|
||||
{% if loop.length > 1 %}
|
||||
<section id="content" class="body">
|
||||
<h2>Others articles</h2>
|
||||
<hr />
|
||||
<ol id="posts-list" class="hfeed">
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<li><article class="hentry">
|
||||
<header>
|
||||
<h2 class="entry-title"><a href="{{ BLOGURL }}/{{ article.url }}" rel="bookmark" title="Permalink to {{ article.title}}">{{ article.title }}</a></h2>
|
||||
<h2><a href="{{ BLOGURL }}/{{ article.url }}" rel="bookmark" title="Permalink to {{ article.title}}">{{ article.title }}</a></h2>
|
||||
</header>
|
||||
|
||||
<div class="entry-content">
|
||||
<footer class="post-info">
|
||||
<abbr class="published" title="{{ article.date.isoformat() }}">
|
||||
{{ article.date.strftime('%Y-%m-%d %H:%M') }}
|
||||
{{ article.date.strftime('%a %d %B %Y') }}
|
||||
</abbr>
|
||||
|
||||
<address class="vcard author">
|
||||
By <a class="url fn" href="#">{{ article.author }}</a>
|
||||
</address>
|
||||
</address>In <a href="{{ BLOGURL }}/category/{{ article.category }}.html">{{ article.category }}</a>
|
||||
</footer><!-- /.post-info -->
|
||||
{{ article.summary }}
|
||||
<a class="readmore" href="{{ BLOGURL }}/{{ article.url }}">read more</a>
|
||||
</div><!-- /.entry-content -->
|
||||
</article></li>
|
||||
{% endif %}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue