diff --git a/ChangeLog b/ChangeLog
index 750a91d..f40cdc7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,14 +1,21 @@
-v0.4 (08/11/2015)
+v0.4 (09/01/2016)
** User **
Redirect user to comment when it's added and not to begining of page
Enable code coloration support with Markdown syntax
Add article inclusion
Add autofocus to login page
+ Sort tags by name
+ Add generation duration time
+
+** Dev **
+ Support Django 1.8
+ Enhance cache post content (avoid recomputing md5sum if present)
+ Add post only generation (for Dev)
** Bugs **
Always update modification date when post/draft is saved
- Support Django 1.8
+ Draft were not remove from _draft directory when moving to Post
v0.3 (13/11/2014)
diff --git a/README b/README
index f68d2ef..2316919 100644
--- a/README
+++ b/README
@@ -1,6 +1,6 @@
Dynastie is static blog generator delivered under GPL v3 licence terms.
-Current version is 0.5
+Current version is 0.4
Requirements :
Django >= 1.8, libapache2-mod-wsgi if you want to use Dynastie with Apache. PyGments (Optional).
@@ -10,7 +10,7 @@ Installation :
* Update dynastie/wsgy.py (with $PWD/../) don't forget the final slash !
* Update dynastie/settings.py (SECRET_KEY...)
* Run ./manage.sh syncdb and create a superuser
-* Run ./manage.sh runserver
+* Run ./manage.sh runserver 0.0.0.0:8080
or
* Copy (and edit) apache_dynastie.conf in /etc/apache2/sites-available, and create a symbolic link from /etc/apache2/sites-enabled to /etc/apache2/sites-available
diff --git a/dynastie/generators/generator.py b/dynastie/generators/generator.py
index 03b2dff..2bb18b5 100755
--- a/dynastie/generators/generator.py
+++ b/dynastie/generators/generator.py
@@ -57,11 +57,13 @@ class DynastieGenerator:
URI = "http://indefero.soutade.fr/p/dynastie"
- def __init__(self, hash_posts={}, hash_posts_content={}):
+ def __init__(self, request, hash_posts={}, hash_posts_content={}):
self.report = ''
self.somethingWrote = False
+ self.request = request
self.hash_posts = hash_posts
self.hash_posts_content = hash_posts_content
+ self.user = request and request.user or None
def addReport(self, string, color=''):
if string in self.report: return
diff --git a/dynastie/generators/index.py b/dynastie/generators/index.py
index 5dde0ae..5f342fa 100755
--- a/dynastie/generators/index.py
+++ b/dynastie/generators/index.py
@@ -31,8 +31,8 @@ from dynastie.generators import markdown2
class Index(DynastieGenerator):
- def __init__(self, hash_posts={}, hash_posts_content={}):
- DynastieGenerator.__init__(self, hash_posts, hash_posts_content)
+ def __init__(self, request=None, hash_posts={}, hash_posts_content={}):
+ DynastieGenerator.__init__(self, request, hash_posts, hash_posts_content)
self.hooks = {'posts' : self.createPosts,
'title' : self.createTitle,
@@ -53,6 +53,7 @@ class Index(DynastieGenerator):
self.filename = 'index'
self.dirname = ''
self.blog = None
+ self.parent_posts = []
self.resetCounters()
@@ -143,7 +144,8 @@ class Index(DynastieGenerator):
nav = nav + href + str(self.cur_page+1) + '.html">Next > '
nav = nav + href + str(self.nb_pages-1) + '.html">Last >>'
- new_dom = parseString('
' + nav + '
')
+ s = '' + nav + '
'
+ new_dom = parseString(s.encode('utf-8'))
new_node = new_dom.getElementsByTagName('div')[0]
res = new_node.cloneNode(True)
root.replaceChild(res, node)
@@ -230,23 +232,45 @@ class Index(DynastieGenerator):
return (b, p)
- def _manageInternalPosts(self, post, text, parent_posts, user=None):
+ def _manageInternalPosts(self, post, text, user=None):
from dynastie.models import Post
if not user: user = post.author
- if post and post.content_format != Post.CONTENT_TEXT: return text
- internal_posts = re.search('\[\[([0-9]+)\]\]', text)
- if not internal_posts: return text
- for post_id in internal_posts.groups():
- post_id = int(post_id)
- if post_id in parent_posts: continue
- _,post = self._have_I_right(user, post_id)
- if not post: continue
- new_content = self._loadPostContent(post, parent_posts)
- if new_content:
- text = text.replace('[[' + str(post_id) + ']]', new_content)
+ # Markdown replace
+ if not post or (post and post.content_format == Post.CONTENT_TEXT):
+ internal_posts = re.search('\[\[([0-9]+)\]\]', text)
+ if internal_posts:
+ for post_id in internal_posts.groups():
+ post_id = int(post_id)
+ if post_id in self.parent_posts: continue
+ _,post = self._have_I_right(user, post_id)
+ if not post: continue
+ new_content = self._loadPostContent(post)
+ if new_content:
+ text = text.replace('[[' + str(post_id) + ']]', new_content)
+ if internal_posts: return text
+ # HTML replace
+ if not post or (post and post.content_format == Post.CONTENT_HTML):
+ while True:
+ start = text.find('')
+
+ if end < start:
+ self.addError('Invalid tags in ' + self.filename)
+ break
+
+ internal_posts = re.search('post_id="([0-9]+)"', text[start:])
+ if not internal_posts: break
+ for post_id in internal_posts.groups():
+ _,post = self._have_I_right(user, post_id)
+ if not post: break
+ new_content = self._loadPostContent(post)
+ if new_content:
+ text = text.replace(text[start:end+18], new_content.encode('utf-8'))
return text
- def _loadPostContent(self, post, parent_posts):
+ def _loadPostContent(self, post):
from dynastie.models import Post
blog = post.blog
@@ -255,29 +279,33 @@ class Index(DynastieGenerator):
filename = blog.src_path + '/_post/' + str(post.id)
if not os.path.exists(filename):
- self.addError('File does not exists ' + filename)
- return None
+ filename2 = blog.src_path + '/_draft/' + str(post.id)
+ if not os.path.exists(filename2):
+ self.addError('File does not exists ' + filename)
+ return None
+ else:
+ filename = filename2
if not filename in self.hash_posts_content:
f = open(filename, 'rb')
post_content = f.read()
f.close()
+ self.parent_posts.append(post.id)
+ post_content = self._manageInternalPosts(post, post_content)
if post.content_format == Post.CONTENT_TEXT:
- parent_posts.append(post.id)
- post_content = self._manageInternalPosts(post, post_content, parent_posts)
post_content = markdown2.markdown(post_content, extras=['fenced-code-blocks'])
self.hash_posts_content[filename] = post_content
else:
post_content = self.hash_posts_content[filename]
return post_content
-
+
def createPost(self, posts, dom, post_elem, root):
from dynastie.models import Post
post = self.cur_post_obj
if post.id in self.hash_posts and not self.first_try:
- node = self.hash_posts[post.id]
+ node,_ = self.hash_posts[post.id]
return node.cloneNode(0)
values = {'post_content': '', 'author': 'Unknown'}
@@ -286,7 +314,8 @@ class Index(DynastieGenerator):
except:
pass
- post_content = _loadPostContent(post, [])
+ self.parent_posts = []
+ post_content = self._loadPostContent(post)
if not post_content: return None
post_content = self.pygmentCode(post_content)
@@ -302,32 +331,26 @@ class Index(DynastieGenerator):
new_node = dom.createTextNode(post_content)
content_node.appendChild(new_node)
+ writer = StrictUTF8Writer()
+ post_elem.writexml(writer)
+ content = writer.getvalue().encode('utf-8')
+
+ md5 = hashlib.md5()
+ md5.update(content)
+
if post.id in self.hash_posts:
# Here, we are in first_try, check that computed
# post has the same result than the one in cache
self.first_try = False
- writer = StrictUTF8Writer()
- node = self.hash_posts[post.id]
- node.writexml(writer)
- content1 = writer.getvalue().encode('utf-8')
-
- writer = StrictUTF8Writer()
- post_elem.writexml(writer)
- content2 = writer.getvalue().encode('utf-8')
+ _,md5_2 = self.hash_posts[post.id]
- md5_1 = hashlib.md5()
- md5_1.update(content1)
-
- md5_2 = hashlib.md5()
- md5_2.update(content2)
-
# If not, clear cache
- if md5_1.digest() != md5_2.digest():
+ if md5.digest() != md5_2:
self.hash_posts = {}
- self.hash_posts[post.id] = post_elem.cloneNode(0)
+ self.hash_posts[post.id] = (post_elem.cloneNode(0), md5.digest())
else:
- self.hash_posts[post.id] = post_elem.cloneNode(0)
+ self.hash_posts[post.id] = (post_elem.cloneNode(0), md5.digest())
return post_elem
@@ -544,6 +567,7 @@ class Index(DynastieGenerator):
from dynastie.models import Post, Blog
self.blog = blog
+ self.parent_posts = []
dom = self.parseTemplate(blog, src, output, 'index')
if dom is None: return self.report
diff --git a/dynastie/generators/post.py b/dynastie/generators/post.py
index 5c48f80..5627b93 100755
--- a/dynastie/generators/post.py
+++ b/dynastie/generators/post.py
@@ -217,6 +217,7 @@ class Post(Index):
self.blog = blog
+ self.parent_posts = []
posts = Post.objects.all()
return self._generate(blog, src, output, posts)
@@ -230,26 +231,30 @@ class Post(Index):
v['date'] = now.strftime("%A, %d %B %Y %H:%m")
v['post_content'] = ''
- post_content = self._manageInternalPosts(None, values['content'], [], self.user)
+ post_content = self._manageInternalPosts(None, values['content'], self.user)
post_content = self.pygmentCode(post_content)
self.simpleTransform(v, dom, root, node)
content_nodes = root.getElementsByTagName("div")
post_transform = ('post_content')
+ content_node = None
for content_node in content_nodes:
the_class = content_node.getAttribute('class')
if not the_class in post_transform:
continue
if the_class == 'post_content':
- new_node = dom.createTextNode(post_content)
- content_node.appendChild(new_node)
+ s = u'' + post_content + u'
'
+ new_node = parseString(s.encode('utf-8'))
+ for n in new_node.childNodes[0].childNodes:
+ content_node.appendChild(n)
+ break
post_nodes = dom.getElementsByTagNameNS(self.URI, "post")
post_elem = post_nodes[0]
post_elem.parentNode.removeChild(post_elem)
- return post_elem
+ return content_node
def preview(self, request, src, values):
from dynastie.models import Blog
@@ -258,7 +263,8 @@ class Post(Index):
# Override all hooks
self.hooks = {'post' : self.createPreview,
- 'tags' : self.createTags}
+ 'tags' : self.createTags,
+ }
if not os.path.exists(src + '/_post.html'):
self.addError('No _post.html found, exiting')
diff --git a/dynastie/models.py b/dynastie/models.py
index ffab2a6..7d76ed2 100755
--- a/dynastie/models.py
+++ b/dynastie/models.py
@@ -171,8 +171,9 @@ class Blog(models.Model):
if errors:
raise Exception(errors)
- def generate(self):
- self.report = '
Generation of ' + datetime.now().strftime("%d/%m/%Y at %H:%M:%S") + '
\n'
+ def generate(self, request):
+ start_time = datetime.now()
+ self.report = ''
self.load_generators()
self.copytree(self.src_path, self.output_path)
generated = []
@@ -190,7 +191,33 @@ class Blog(models.Model):
if not r is None:
self.report = self.report + '
\n' + r
- return self.report
+ duration = datetime.now() - start_time
+ t = '
Generation of ' + start_time.strftime("%d/%m/%Y at %H:%M:%S") + '
\n'
+ t = t + 'Duration ' + str(duration) + '
\n'
+ return t + self.report
+
+ def generate_post(self, request, post):
+ from dynastie.generators import post as PostGenerator
+ start_time = datetime.now()
+ self.report = ''
+ self.load_generators()
+ self.copytree(self.src_path, self.output_path)
+ post_list = [post]
+ hash_posts = {}
+ hash_posts_content = {}
+ engine = globals()['post']
+ for name, obj in inspect.getmembers(engine):
+ if inspect.isclass(obj) and obj.__module__.startswith("dynastie.generators") \
+ and obj.__module__.endswith("post"):
+ e = obj(request, hash_posts, hash_posts_content)
+ self.report = e._generate(self, self.src_path, self.output_path, post_list)
+ break
+ # report = PostGenerator()._generate(self, self.src_path, self.output_path, post_list)
+
+ duration = datetime.now() - start_time
+ t = '
Generation of ' + start_time.strftime("%d/%m/%Y at %H:%M:%S") + ' post ' + str(post.id) + '
\n'
+ t = t + 'Duration ' + str(duration) + '
\n'
+ return t + self.report
class Editor(models.Model):
name = models.CharField(max_length=255, unique=True)
@@ -443,6 +470,10 @@ def delete_tag_signal(sender, **kwargs):
def delete_post_signal(sender, **kwargs):
kwargs['instance'].remove()
+@receiver(post_delete, sender=Draft)
+def delete_draft_signal(sender, **kwargs):
+ kwargs['instance'].remove()
+
@receiver(pre_delete, sender=Post)
def pre_delete_post_signal(sender, **kwargs):
post = kwargs['instance']
diff --git a/dynastie/sites/blog.soutade.fr/_base.html b/dynastie/sites/blog.soutade.fr/_base.html
index 9da6c73..89a077b 100755
--- a/dynastie/sites/blog.soutade.fr/_base.html
+++ b/dynastie/sites/blog.soutade.fr/_base.html
@@ -77,6 +77,7 @@
diff --git a/dynastie/sites/blog.soutade.fr/_base_post.html b/dynastie/sites/blog.soutade.fr/_base_post.html
index 3110b9c..f01e26e 100644
--- a/dynastie/sites/blog.soutade.fr/_base_post.html
+++ b/dynastie/sites/blog.soutade.fr/_base_post.html
@@ -78,6 +78,7 @@
diff --git a/dynastie/sites/blog.soutade.fr/css/blog.css b/dynastie/sites/blog.soutade.fr/css/blog.css
index 0d2dbd9..7889e30 100755
--- a/dynastie/sites/blog.soutade.fr/css/blog.css
+++ b/dynastie/sites/blog.soutade.fr/css/blog.css
@@ -341,13 +341,13 @@ a img
.inlineimage
{
display:inline;
- margin-right: 50px;
+ margin-right: 20px;
}
a .inlineimage
{
display:inline;
- margin-right: 50px;
+ margin-right: 20px;
}
h1, h2, h3, h4, h5, h6, h1 a, h2 a, h3 a, h4 a, h5 a, h6 a h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited
@@ -463,68 +463,68 @@ ul li
}
/* Pygments */
-.highlight { background-color: #e8e8e8; }
-.color_emacs_hll { background-color: #ffffcc }
-.color_emacs_c { color: #008800; font-style: italic } /* Comment */
-.color_emacs_err { border: 1px solid #FF0000 } /* Error */
-.color_emacs_k { color: #AA22FF; font-weight: bold } /* Keyword */
-.color_emacs_o { color: #666666 } /* Operator */
-.color_emacs_cm { color: #008800; font-style: italic } /* Comment.Multiline */
-.color_emacs_cp { color: #008800 } /* Comment.Preproc */
-.color_emacs_c1 { color: #008800; font-style: italic } /* Comment.Single */
-.color_emacs_cs { color: #008800; font-weight: bold } /* Comment.Special */
-.color_emacs_gd { color: #A00000 } /* Generic.Deleted */
-.color_emacs_ge { font-style: italic } /* Generic.Emph */
-.color_emacs_gr { color: #FF0000 } /* Generic.Error */
-.color_emacs_gh { color: #000080; font-weight: bold } /* Generic.Heading */
-.color_emacs_gi { color: #00A000 } /* Generic.Inserted */
-.color_emacs_go { color: #808080 } /* Generic.Output */
-.color_emacs_gp { color: #000080; font-weight: bold } /* Generic.Prompt */
-.color_emacs_gs { font-weight: bold } /* Generic.Strong */
-.color_emacs_gu { color: #800080; font-weight: bold } /* Generic.Subheading */
-.color_emacs_gt { color: #0040D0 } /* Generic.Traceback */
-.color_emacs_kc { color: #AA22FF; font-weight: bold } /* Keyword.Constant */
-.color_emacs_kd { color: #AA22FF; font-weight: bold } /* Keyword.Declaration */
-.color_emacs_kn { color: #AA22FF; font-weight: bold } /* Keyword.Namespace */
-.color_emacs_kp { color: #AA22FF } /* Keyword.Pseudo */
-.color_emacs_kr { color: #AA22FF; font-weight: bold } /* Keyword.Reserved */
-.color_emacs_kt { color: #00BB00; font-weight: bold } /* Keyword.Type */
-.color_emacs_m { color: #666666 } /* Literal.Number */
-.color_emacs_s { color: #BB4444 } /* Literal.String */
-.color_emacs_na { color: #BB4444 } /* Name.Attribute */
-.color_emacs_nb { color: #AA22FF } /* Name.Builtin */
-.color_emacs_nc { color: #0000FF } /* Name.Class */
-.color_emacs_no { color: #880000 } /* Name.Constant */
-.color_emacs_nd { color: #AA22FF } /* Name.Decorator */
-.color_emacs_ni { color: #999999; font-weight: bold } /* Name.Entity */
-.color_emacs_ne { color: #D2413A; font-weight: bold } /* Name.Exception */
-.color_emacs_nf { color: #00A000 } /* Name.Function */
-.color_emacs_nl { color: #A0A000 } /* Name.Label */
-.color_emacs_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
-.color_emacs_nt { color: #008000; font-weight: bold } /* Name.Tag */
-.color_emacs_nv { color: #B8860B } /* Name.Variable */
-.color_emacs_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
-.color_emacs_w { color: #bbbbbb } /* Text.Whitespace */
-.color_emacs_mf { color: #666666 } /* Literal.Number.Float */
-.color_emacs_mh { color: #666666 } /* Literal.Number.Hex */
-.color_emacs_mi { color: #666666 } /* Literal.Number.Integer */
-.color_emacs_mo { color: #666666 } /* Literal.Number.Oct */
-.color_emacs_sb { color: #BB4444 } /* Literal.String.Backtick */
-.color_emacs_sc { color: #BB4444 } /* Literal.String.Char */
-.color_emacs_sd { color: #BB4444; font-style: italic } /* Literal.String.Doc */
-.color_emacs_s2 { color: #BB4444 } /* Literal.String.Double */
-.color_emacs_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
-.color_emacs_sh { color: #BB4444 } /* Literal.String.Heredoc */
-.color_emacs_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
-.color_emacs_sx { color: #008000 } /* Literal.String.Other */
-.color_emacs_sr { color: #BB6688 } /* Literal.String.Regex */
-.color_emacs_s1 { color: #BB4444 } /* Literal.String.Single */
-.color_emacs_ss { color: #B8860B } /* Literal.String.Symbol */
-.color_emacs_bp { color: #AA22FF } /* Name.Builtin.Pseudo */
-.color_emacs_vc { color: #B8860B } /* Name.Variable.Class */
-.color_emacs_vg { color: #B8860B } /* Name.Variable.Global */
-.color_emacs_vi { color: #B8860B } /* Name.Variable.Instance */
-.color_emacs_il { color: #666666 } /* Literal.Number.Integer.Long */
+.codehilite, .highlight { background-color: #e8e8e8; }
+.hl, .color_emacs_hll { background-color: #ffffcc }
+.c, .color_emacs_c { color: #008800; font-style: italic } /* Comment */
+.er, .color_emacs_err { border: 1px solid #FF0000 } /* Error */
+.k, .color_emacs_k { color: #AA22FF; font-weight: bold } /* Keyword */
+.o, .color_emacs_o { color: #666666 } /* Operator */
+.cm, .color_emacs_cm { color: #008800; font-style: italic } /* Comment.Multiline */
+.cp, .color_emacs_cp { color: #008800 } /* Comment.Preproc */
+.c1, .color_emacs_c1 { color: #008800; font-style: italic } /* Comment.Single */
+.cs, .color_emacs_cs { color: #008800; font-weight: bold } /* Comment.Special */
+.gd, .color_emacs_gd { color: #A00000 } /* Generic.Deleted */
+.ge, .color_emacs_ge { font-style: italic } /* Generic.Emph */
+.gr, .color_emacs_gr { color: #FF0000 } /* Generic.Error */
+.gh, .color_emacs_gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.gi, .color_emacs_gi { color: #00A000 } /* Generic.Inserted */
+.go, .color_emacs_go { color: #808080 } /* Generic.Output */
+.gp, .color_emacs_gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.gs, .color_emacs_gs { font-weight: bold } /* Generic.Strong */
+.gu, .color_emacs_gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.gt, .color_emacs_gt { color: #0040D0 } /* Generic.Traceback */
+.kc, .color_emacs_kc { color: #AA22FF; font-weight: bold } /* Keyword.Constant */
+.kd, .color_emacs_kd { color: #AA22FF; font-weight: bold } /* Keyword.Declaration */
+.kn, .color_emacs_kn { color: #AA22FF; font-weight: bold } /* Keyword.Namespace */
+.kp, .color_emacs_kp { color: #AA22FF } /* Keyword.Pseudo */
+.kr, .color_emacs_kr { color: #AA22FF; font-weight: bold } /* Keyword.Reserved */
+.kt, .color_emacs_kt { color: #00BB00; font-weight: bold } /* Keyword.Type */
+.m, .color_emacs_m { color: #666666 } /* Literal.Number */
+.s, .color_emacs_s { color: #BB4444 } /* Literal.String */
+.na, .color_emacs_na { color: #BB4444 } /* Name.Attribute */
+.nb, .color_emacs_nb { color: #AA22FF } /* Name.Builtin */
+.nc, .color_emacs_nc { color: #0000FF } /* Name.Class */
+.no, .color_emacs_no { color: #880000 } /* Name.Constant */
+.nd, .color_emacs_nd { color: #AA22FF } /* Name.Decorator */
+.ni, .color_emacs_ni { color: #999999; font-weight: bold } /* Name.Entity */
+.ne, .color_emacs_ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.nf, .color_emacs_nf { color: #00A000 } /* Name.Function */
+.nl, .color_emacs_nl { color: #A0A000 } /* Name.Label */
+.nn, .color_emacs_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.nt, .color_emacs_nt { color: #008000; font-weight: bold } /* Name.Tag */
+.nv, .color_emacs_nv { color: #B8860B } /* Name.Variable */
+.ow, .color_emacs_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.w, .color_emacs_w { color: #bbbbbb } /* Text.Whitespace */
+.mf, .color_emacs_mf { color: #666666 } /* Literal.Number.Float */
+.mh, .color_emacs_mh { color: #666666 } /* Literal.Number.Hex */
+.mi, .color_emacs_mi { color: #666666 } /* Literal.Number.Integer */
+.mo, .color_emacs_mo { color: #666666 } /* Literal.Number.Oct */
+.sb, .color_emacs_sb { color: #BB4444 } /* Literal.String.Backtick */
+.sc, .color_emacs_sc { color: #BB4444 } /* Literal.String.Char */
+.sd, .color_emacs_sd { color: #BB4444; font-style: italic } /* Literal.String.Doc */
+.s2, .color_emacs_s2 { color: #BB4444 } /* Literal.String.Double */
+.se, .color_emacs_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.sh, .color_emacs_sh { color: #BB4444 } /* Literal.String.Heredoc */
+.si, .color_emacs_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.sx, .color_emacs_sx { color: #008000 } /* Literal.String.Other */
+.sr, .color_emacs_sr { color: #BB6688 } /* Literal.String.Regex */
+.s1, .color_emacs_s1 { color: #BB4444 } /* Literal.String.Single */
+.ss, .color_emacs_ss { color: #B8860B } /* Literal.String.Symbol */
+.bp, .color_emacs_bp { color: #AA22FF } /* Name.Builtin.Pseudo */
+.vc, .color_emacs_vc { color: #B8860B } /* Name.Variable.Class */
+.vg, .color_emacs_vg { color: #B8860B } /* Name.Variable.Global */
+.vi, .color_emacs_vi { color: #B8860B } /* Name.Variable.Instance */
+.il, .color_emacs_il { color: #666666 } /* Literal.Number.Integer.Long */
#search_form
{
diff --git a/dynastie/static/js/dynastie.js b/dynastie/static/js/dynastie.js
index e1d6017..aeeeaa4 100755
--- a/dynastie/static/js/dynastie.js
+++ b/dynastie/static/js/dynastie.js
@@ -3,7 +3,7 @@ tinyMCE.init({
// General options
mode : "textareas",
theme : "advanced",
- plugins : "autolink,lists,spellchecker,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,dynastiecolor",
+ plugins : "autolink,lists,spellchecker,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,dynastiecolor,dynastieinclude",
editor_selector : "mceAdvanced",
encoding : "raw",
entities : "",
@@ -14,7 +14,7 @@ tinyMCE.init({
// Theme options
theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,formatselect,fontselect,fontsizeselect",
theme_advanced_buttons2 : "bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor",
- theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,charmap,emotions,iespell,media,advhr,dynastiecolor",
+ theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,charmap,emotions,iespell,media,advhr,dynastiecolor,dynastieinclude",
// theme_advanced_buttons4 : "insertlayer,moveforward,movebackward,absolute,|,styleprops,spellchecker,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,blockquote,pagebreak,|,insertfile,insertimage",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
@@ -85,4 +85,4 @@ function switchEditor()
help.style.display="block";
// tinymce.execCommand('mceToggleEditor',false,'content');
}
-}
\ No newline at end of file
+}
diff --git a/dynastie/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/editor_plugin.js b/dynastie/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/editor_plugin.js
deleted file mode 100755
index 40ac9fb..0000000
--- a/dynastie/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/editor_plugin.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * editor_plugin_src.js
- *
- * Copyright 2012, Grégory Soutadé
- * Released under LGPL License.
- *
- */
-
-(function() {
- tinymce.create('tinymce.plugins.DynastieColor', {
- init : function(ed, url) {
- var t = this, css = tinymce.explode(ed.settings.content_css);
-
- t.editor = ed;
-
- // Force absolute CSS urls
- tinymce.each(css, function(u, k) {
- css[k] = ed.documentBaseURI.toAbsolute(u);
- });
-
- ed.addCommand('mceDynastieColor', function() {
- ed.windowManager.open({
- file : ed.getParam("plugin_dynastiecolor_pageurl", url + "/dynastiecolor.html"),
- width : parseInt(ed.getParam("plugin_dynastiecolor_width", "700")),
- height : parseInt(ed.getParam("plugin_dynastiecolor_height", "800")),
- resizable : "yes",
- scrollbars : "yes",
- popup_css : css ? css.join(',') : ed.baseURI.toAbsolute("themes/" + ed.settings.theme + "/skins/" + ed.settings.skin + "/content.css"),
- }, {
- base : ed.documentBaseURI.getURI()
- });
- });
-
- ed.addButton('dynastiecolor', {title : 'Insert code', cmd : 'mceDynastieColor', image : url + "/img/dynastiecolor.png"});
- },
-
- getInfo : function() {
- return {
- longname : 'DynastieColor',
- author : 'Grégory Soutadé',
- authorurl : 'http://soutade.fr',
- infourl : 'http://indefero.soutade.fr/p/dynastie',
- version : tinymce.majorVersion + "." + tinymce.minorVersion
- };
- }
- });
-
- // Register plugin
- tinymce.PluginManager.add('dynastiecolor', tinymce.plugins.DynastieColor);
-})();
\ No newline at end of file
diff --git a/dynastie/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/editor_plugin.js b/dynastie/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/editor_plugin.js
new file mode 120000
index 0000000..3a96ace
--- /dev/null
+++ b/dynastie/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/editor_plugin.js
@@ -0,0 +1 @@
+editor_plugin_src.js
\ No newline at end of file
diff --git a/dynastie/templates/view_blog.html b/dynastie/templates/view_blog.html
index 84f1e2b..c20939a 100755
--- a/dynastie/templates/view_blog.html
+++ b/dynastie/templates/view_blog.html
@@ -23,7 +23,7 @@
Drafts
{% for draft in drafts %}
- {{ draft.id }} | {{ draft.title }} | {{ draft.creation_date }} | {{ draft.modification_date }} | Delete |
+ {{ draft.id }} | {{ draft.title }} | {{ draft.category.name }} | {{ draft.creation_date }} | {{ draft.modification_date }} | Delete |
{% endfor %}
{% endif %}
diff --git a/dynastie/urls.py b/dynastie/urls.py
index d70ec25..1e2203f 100755
--- a/dynastie/urls.py
+++ b/dynastie/urls.py
@@ -47,6 +47,7 @@ urlpatterns = patterns('',
url(r'^draft/edit/(\d+)$', 'dynastie.views.edit_draft', name='edit_draft'),
url(r'^draft/delete/(\d+)$', 'dynastie.views.delete_draft', name='delete_draft'),
url(r'^generate/(\d+)$', 'dynastie.views.generate', name='generate'),
+ url(r'^generate/(\d+)/(\d+)$','dynastie.views.generate_post',name='generate_post'),
url(r'^preview/(\d+)$', 'dynastie.views.preview', name='preview'),
url(r'^tinyMCEExternalList/post/add/(\d+)$', 'dynastie.views.tinymcelist_add', name='tinymce'),
url(r'^tinyMCEExternalList/post/edit/(\d+)$', 'dynastie.views.tinymcelist_edit', name='tinymce'),
diff --git a/dynastie/views.py b/dynastie/views.py
index 3215659..c83d8c5 100755
--- a/dynastie/views.py
+++ b/dynastie/views.py
@@ -498,7 +498,7 @@ def add_post(request, blog_id):
return render(request, 'add_post.html', {
'form': form, 'blog_id' : blog_id,
- 'all_tags' : Tag.objects.all(),
+ 'all_tags' : Tag.objects.all().order_by('name'),
'editor' : 'html'
})
@@ -528,7 +528,7 @@ def edit_post(request, post_id):
if 'cancel' in request.POST:
return HttpResponseRedirect('/blog/' + str(blog_id))
else:
- form = PostForm(instance=post, initial={'text_tags':', '.join((tag.name) for tag in post.tags.all())})
+ form = PostForm(instance=post, initial={'text_tags':', '.join((tag.name) for tag in post.tags.all().order_by('name'))})
filename = b.src_path + '/_post/' + str(post.pk)
if os.path.exists(filename):
@@ -544,7 +544,7 @@ def edit_post(request, post_id):
return render(request, 'edit_post.html', {
'form': form, 'post_id' : post_id, 'content' : content,
'blog_id' : blog_id, 'comments' : comment_list,
- 'all_tags' : Tag.objects.all(),
+ 'all_tags' : Tag.objects.all().order_by('name'),
'editor' : post.get_editor()
})
@@ -588,7 +588,7 @@ def edit_draft(request, draft_id):
if 'cancel' in request.POST:
return HttpResponseRedirect('/blog/' + str(blog_id))
else:
- form = PostForm(instance=draft, initial={'text_tags':', '.join((tag.name) for tag in draft.tags.all())})
+ form = PostForm(instance=draft, initial={'text_tags':', '.join((tag.name) for tag in draft.tags.all().order_by('name'))})
filename = b.src_path + '/_draft/' + str(draft.pk)
if os.path.exists(filename):
@@ -601,7 +601,7 @@ def edit_draft(request, draft_id):
return render(request, 'edit_draft.html', {
'form': form, 'draft_id' : draft_id, 'content' : content,
'blog_id' : blog_id,
- 'all_tags' : Tag.objects.all(),
+ 'all_tags' : Tag.objects.all().order_by('name'),
'editor' : draft.get_editor()
})
@@ -649,7 +649,15 @@ def _generate(request, blog_id, report):
def generate(request, blog_id):
b,_ = have_I_right(request, blog_id)
- report = b.generate()
+ report = b.generate(request)
+
+ return _generate(request, blog_id, report)
+
+@login_required
+def generate_post(request, blog_id, post_id):
+ b,post = have_I_right(request, blog_id, post_id)
+
+ report = b.generate_post(request, post)
return _generate(request, blog_id, report)
@@ -708,7 +716,7 @@ def preview(request, blog_id):
content = request.POST['content']
if request.POST['editor'] == 'text':
from dynastie.generators import markdown2
- content = markdown2.markdown(content)
+ content = markdown2.markdown(content, extras=['fenced-code-blocks'])
values = {'title' : request.POST['title'], \
'author' : request.user.first_name + ' ' + request.user.last_name, \
@@ -721,7 +729,7 @@ def preview(request, blog_id):
if inspect.isclass(obj) and obj.__module__.startswith("dynastie.generators") \
and obj.__module__.endswith("post"):
e = obj()
- content = e.preview(b.src_path, values)
+ content = e.preview(request, b.src_path, values)
break
output = b.output_path