aboutsummaryrefslogtreecommitdiff
path: root/weblog
diff options
context:
space:
mode:
Diffstat (limited to 'weblog')
-rw-r--r--weblog/__init__.py79
-rw-r--r--weblog/admin.py46
-rw-r--r--weblog/apps.py18
-rw-r--r--weblog/locale/es/LC_MESSAGES/django.mobin0 -> 3062 bytes
-rw-r--r--weblog/locale/es/LC_MESSAGES/django.po274
-rw-r--r--weblog/locale/ru/LC_MESSAGES/django.mobin0 -> 3905 bytes
-rw-r--r--weblog/locale/ru/LC_MESSAGES/django.po274
-rw-r--r--weblog/migrations/0001_initial.py65
-rw-r--r--weblog/migrations/0002_auto_20180113_1606.py57
-rw-r--r--weblog/migrations/0003_auto_20180119_0156.py28
-rw-r--r--weblog/migrations/0004_auto_20180119_0156.py21
-rw-r--r--weblog/migrations/0005_auto_20180119_0231.py20
-rw-r--r--weblog/migrations/0006_auto_20180121_1002.py27
-rw-r--r--weblog/migrations/0007_auto_20180122_1943.py22
-rw-r--r--weblog/migrations/__init__.py0
-rw-r--r--weblog/models.py93
-rw-r--r--weblog/static/weblog/css/weblog.css7
-rw-r--r--weblog/static/weblog/js/weblog.js13
-rw-r--r--weblog/templates/weblog/index.html78
-rw-r--r--weblog/templates/weblog/post.html67
-rw-r--r--weblog/templates/weblog/sidebar_archive.html13
-rw-r--r--weblog/templates/weblog/sidebar_categories.html11
-rw-r--r--weblog/templates/weblog/weblog.html42
-rw-r--r--weblog/templates/weblog_base.html28
-rw-r--r--weblog/templates/weblog_base_old.html35
-rw-r--r--weblog/templatetags/__init__.py0
-rw-r--r--weblog/templatetags/__pycache__/__init__.cpython-35.pycbin0 -> 166 bytes
-rw-r--r--weblog/templatetags/__pycache__/__init__.cpython-36.pycbin0 -> 166 bytes
-rw-r--r--weblog/templatetags/__pycache__/weblog_extras.cpython-35.pycbin0 -> 2682 bytes
-rw-r--r--weblog/templatetags/__pycache__/weblog_extras.cpython-36.pycbin0 -> 1448 bytes
-rw-r--r--weblog/templatetags/weblog_extras.py70
-rw-r--r--weblog/tests.py3
-rw-r--r--weblog/urls.py12
-rw-r--r--weblog/views.py207
34 files changed, 1610 insertions, 0 deletions
diff --git a/weblog/__init__.py b/weblog/__init__.py
new file mode 100644
index 0000000..a97f18a
--- /dev/null
+++ b/weblog/__init__.py
@@ -0,0 +1,79 @@
+from . import apps
+from django.conf import settings
+
+try:
+ apps.SETTINGS['enable_comments'] = settings.WEBLOG_ENABLE_COMMENTS
+except AttributeError:
+ pass
+except NameError:
+ pass
+
+try:
+ apps.SETTINGS['allow_anon_comments'] = settings.WEBLOG_ALLOW_ANON_COMMENTS
+except AttributeError:
+ pass
+except NameError:
+ pass
+
+try:
+ apps.SETTINGS['multilingual'] = settings.WEBLOG_MULTILINGUAL
+except AttributeError:
+ pass
+except NameError:
+ pass
+
+try:
+ apps.SETTINGS['blog_title'] = settings.WEBLOG_TITLE
+except AttributeError:
+ pass
+except NameError:
+ pass
+
+try:
+ apps.SETTINGS['base_template'] = settings.WEBLOG_BASE_TEMPLATE
+except AttributeError:
+ pass
+except NameError:
+ pass
+
+try:
+ apps.SETTINGS['show_author'] = settings.WEBLOG_SHOW_AUTHOR
+except AttributeError:
+ pass
+except NameError:
+ pass
+
+try:
+ apps.SETTINGS['use_authors_username'] = settings.WEBLOG_USE_AUTHORS_USERNAME
+except AttributeError:
+ pass
+except NameError:
+ pass
+
+try:
+ apps.SETTINGS['show_sidebar'] = settings.WEBLOG_SHOW_SIDEBAR
+except AttributeError:
+ pass
+except NameError:
+ pass
+
+try:
+ apps.SETTINGS['show_categories'] = settings.WEBLOG_SHOW_CATEGORIES
+except AttributeError:
+ pass
+except NameError:
+ pass
+
+try:
+ apps.SETTINGS['show_archive'] = settings.WEBLOG_SHOW_ARCHIVE
+except AttributeError:
+ pass
+except NameError:
+ pass
+
+try:
+ apps.SETTINGS['posts_per_page'] = settings.WEBLOG_POSTS_PER_PAGE
+except AttributeError:
+ pass
+except NameError:
+ pass \ No newline at end of file
diff --git a/weblog/admin.py b/weblog/admin.py
new file mode 100644
index 0000000..1b4e128
--- /dev/null
+++ b/weblog/admin.py
@@ -0,0 +1,46 @@
+from django.contrib import admin
+from django_summernote.admin import SummernoteModelAdmin, SummernoteInlineModelAdmin
+from .apps import SETTINGS as blog_settings
+from .models import BlogPost, Translation, PostComment, Category, CategoryTranslation
+
+
+blogPostInlines = []
+categoryInlines = []
+
+class TranslationInline(admin.StackedInline, SummernoteInlineModelAdmin):
+ model = Translation
+ extra = 1
+
+class CategoryTranslationInline(admin.StackedInline):
+ model = CategoryTranslation
+ extra = 1
+
+class PostCommentInline(admin.StackedInline):
+ model = PostComment
+ extra = 0
+
+if blog_settings['multilingual']:
+ blogPostInlines.append(TranslationInline)
+ categoryInlines.append(CategoryTranslationInline)
+
+if blog_settings['enable_comments']:
+ blogPostInlines.append(PostCommentInline)
+
+class BlogPostAdmin(SummernoteModelAdmin):
+ list_display = ['title', 'author', 'publish_date']
+ list_filter = ['publish_date', 'categories']
+ inlines = blogPostInlines
+ summer_note_fields = '__all__'
+
+ def get_form(self, request, obj=None, **kwargs):
+ if not blog_settings['multilingual']:
+ self.exclude = ('original_language', )
+ form = super(BlogPostAdmin, self).get_form(request, obj, **kwargs)
+ return form
+
+class CategoryAdmin(admin.ModelAdmin):
+ list_display = ['name']
+ inlines = categoryInlines
+
+admin.site.register(BlogPost, BlogPostAdmin)
+admin.site.register(Category, CategoryAdmin)
diff --git a/weblog/apps.py b/weblog/apps.py
new file mode 100644
index 0000000..3389f92
--- /dev/null
+++ b/weblog/apps.py
@@ -0,0 +1,18 @@
+from django.apps import AppConfig
+
+SETTINGS = {
+ 'enable_comments': False,
+ 'allow_anon_comments': True,
+ 'multilingual': True,
+ 'blog_title': 'Django-Weblog',
+ 'base_template': 'base.html',
+ 'show_author': True,
+ 'use_authors_username': True,
+ 'show_sidebar': True,
+ 'show_categories': False,
+ 'show_archive': True,
+ 'posts_per_page': 10,
+}
+
+class WeblogConfig(AppConfig):
+ name = 'weblog'
diff --git a/weblog/locale/es/LC_MESSAGES/django.mo b/weblog/locale/es/LC_MESSAGES/django.mo
new file mode 100644
index 0000000..9558ef1
--- /dev/null
+++ b/weblog/locale/es/LC_MESSAGES/django.mo
Binary files differ
diff --git a/weblog/locale/es/LC_MESSAGES/django.po b/weblog/locale/es/LC_MESSAGES/django.po
new file mode 100644
index 0000000..5afb637
--- /dev/null
+++ b/weblog/locale/es/LC_MESSAGES/django.po
@@ -0,0 +1,274 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2018-01-31 08:00+0300\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: weblog/models.py:8 weblog/models.py:23
+msgctxt "Noun, not personal name"
+msgid "Name"
+msgstr "Nombre"
+
+#: weblog/models.py:9 weblog/models.py:45
+msgid "Slug (URL)"
+msgstr ""
+
+#: weblog/models.py:10
+msgid "Parent category"
+msgstr "Categoría raíz"
+
+#: weblog/models.py:19 weblog/models.py:25
+msgctxt "Post category"
+msgid "Category"
+msgstr "Categoría"
+
+#: weblog/models.py:20 weblog/models.py:46 weblog/templates/weblog/post.html:16
+#: weblog/templates/weblog/sidebar_categories.html:3
+msgctxt "Post categories"
+msgid "Categories"
+msgstr "Categorías"
+
+#: weblog/models.py:24 weblog/models.py:67
+msgid "Language (ISO)"
+msgstr "Idioma (ISO)"
+
+#: weblog/models.py:34
+msgid "Category name translation"
+msgstr "Traducción de la categoría"
+
+#: weblog/models.py:35
+msgid "Category name translations"
+msgstr "Traducciones de categorías"
+
+#: weblog/models.py:39 weblog/models.py:78
+msgid "Author"
+msgstr "Autor"
+
+#: weblog/models.py:40 weblog/models.py:68
+msgctxt "As in name"
+msgid "Title"
+msgstr "Título"
+
+#: weblog/models.py:41 weblog/models.py:69 weblog/models.py:80
+msgctxt "Of post, comment, article, etc."
+msgid "Content"
+msgstr "Contenido"
+
+#: weblog/models.py:42 weblog/models.py:70
+msgid "Preview image"
+msgstr "Imágen de vista previa"
+
+#: weblog/models.py:43 weblog/models.py:71
+msgid "Preview Text"
+msgstr "Texto de vista previa"
+
+#: weblog/models.py:44
+msgid "Original language (ISO)"
+msgstr "Idioma original"
+
+#: weblog/models.py:47
+msgctxt "Make post viewable"
+msgid "Published"
+msgstr "Publicado"
+
+#: weblog/models.py:48
+msgid "Publish date"
+msgstr "Fecha de publicación"
+
+#: weblog/models.py:62
+msgid "Blog Post"
+msgstr "Entrada de blog"
+
+#: weblog/models.py:63
+msgid "Blog Posts"
+msgstr "Entradas de blog"
+
+#: weblog/models.py:66 weblog/models.py:79
+#, fuzzy
+#| msgid "Blog Post"
+msgctxt "Noun, as in blog post"
+msgid "Post"
+msgstr "Entrada"
+
+#: weblog/models.py:74
+msgid "Translation"
+msgstr "Traducción"
+
+#: weblog/models.py:75
+msgid "Translations"
+msgstr "Traducciones"
+
+#: weblog/models.py:83
+msgctxt "Noun"
+msgid "Comment"
+msgstr "Comentario"
+
+#: weblog/models.py:84
+msgctxt "Noun"
+msgid "Comments"
+msgstr "Comentarios"
+
+#: weblog/templates/weblog/index.html:6 weblog/templatetags/weblog_extras.py:43
+#: weblog/views.py:75 weblog/views.py:150
+msgctxt "Posts without category"
+msgid "Uncategorized"
+msgstr "Sin categoría"
+
+#: weblog/templates/weblog/index.html:17
+msgctxt "Uncategorized page title"
+msgid "Uncategorized posts"
+msgstr "Entradas sin categoría"
+
+#: weblog/templates/weblog/index.html:19
+#, python-format
+msgctxt "Posts in category"
+msgid "Posts in %(category_name)s"
+msgstr "Entradas en %(category_name)s"
+
+#: weblog/templates/weblog/index.html:28 weblog/templates/weblog/post.html:7
+#, python-format
+msgid "Published on %(publish_date)s"
+msgstr "Publicado el %(publish_date)s"
+
+#: weblog/templates/weblog/index.html:28 weblog/templates/weblog/post.html:7
+#, python-format
+msgctxt "Written by (Author)"
+msgid ", by %(author)s"
+msgstr ", por %(author)s"
+
+#: weblog/templates/weblog/index.html:34
+msgid "Read more..."
+msgstr "Leer más..."
+
+#: weblog/templates/weblog/index.html:41
+msgctxt "Page"
+msgid "First"
+msgstr "Primera"
+
+#: weblog/templates/weblog/index.html:42
+msgctxt "Page"
+msgid "Previous"
+msgstr "Anterior"
+
+#: weblog/templates/weblog/index.html:70
+msgctxt "Page"
+msgid "Next"
+msgstr "Siguiente"
+
+#: weblog/templates/weblog/index.html:71
+msgctxt "Page"
+msgid "Last"
+msgstr "Última"
+
+#: weblog/templates/weblog/index.html:76
+msgid "Nothing has been posted yet."
+msgstr "No hay ninguna publicación."
+
+#: weblog/templates/weblog/post.html:24
+msgid "Leave a comment"
+msgstr "Dejar un comentario"
+
+#: weblog/templates/weblog/post.html:31
+msgid "Submit comment"
+msgstr "Enviar comentario"
+
+#: weblog/templates/weblog/post.html:35
+msgid "To leave a comment you need to sign in"
+msgstr "Para poder comentar, necesitar iniciar sesión."
+
+#: weblog/templates/weblog/post.html:47
+msgid "Comment submited successfully"
+msgstr "Comentario enviado exitosamente"
+
+#: weblog/templates/weblog/post.html:54
+msgctxt "Unauthenticated comment poster"
+msgid "Anonymous"
+msgstr "Anónimo"
+
+#: weblog/templates/weblog/post.html:62
+msgid "Nobody has left a comment on this post yet"
+msgstr "No hay ningún comentario relacionado a esta entrada"
+
+#: weblog/templates/weblog/sidebar_archive.html:2
+msgctxt "Blog archive"
+msgid "Archive"
+msgstr "Archivo"
+
+#: weblog/templatetags/weblog_extras.py:12
+msgid "January"
+msgstr ""
+
+#: weblog/templatetags/weblog_extras.py:13
+msgid "February"
+msgstr ""
+
+#: weblog/templatetags/weblog_extras.py:14
+msgid "March"
+msgstr ""
+
+#: weblog/templatetags/weblog_extras.py:15
+msgid "April"
+msgstr ""
+
+#: weblog/templatetags/weblog_extras.py:16
+msgid "May"
+msgstr ""
+
+#: weblog/templatetags/weblog_extras.py:17
+msgid "June"
+msgstr ""
+
+#: weblog/templatetags/weblog_extras.py:18
+msgid "July"
+msgstr ""
+
+#: weblog/templatetags/weblog_extras.py:19
+msgid "August"
+msgstr ""
+
+#: weblog/templatetags/weblog_extras.py:20
+msgid "September"
+msgstr ""
+
+#: weblog/templatetags/weblog_extras.py:21
+msgid "October"
+msgstr ""
+
+#: weblog/templatetags/weblog_extras.py:22
+msgid "November"
+msgstr ""
+
+#: weblog/templatetags/weblog_extras.py:23
+msgid "December"
+msgstr ""
+
+#: weblog/views.py:171
+msgid "You need to sign in to submit a comment"
+msgstr "Para poder comentar necesita iniciar sesión"
+
+#: weblog/views.py:173
+msgid "Error submitting comment: Invalid data"
+msgstr "Error al intentar enviar el comentario: Información invalida"
+
+#~ msgid "English"
+#~ msgstr "Inglés"
+
+#~ msgid "Spanish"
+#~ msgstr "Español"
+
+#~ msgid "Russian"
+#~ msgstr "Ruso"
diff --git a/weblog/locale/ru/LC_MESSAGES/django.mo b/weblog/locale/ru/LC_MESSAGES/django.mo
new file mode 100644
index 0000000..a419335
--- /dev/null
+++ b/weblog/locale/ru/LC_MESSAGES/django.mo
Binary files differ
diff --git a/weblog/locale/ru/LC_MESSAGES/django.po b/weblog/locale/ru/LC_MESSAGES/django.po
new file mode 100644
index 0000000..e586fbd
--- /dev/null
+++ b/weblog/locale/ru/LC_MESSAGES/django.po
@@ -0,0 +1,274 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2018-01-31 08:00+0300\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
+"%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n"
+"%100>=11 && n%100<=14)? 2 : 3);\n"
+
+#: weblog/models.py:8 weblog/models.py:23
+msgctxt "Noun, not personal name"
+msgid "Name"
+msgstr "Название"
+
+#: weblog/models.py:9 weblog/models.py:45
+msgid "Slug (URL)"
+msgstr ""
+
+#: weblog/models.py:10
+msgid "Parent category"
+msgstr "Корневая категория"
+
+#: weblog/models.py:19 weblog/models.py:25
+msgctxt "Post category"
+msgid "Category"
+msgstr "Категория"
+
+#: weblog/models.py:20 weblog/models.py:46 weblog/templates/weblog/post.html:16
+#: weblog/templates/weblog/sidebar_categories.html:3
+msgctxt "Post categories"
+msgid "Categories"
+msgstr "Категории"
+
+#: weblog/models.py:24 weblog/models.py:67
+msgid "Language (ISO)"
+msgstr "Язык (В стандарте ISO)"
+
+#: weblog/models.py:34
+msgid "Category name translation"
+msgstr "Перевод названия категории"
+
+#: weblog/models.py:35
+msgid "Category name translations"
+msgstr "Переводы названия категории"
+
+#: weblog/models.py:39 weblog/models.py:78
+msgid "Author"
+msgstr "Автор"
+
+#: weblog/models.py:40 weblog/models.py:68
+msgctxt "As in name"
+msgid "Title"
+msgstr "Название"
+
+#: weblog/models.py:41 weblog/models.py:69 weblog/models.py:80
+msgctxt "Of post, comment, article, etc."
+msgid "Content"
+msgstr "Содержание"
+
+#: weblog/models.py:42 weblog/models.py:70
+msgid "Preview image"
+msgstr "Картинка предпросмотра"
+
+#: weblog/models.py:43 weblog/models.py:71
+msgid "Preview Text"
+msgstr "Текст предпросмотра"
+
+#: weblog/models.py:44
+msgid "Original language (ISO)"
+msgstr "Язык оригинала (в стандарте ISO)"
+
+#: weblog/models.py:47
+msgctxt "Make post viewable"
+msgid "Published"
+msgstr "Опубликовать"
+
+#: weblog/models.py:48
+msgid "Publish date"
+msgstr "Дата публикации"
+
+#: weblog/models.py:62
+msgid "Blog Post"
+msgstr "Запись блога"
+
+#: weblog/models.py:63
+msgid "Blog Posts"
+msgstr "Записи блога"
+
+#: weblog/models.py:66 weblog/models.py:79
+msgctxt "Noun, as in blog post"
+msgid "Post"
+msgstr "Запись"
+
+#: weblog/models.py:74
+msgid "Translation"
+msgstr "Перевод"
+
+#: weblog/models.py:75
+msgid "Translations"
+msgstr "Переводы"
+
+#: weblog/models.py:83
+msgctxt "Noun"
+msgid "Comment"
+msgstr "Комментарий"
+
+#: weblog/models.py:84
+msgctxt "Noun"
+msgid "Comments"
+msgstr "Комментарии"
+
+#: weblog/templates/weblog/index.html:6 weblog/templatetags/weblog_extras.py:43
+#: weblog/views.py:75 weblog/views.py:150
+msgctxt "Posts without category"
+msgid "Uncategorized"
+msgstr "Без категории"
+
+#: weblog/templates/weblog/index.html:17
+msgctxt "Uncategorized page title"
+msgid "Uncategorized posts"
+msgstr "Записи без категории"
+
+#: weblog/templates/weblog/index.html:19
+#, python-format
+msgctxt "Posts in category"
+msgid "Posts in %(category_name)s"
+msgstr "Записи в %(category_name)s"
+
+#: weblog/templates/weblog/index.html:28 weblog/templates/weblog/post.html:7
+#, python-format
+msgid "Published on %(publish_date)s"
+msgstr "Опубликовано %(publish_date)s"
+
+#: weblog/templates/weblog/index.html:28 weblog/templates/weblog/post.html:7
+#, python-format
+msgctxt "Written by (Author)"
+msgid ", by %(author)s"
+msgstr ". %(author)s"
+
+#: weblog/templates/weblog/index.html:34
+msgid "Read more..."
+msgstr "Читать далее..."
+
+#: weblog/templates/weblog/index.html:41
+msgctxt "Page"
+msgid "First"
+msgstr "Первая"
+
+#: weblog/templates/weblog/index.html:42
+msgctxt "Page"
+msgid "Previous"
+msgstr "Предыдущая"
+
+#: weblog/templates/weblog/index.html:70
+msgctxt "Page"
+msgid "Next"
+msgstr "Следующая"
+
+#: weblog/templates/weblog/index.html:71
+msgctxt "Page"
+msgid "Last"
+msgstr "Последняя"
+
+#: weblog/templates/weblog/index.html:76
+msgid "Nothing has been posted yet."
+msgstr "Нет записи на данный момент."
+
+#: weblog/templates/weblog/post.html:24
+msgid "Leave a comment"
+msgstr "Оставьте комментарий"
+
+#: weblog/templates/weblog/post.html:31
+msgid "Submit comment"
+msgstr "Отправить комметарий"
+
+#: weblog/templates/weblog/post.html:35
+msgid "To leave a comment you need to sign in"
+msgstr "Для того чтобы оставить комментарий, зайдите в свою учетную запись"
+
+#: weblog/templates/weblog/post.html:47
+msgid "Comment submited successfully"
+msgstr "Ваш комментарий был успешно отправлен"
+
+#: weblog/templates/weblog/post.html:54
+msgctxt "Unauthenticated comment poster"
+msgid "Anonymous"
+msgstr "Анонимный"
+
+#: weblog/templates/weblog/post.html:62
+msgid "Nobody has left a comment on this post yet"
+msgstr "У этой записи нет комментарии."
+
+#: weblog/templates/weblog/sidebar_archive.html:2
+msgctxt "Blog archive"
+msgid "Archive"
+msgstr "Архив"
+
+#: weblog/templatetags/weblog_extras.py:12
+msgid "January"
+msgstr ""
+
+#: weblog/templatetags/weblog_extras.py:13
+msgid "February"
+msgstr ""
+
+#: weblog/templatetags/weblog_extras.py:14
+msgid "March"
+msgstr ""
+
+#: weblog/templatetags/weblog_extras.py:15
+msgid "April"
+msgstr ""
+
+#: weblog/templatetags/weblog_extras.py:16
+msgid "May"
+msgstr ""
+
+#: weblog/templatetags/weblog_extras.py:17
+msgid "June"
+msgstr ""
+
+#: weblog/templatetags/weblog_extras.py:18
+msgid "July"
+msgstr ""
+
+#: weblog/templatetags/weblog_extras.py:19
+msgid "August"
+msgstr ""
+
+#: weblog/templatetags/weblog_extras.py:20
+msgid "September"
+msgstr ""
+
+#: weblog/templatetags/weblog_extras.py:21
+msgid "October"
+msgstr ""
+
+#: weblog/templatetags/weblog_extras.py:22
+msgid "November"
+msgstr ""
+
+#: weblog/templatetags/weblog_extras.py:23
+msgid "December"
+msgstr ""
+
+#: weblog/views.py:171
+msgid "You need to sign in to submit a comment"
+msgstr "Для того чтобы оставить комментарий, зайдите в свою учетную запись"
+
+#: weblog/views.py:173
+msgid "Error submitting comment: Invalid data"
+msgstr "Ошибка: неправильный формат данных"
+
+#~ msgid "English"
+#~ msgstr "Английский"
+
+#~ msgid "Spanish"
+#~ msgstr "Испанский"
+
+#~ msgid "Russian"
+#~ msgstr "Русский"
diff --git a/weblog/migrations/0001_initial.py b/weblog/migrations/0001_initial.py
new file mode 100644
index 0000000..2ab0238
--- /dev/null
+++ b/weblog/migrations/0001_initial.py
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.8 on 2018-01-09 08:02
+from __future__ import unicode_literals
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='BlogPost',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('title', models.CharField(max_length=100, verbose_name='Title')),
+ ('content', models.TextField(verbose_name='Content')),
+ ('preview_image', models.ImageField(blank=True, upload_to='weblog/preview_images/%Y/%m/%d/', verbose_name='Preview image')),
+ ('preview_text', models.CharField(blank=True, max_length=250, verbose_name='Preview Text')),
+ ('original_language', models.CharField(max_length=5, verbose_name='Original language (ISO)')),
+ ('publish_date', models.DateTimeField(verbose_name='Publish date')),
+ ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Author')),
+ ],
+ options={
+ 'verbose_name': 'Blog Post',
+ 'verbose_name_plural': 'Blog Posts',
+ },
+ ),
+ migrations.CreateModel(
+ name='PostComment',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('content', models.TextField(verbose_name='Content')),
+ ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Author')),
+ ('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='weblog.BlogPost', verbose_name='Post')),
+ ],
+ options={
+ 'verbose_name': 'Comment',
+ 'verbose_name_plural': 'Comments',
+ },
+ ),
+ migrations.CreateModel(
+ name='Translation',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('language', models.CharField(max_length=5, verbose_name='Language (ISO)')),
+ ('title', models.CharField(max_length=100, verbose_name='Title')),
+ ('content', models.TextField(verbose_name='Content')),
+ ('preview_image', models.ImageField(blank=True, upload_to='weblog/preview_images/%Y/%m/%d/', verbose_name='Preview image')),
+ ('preview_text', models.CharField(blank=True, max_length=250, verbose_name='Preview Text')),
+ ('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='weblog.BlogPost', verbose_name='Post')),
+ ],
+ options={
+ 'verbose_name': 'Translation',
+ 'verbose_name_plural': 'Translations',
+ },
+ ),
+ ]
diff --git a/weblog/migrations/0002_auto_20180113_1606.py b/weblog/migrations/0002_auto_20180113_1606.py
new file mode 100644
index 0000000..8eb3789
--- /dev/null
+++ b/weblog/migrations/0002_auto_20180113_1606.py
@@ -0,0 +1,57 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.8 on 2018-01-13 13:06
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('weblog', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Category',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=250, verbose_name='Name')),
+ ('parent_category', models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, to='weblog.Category', verbose_name='Parent category')),
+ ],
+ options={
+ 'verbose_name': 'Category',
+ 'verbose_name_plural': 'Categories',
+ },
+ ),
+ migrations.CreateModel(
+ name='CategoryTranslation',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=250, verbose_name='Name')),
+ ('language', models.CharField(max_length=5, verbose_name='Language (ISO)')),
+ ('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='weblog.Category', verbose_name='Category')),
+ ],
+ options={
+ 'verbose_name': 'Category name translation',
+ 'verbose_name_plural': 'Category name translations',
+ },
+ ),
+ migrations.AddField(
+ model_name='blogpost',
+ name='published',
+ field=models.BooleanField(default=False, verbose_name='Published'),
+ preserve_default=False,
+ ),
+ migrations.AlterField(
+ model_name='blogpost',
+ name='original_language',
+ field=models.CharField(blank=True, max_length=5, verbose_name='Original language (ISO)'),
+ ),
+ migrations.AddField(
+ model_name='blogpost',
+ name='category',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='weblog.Category', verbose_name='Category'),
+ ),
+ ]
diff --git a/weblog/migrations/0003_auto_20180119_0156.py b/weblog/migrations/0003_auto_20180119_0156.py
new file mode 100644
index 0000000..73ca4e1
--- /dev/null
+++ b/weblog/migrations/0003_auto_20180119_0156.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.8 on 2018-01-18 22:56
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('weblog', '0002_auto_20180113_1606'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='blogpost',
+ options={'ordering': ['-publish_date', 'title'], 'verbose_name': 'Blog Post', 'verbose_name_plural': 'Blog Posts'},
+ ),
+ migrations.RemoveField(
+ model_name='blogpost',
+ name='category',
+ ),
+ migrations.AddField(
+ model_name='blogpost',
+ name='categories',
+ field=models.ManyToManyField(blank=True, to='weblog.Category', verbose_name='Categories'),
+ ),
+ ]
diff --git a/weblog/migrations/0004_auto_20180119_0156.py b/weblog/migrations/0004_auto_20180119_0156.py
new file mode 100644
index 0000000..937b7a0
--- /dev/null
+++ b/weblog/migrations/0004_auto_20180119_0156.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.8 on 2018-01-18 22:56
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('weblog', '0003_auto_20180119_0156'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='category',
+ name='parent_category',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='weblog.Category', verbose_name='Parent category'),
+ ),
+ ]
diff --git a/weblog/migrations/0005_auto_20180119_0231.py b/weblog/migrations/0005_auto_20180119_0231.py
new file mode 100644
index 0000000..42b1bd0
--- /dev/null
+++ b/weblog/migrations/0005_auto_20180119_0231.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.8 on 2018-01-18 23:31
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('weblog', '0004_auto_20180119_0156'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='category',
+ name='name',
+ field=models.CharField(max_length=250, unique=True, verbose_name='Name'),
+ ),
+ ]
diff --git a/weblog/migrations/0006_auto_20180121_1002.py b/weblog/migrations/0006_auto_20180121_1002.py
new file mode 100644
index 0000000..db56a3f
--- /dev/null
+++ b/weblog/migrations/0006_auto_20180121_1002.py
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.8 on 2018-01-21 07:02
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('weblog', '0005_auto_20180119_0231'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='blogpost',
+ name='slug',
+ field=models.SlugField(default='Test', max_length=100, unique=True, verbose_name='Slug (URL)'),
+ preserve_default=False,
+ ),
+ migrations.AddField(
+ model_name='category',
+ name='slug',
+ field=models.SlugField(default='Test', max_length=60, unique=True, verbose_name='Slug (URL)'),
+ preserve_default=False,
+ ),
+ ]
diff --git a/weblog/migrations/0007_auto_20180122_1943.py b/weblog/migrations/0007_auto_20180122_1943.py
new file mode 100644
index 0000000..cae0a4f
--- /dev/null
+++ b/weblog/migrations/0007_auto_20180122_1943.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.8 on 2018-01-22 16:43
+from __future__ import unicode_literals
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('weblog', '0006_auto_20180121_1002'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='postcomment',
+ name='author',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Author'),
+ ),
+ ]
diff --git a/weblog/migrations/__init__.py b/weblog/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/weblog/migrations/__init__.py
diff --git a/weblog/models.py b/weblog/models.py
new file mode 100644
index 0000000..80e917e
--- /dev/null
+++ b/weblog/models.py
@@ -0,0 +1,93 @@
+from django.db import models
+from django.shortcuts import reverse
+from django.contrib.auth.models import User
+from django.forms import ModelForm, Textarea
+from django.utils.translation import ugettext_lazy as _, pgettext_lazy
+
+class Category(models.Model):
+ name = models.CharField(max_length=250, verbose_name=pgettext_lazy('Noun, not personal name', 'Name'), blank=False, unique=True)
+ slug = models.SlugField(max_length=60, verbose_name=_('Slug (URL)'), db_index=True, unique=True)
+ parent_category = models.ForeignKey('self', verbose_name=_('Parent category'), null=True, blank=True)
+
+ def get_absolute_url(self):
+ return reverse('weblog:CategoryIndex', kwargs={'category_slug': self.slug})
+
+ def __str__(self):
+ return self.name
+
+ class Meta:
+ verbose_name = pgettext_lazy('Post category', 'Category')
+ verbose_name_plural = pgettext_lazy('Post categories', 'Categories')
+
+class CategoryTranslation(models.Model):
+ name = models.CharField(max_length=250, verbose_name=pgettext_lazy('Noun, not personal name', 'Name'), blank=False)
+ language = models.CharField(max_length=5, verbose_name=_('Language (ISO)'), blank=False)
+ category = models.ForeignKey(Category, verbose_name = pgettext_lazy('Post category', 'Category'), blank=False)
+
+ def __str__(self):
+ return self.name
+
+ def slug(self):
+ return self.category.slug
+
+ class Meta:
+ verbose_name = _('Category name translation')
+ verbose_name_plural = _('Category name translations')
+
+
+class BlogPost(models.Model):
+ author = models.ForeignKey(User, verbose_name=_('Author'))
+ title = models.CharField(max_length=100, verbose_name=pgettext_lazy('As in name', 'Title'), blank=False)
+ content = models.TextField(verbose_name=pgettext_lazy('Of post, comment, article, etc.', 'Content'), blank=False)
+ preview_image = models.ImageField(upload_to='weblog/preview_images/%Y/%m/%d/', blank=True, verbose_name=_('Preview image'))
+ preview_text = models.CharField(max_length=250, blank=True, verbose_name=_('Preview Text'))
+ original_language = models.CharField(max_length=5, verbose_name=_('Original language (ISO)'), blank=True)
+ slug = models.SlugField(max_length=100, verbose_name=_('Slug (URL)'), db_index=True, unique=True)
+ categories = models.ManyToManyField(Category, verbose_name=pgettext_lazy('Post categories', 'Categories'), blank=True)
+ published = models.BooleanField(verbose_name=pgettext_lazy('Make post viewable', 'Published'))
+ publish_date = models.DateTimeField(verbose_name=_('Publish date'))
+
+ def get_absolute_url(self):
+ if self.categories.all().count() > 0:
+ category = self.categories.all()[0].slug
+ return reverse('weblog:PostView', kwargs={'category_slug': category, 'post_slug': self.slug})
+ else:
+ return reverse('weblog:PostView', kwargs={'category_slug': 'misc', 'post_slug': self.slug})
+
+ def __str__(self):
+ return self.title
+
+ class Meta:
+ ordering = ['-publish_date', 'title']
+ verbose_name = _('Blog Post')
+ verbose_name_plural = _('Blog Posts')
+
+class Translation(models.Model):
+ post = models.ForeignKey(BlogPost, verbose_name=pgettext_lazy('Noun, as in blog post', 'Post'))
+ language = models.CharField(max_length=5, verbose_name=_('Language (ISO)'), blank=False)
+ title = models.CharField(max_length=100, verbose_name=pgettext_lazy('As in name', 'Title'), blank=False)
+ content = models.TextField(verbose_name=pgettext_lazy('Of post, comment, article, etc.', 'Content'), blank=False)
+ preview_image = models.ImageField(upload_to='weblog/preview_images/%Y/%m/%d/', blank=True, verbose_name=_('Preview image'))
+ preview_text = models.CharField(max_length=250, blank=True, verbose_name=_('Preview Text'))
+
+ class Meta:
+ verbose_name = _('Translation')
+ verbose_name_plural = _('Translations')
+
+class PostComment(models.Model):
+ author = models.ForeignKey(User, verbose_name=_('Author'), null=True, blank=True)
+ post = models.ForeignKey(BlogPost, verbose_name=pgettext_lazy('Noun, as in blog post', 'Post'))
+ content = models.TextField(verbose_name=pgettext_lazy('Of post, comment, article, etc.', 'Content'), blank=False)
+
+ class Meta:
+ verbose_name = pgettext_lazy('Noun', 'Comment')
+ verbose_name_plural = pgettext_lazy('Noun', 'Comments')
+
+class PostCommentForm(ModelForm):
+ class Meta:
+ model = PostComment
+ fields = ('content',)
+ labels = {'content': ''}
+ widgets = {
+ 'content': Textarea(attrs={'class': 'form-control', 'rows': '5'}),
+ } \ No newline at end of file
diff --git a/weblog/static/weblog/css/weblog.css b/weblog/static/weblog/css/weblog.css
new file mode 100644
index 0000000..cb1facc
--- /dev/null
+++ b/weblog/static/weblog/css/weblog.css
@@ -0,0 +1,7 @@
+.archive-list{
+ list-style-type: none;
+}
+
+.archive-child-list{
+ display: none;
+} \ No newline at end of file
diff --git a/weblog/static/weblog/js/weblog.js b/weblog/static/weblog/js/weblog.js
new file mode 100644
index 0000000..b802841
--- /dev/null
+++ b/weblog/static/weblog/js/weblog.js
@@ -0,0 +1,13 @@
+function toggleNode(caller){
+ state = $(caller).attr('node-state');
+ target = $(caller).attr('node-target');
+ if(state=='closed'){
+ $(caller).html('—');
+ $(caller).attr('node-state', 'open');
+ }
+ else{
+ $(caller).html('+');
+ $(caller).attr('node-state', 'closed');
+ }
+ $('#'+target).toggle();
+} \ No newline at end of file
diff --git a/weblog/templates/weblog/index.html b/weblog/templates/weblog/index.html
new file mode 100644
index 0000000..c46da38
--- /dev/null
+++ b/weblog/templates/weblog/index.html
@@ -0,0 +1,78 @@
+{% extends 'weblog/weblog.html' %}
+{% load i18n %}
+{% block title_block %}
+{% if category %}
+{% if category == 'misc' %}
+{% trans 'Uncategorized' context 'Posts without category' %}
+{% else %}
+{{ category.name }}
+{% endif %}
+{% else %}
+{{ blog_title }}
+{% endif %}
+{% endblock %}
+{% block blog_content_block %}
+{% if category %}
+{% if category == 'misc' %}
+<h1>{% trans 'Uncategorized posts' context 'Uncategorized page title' %}</h1>
+{% else %}
+<h1>{% blocktrans with category_name=category.name context 'Posts in category' %}Posts in {{ category_name }}{% endblocktrans %}</h1>
+{% endif %}
+{% else %}
+<h1>{{ blog_title }}</h1>
+{% endif %}
+ {% if posts %}
+ {% for post in posts %}
+ <div class="container-fluid blogpost">
+ <h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
+ <p class="publish-info">{% blocktrans with publish_date=post.publish_date %}Published on {{ publish_date }}{% endblocktrans %}{% if post.author %}{% blocktrans with author=post.author context 'Written by (Author)' %}, by {{ author }}{% endblocktrans %}{% endif %}</p>
+ <hr>
+ {% if post.preview_image %}<img class="img-responsive preview-img" src="{{ post.preview_image.url }}">{% endif %}
+ {{ post.preview_text|safe }}
+ <hr>
+ <div class="text-right">
+ <a href="{{ post.url }}">{% trans 'Read more...' %}</a>
+ </div>
+ </div>
+ {% endfor %}
+ {% if last_page > 1 %}
+ <ul class="pagination">
+ {% if current_page != 1 %}
+ <li title="{% trans 'First' context 'Page' %}"><a href="{% if category %}{% if category == 'misc' %}{% url 'weblog:CategoryIndex' category_slug='misc' %}{% else %}{% url 'weblog:CategoryIndex' category_slug=category.slug %}{% endif %}{% else %}{% url 'weblog:Index' %}{% endif %}">&laquo;</a></li>
+ <li title="{% trans 'Previous' context 'Page' %}"><a href="{% if category %}{% if category == 'misc' %}{% url 'weblog:CategoryIndex' category_slug='misc' %}?page={{ current_page|add:'-1' }}{% else %}{% url 'weblog:CategoryIndex' category_slug=category.slug %}?page={{ current_page|add:'-1' }}{% endif %}{% else %}{% url 'weblog:Index' %}?page={{ current_page|add:'-1' }}{% endif %}">&larr;</a></li>
+ {% if current_page == last_page and current_page|add:'-4' >= 1 %}
+ <li><a href="{% if category %}{% if category == 'misc' %}{% url 'weblog:CategoryIndex' category_slug='misc' %}?page={{ current_page|add:'-4' }}{% else %}{% url 'weblog:CategoryIndex' category_slug=category.slug %}?page={{ current_page|add:'-4' }}{% endif %}{% else %}{% url 'weblog:Index' %}?page={{ current_page|add:'-4' }}{% endif %}">{{ current_page|add:'-4' }}</a></li>
+ {% endif %}
+ {% if current_page|add:'1' >= last_page and current_page|add:'-3' >= 1 %}
+ <li><a href="{% if category %}{% if category == 'misc' %}{% url 'weblog:CategoryIndex' category_slug='misc' %}?page={{ current_page|add:'-3' }}{% else %}{% url 'weblog:CategoryIndex' category_slug=category.slug %}?page={{ current_page|add:'-3' }}{% endif %}{% else %}{% url 'weblog:Index' %}?page={{ current_page|add:'-3' }}{% endif %}">{{ current_page|add:'-3' }}</a></li>
+ {% endif %}
+ {% if current_page|add:'-2' >= 1 %}
+ <li><a href="{% if category %}{% if category == 'misc' %}{% url 'weblog:CategoryIndex' category_slug='misc' %}?page={{ current_page|add:'-2' }}{% else %}{% url 'weblog:CategoryIndex' category_slug=category.slug %}?page={{ current_page|add:'-2' }}{% endif %}{% else %}{% url 'weblog:Index' %}?page={{ current_page|add:'-2' }}{% endif %}">{{ current_page|add:'-2' }}</a></li>
+ {% endif %}
+ {% if current_page|add:'-1' >= 1 %}
+ <li><a href="{% if category %}{% if category == 'misc' %}{% url 'weblog:CategoryIndex' category_slug='misc' %}?page={{ current_page|add:'-1' }}{% else %}{% url 'weblog:CategoryIndex' category_slug=category.slug %}?page={{ current_page|add:'-1' }}{% endif %}{% else %}{% url 'weblog:Index' %}?page={{ current_page|add:'-1' }}{% endif %}">{{ current_page|add:'-1' }}</a></li>
+ {% endif %}
+ {% endif %}
+ <li class="active"><a href="#">{{ current_page }}</a></li>
+ {% if current_page != last_page %}
+ {% if current_page|add:'1' <= last_page %}
+ <li><a href="{% if category %}{% if category == 'misc' %}{% url 'weblog:CategoryIndex' category_slug='misc' %}?page={{ current_page|add:'1' }}{% else %}{% url 'weblog:CategoryIndex' category_slug=category.slug %}?page={{ current_page|add:'1' }}{% endif %}{% else %}{% url 'weblog:Index' %}?page={{ current_page|add:'1' }}{% endif %}">{{ current_page|add:'1' }}</a></li>
+ {% endif %}
+ {% if current_page|add:'2' <= last_page %}
+ <li><a href="{% if category %}{% if category == 'misc' %}{% url 'weblog:CategoryIndex' category_slug='misc' %}?page={{ current_page|add:'2' }}{% else %}{% url 'weblog:CategoryIndex' category_slug=category.slug %}?page={{ current_page|add:'2' }}{% endif %}{% else %}{% url 'weblog:Index' %}?page={{ current_page|add:'2' }}{% endif %}">{{ current_page|add:'2' }}</a></li>
+ {% endif %}
+ {% if current_page|add:'-1' <= 1 and current_page|add:'3' <= last_page %}
+ <li><a href="{% if category %}{% if category == 'misc' %}{% url 'weblog:CategoryIndex' category_slug='misc' %}?page={{ current_page|add:'3' }}{% else %}{% url 'weblog:CategoryIndex' category_slug=category.slug %}?page={{ current_page|add:'3' }}{% endif %}{% else %}{% url 'weblog:Index' %}?page={{ current_page|add:'3' }}{% endif %}">{{ current_page|add:'3' }}</a></li>
+ {% endif %}
+ {% if current_page == 1 and current_page|add:'4' <= last_page %}
+ <li><a href="{% if category %}{% if category == 'misc' %}{% url 'weblog:CategoryIndex' category_slug='misc' %}?page={{ current_page|add:'4' }}{% else %}{% url 'weblog:CategoryIndex' category_slug=category.slug %}?page={{ current_page|add:'4' }}{% endif %}{% else %}{% url 'weblog:Index' %}?page={{ current_page|add:'4' }}{% endif %}">{{ current_page|add:'4' }}</a></li>
+ {% endif %}
+ <li title="{% trans 'Next' context 'Page' %}"><a href="{% if category %}{% if category == 'misc' %}{% url 'weblog:CategoryIndex' category_slug='misc' %}?page={{ current_page|add:'1' }}{% else %}{% url 'weblog:CategoryIndex' category_slug=category.slug %}?page={{ current_page|add:'1' }}{% endif %}{% else %}{% url 'weblog:Index' %}?page={{ current_page|add:'1' }}{% endif %}">&rarr;</a></li>
+ <li title="{% trans 'Last' context 'Page' %}"><a href="{% if category %}{% if category == 'misc' %}{% url 'weblog:CategoryIndex' category_slug='misc' %}?page={{ last_page }}{% else %}{% url 'weblog:CategoryIndex' category_slug=category.slug %}?page={{ last_page }}{% endif %}{% else %}{% url 'weblog:Index' %}?page={{ last_page }}{% endif %}">&raquo;</a></li>
+ {% endif %}
+ </ul>
+ {% endif %}
+ {% else %}
+ <div class="text-center"><h2>{% trans 'Nothing has been posted yet.' %}</h2></div>
+ {% endif %}
+{% endblock %} \ No newline at end of file
diff --git a/weblog/templates/weblog/post.html b/weblog/templates/weblog/post.html
new file mode 100644
index 0000000..364e17c
--- /dev/null
+++ b/weblog/templates/weblog/post.html
@@ -0,0 +1,67 @@
+{% extends 'weblog/weblog.html' %}
+{% load i18n %}
+{% block title_block %}{% if post_translation %}{{ post_translation.title }}{% else %}{{ post.title }}{% endif %}{% endblock %}
+{% block blog_content_block %}
+<div class="container-fluid blogpost">
+ <h2>{% if post_translation %}{{ post_translation.title }}{% else %}{{ post.title }}{% endif %}</h2>
+ <p class="publish-info">{% blocktrans with publish_date=post.publish_date %}Published on {{ publish_date }}{% endblocktrans %}{% if post_author %}{% blocktrans with author=post_author context 'Written by (Author)' %}, by {{ author }}{% endblocktrans %}{% endif %}</p>
+ <hr>
+ {% if post_translation %}
+ {{ post_translation.content|safe }}
+ {% else %}
+ {{ post.content|safe }}
+ {% endif %}
+ {% if post_categories %}
+ <hr>
+ <p>{% trans 'Categories' context 'Post categories' %}:
+ {% for post_category in post_categories %}
+ <a class="label label-info" href="{% url 'weblog:CategoryIndex' category_slug=post_category.slug %}">{{ post_category.name }}</a>
+ {% endfor %}
+ </p>{% endif %}
+ {% if enable_comments %}
+ <hr id="#comment-section">
+ {% if user.is_authenticated or allow_anon_comments %}
+ <h3>{% trans 'Leave a comment' %}</h3>
+ <form id="comment_form" method="POST" action="{{ post.get_absolute_url }}#comment-section">
+ {% csrf_token %}
+ <div class="form-group">
+ {{ comment_form }}
+ </div>
+ <div class="form-group text-right">
+ <button class="btn btn-primary" type="submit" value="Submit">{% trans 'Submit comment' %}</button>
+ </div>
+ </form>
+ {% else %}
+ <h4>{% trans 'To leave a comment you need to sign in' %}</h4>
+ {% endif %}
+ {% if comments %}
+ {% if comment_submission %}
+ {% if comment_submission_error %}
+ <div class="alert alert-danger alert-dismissable">
+ <a href="#" class="close" data-dismiss="alert" aria-label="close">&times;</a>
+ {{ comment_submission_error }}
+ </div>
+ {% else %}
+ <div class="alert alert-success alert-dismissable">
+ <a href="#" class="close" data-dismiss="alert" aria-label="close">&times;</a>
+ {% trans 'Comment submited successfully' %}
+ </div>
+ {% endif %}
+ {% endif %}
+ {% for comment in comments %}
+ <div class="media">
+ <div class="media-body">
+ <h4 class="media-heading">{% if comment.author %}{{ comment.author.get_username }}{% else %}{% trans 'Anonymous' context 'Unauthenticated comment poster' %}{% endif %}</h4>
+ <p>{{ comment.content }}</p>
+ </div>
+ </div>
+ {% endfor %}
+ {% else %}
+ <div class="text-center">
+ <br>
+ <h3>{% trans 'Nobody has left a comment on this post yet' %}</h3>
+ </div>
+ {% endif %}
+ {% endif %}
+</div>
+{% endblock %} \ No newline at end of file
diff --git a/weblog/templates/weblog/sidebar_archive.html b/weblog/templates/weblog/sidebar_archive.html
new file mode 100644
index 0000000..5953bfe
--- /dev/null
+++ b/weblog/templates/weblog/sidebar_archive.html
@@ -0,0 +1,13 @@
+{% load i18n %}
+<h3>{% trans 'Archive' context 'Blog archive' %}</h3>
+<ul class='archive-list'>
+{% for a_year in archive %}
+<li><a class="node-toggle" node-target="{{ a_year.0 }}-list" node-state="closed" href="javascript:void(0)" onclick="toggleNode(this);">+</a> <a href="{% url 'weblog:ArchiveIndex' year=a_year.0 %}">{{ a_year.0 }}</a>
+ <ul id="{{ a_year.0 }}-list" class='archive-child-list'>
+ {% for a_month in a_year.1 %}
+ <li><a href="{% url 'weblog:ArchiveIndex' year=a_year.0 month=a_month.0 %}">{{ a_month.1 }}</a></li>
+ {% endfor %}
+ </ul>
+</li>
+{% endfor %}
+</ul> \ No newline at end of file
diff --git a/weblog/templates/weblog/sidebar_categories.html b/weblog/templates/weblog/sidebar_categories.html
new file mode 100644
index 0000000..7e7fa5c
--- /dev/null
+++ b/weblog/templates/weblog/sidebar_categories.html
@@ -0,0 +1,11 @@
+{% load i18n %}
+{% if categories %}
+<h3>{% trans 'Categories' context 'Post categories' %}</h3>
+<div class="list-group weblog-categories">
+ {% for category in categories %}
+ <a href="{% url 'weblog:CategoryIndex' category_slug=category.slug %}" class="list-group-item{% if category.slug == selected_cat_slug %} active{% endif %}">
+ {{ category.name }}
+ </a>
+ {% endfor %}
+</div>
+{% endif %} \ No newline at end of file
diff --git a/weblog/templates/weblog/weblog.html b/weblog/templates/weblog/weblog.html
new file mode 100644
index 0000000..9980b54
--- /dev/null
+++ b/weblog/templates/weblog/weblog.html
@@ -0,0 +1,42 @@
+{% extends base_template %}
+{% load i18n %}
+{% load weblog_extras %}
+{% block title_block %}{% endblock %}
+{% block blog_block %}
+<ol class="breadcrumb">
+ {% if breadcrumbs %}
+ <li><a href="{% url 'weblog:Index' %}">{{ blog_title }}</a></li>
+ {% for crumb in breadcrumbs %}
+ {% if forloop.last %}
+ <li class="active">{{ crumb.name }}</li>
+ {% else %}<li><a href="{{ crumb.url }}">{{ crumb.name }}</a></li>{% endif %}
+ {% endfor %}
+ {% else %}
+ <li class="active"><a href="{% url 'weblog:Index' %}">{{ blog_title }}</a></li>
+ {% endif %}
+</ol>
+<div class="row">
+ <div class="{% if show_sidebar %}col-sm-9{% else %}container-fluid{% endif %}">
+ {% block blog_content_block %}
+ {% endblock %}
+ </div>
+ {% if show_sidebar %}
+ <div class="col-sm-3 weblog-sidebar">
+ {% if show_categories %}
+ {% if category %}
+ {% if category == 'misc' %}
+ {% get_sidebar_categories category %}
+ {% else %}
+ {% get_sidebar_categories category.slug %}
+ {% endif %}
+ {% else %}
+ {% get_sidebar_categories %}
+ {% endif %}
+ {% endif %}
+ {% if show_archive %}
+ {% get_sidebar_archive %}
+ {% endif %}
+ </div>
+ {% endif %}
+</div>
+{% endblock %} \ No newline at end of file
diff --git a/weblog/templates/weblog_base.html b/weblog/templates/weblog_base.html
new file mode 100644
index 0000000..536e736
--- /dev/null
+++ b/weblog/templates/weblog_base.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+{% load static %}
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Simple blog - {% block title_block %} Home {% endblock %}</title>
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
+ <link rel="stylesheet" href="{% static '/weblog/css/weblog.css' %}">
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js" defer></script>
+ <script src="{% static '/weblog/js/weblog.js' %}" defer></script>
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" defer></script>
+ </head>
+ <body>
+ <nav class="navbar navbar-inverse">
+ <div class="container nav-container">
+ <div class="navbar-header">
+ <a class="navbar-brand" href="{% url 'weblog:Index' %}">{{ blog_title }}</a>
+ </div>
+ </div>
+ </nav>
+ <div class="container">
+ {% block content_block %}
+ {% block blog_block %}
+ {% endblock %}
+ {% endblock %}
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/weblog/templates/weblog_base_old.html b/weblog/templates/weblog_base_old.html
new file mode 100644
index 0000000..a4dbd30
--- /dev/null
+++ b/weblog/templates/weblog_base_old.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+{% load static %}
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Simple blog - {% block title_block %} Home {% endblock %}</title>
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
+ <link rel="stylesheet" href="{% static '/weblog/css/weblog.css' %}">
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js" defer></script>
+ <script src="{% static '/weblog/js/weblog.js' %}" defer></script>
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" defer></script>
+ </head>
+ <body>
+ <nav class="navbar navbar-inverse">
+ <div class="container nav-container">
+ <div class="navbar-header">
+ <a class="navbar-brand" href="{% url 'weblog:Index' %}">{{ blog_title }}</a>
+ </div>
+ <div class="collapse navbar-collapse">
+ <ul class="nav navbar-nav navbar-right">
+ <li><a href="{% url 'weblog:ChangeLanguage' language='en' %}?next={{ request.path }}">EN</a></li>
+ <li><a href="{% url 'weblog:ChangeLanguage' language='es' %}?next={{ request.path }}">ES</a></li>
+ <li><a href="{% url 'weblog:ChangeLanguage' language='ru' %}?next={{ request.path }}">RU</a></li>
+ </ul>
+ </div>
+ </div>
+ </nav>
+ <div class="container">
+ {% block content_block %}
+ {% block blog_block %}
+ {% endblock %}
+ {% endblock %}
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/weblog/templatetags/__init__.py b/weblog/templatetags/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/weblog/templatetags/__init__.py
diff --git a/weblog/templatetags/__pycache__/__init__.cpython-35.pyc b/weblog/templatetags/__pycache__/__init__.cpython-35.pyc
new file mode 100644
index 0000000..8b2440b
--- /dev/null
+++ b/weblog/templatetags/__pycache__/__init__.cpython-35.pyc
Binary files differ
diff --git a/weblog/templatetags/__pycache__/__init__.cpython-36.pyc b/weblog/templatetags/__pycache__/__init__.cpython-36.pyc
new file mode 100644
index 0000000..8ec5021
--- /dev/null
+++ b/weblog/templatetags/__pycache__/__init__.cpython-36.pyc
Binary files differ
diff --git a/weblog/templatetags/__pycache__/weblog_extras.cpython-35.pyc b/weblog/templatetags/__pycache__/weblog_extras.cpython-35.pyc
new file mode 100644
index 0000000..bcc8327
--- /dev/null
+++ b/weblog/templatetags/__pycache__/weblog_extras.cpython-35.pyc
Binary files differ
diff --git a/weblog/templatetags/__pycache__/weblog_extras.cpython-36.pyc b/weblog/templatetags/__pycache__/weblog_extras.cpython-36.pyc
new file mode 100644
index 0000000..eb1b1e6
--- /dev/null
+++ b/weblog/templatetags/__pycache__/weblog_extras.cpython-36.pyc
Binary files differ
diff --git a/weblog/templatetags/weblog_extras.py b/weblog/templatetags/weblog_extras.py
new file mode 100644
index 0000000..1f72a86
--- /dev/null
+++ b/weblog/templatetags/weblog_extras.py
@@ -0,0 +1,70 @@
+from django import template
+from django.utils import translation
+from django.utils.translation import ugettext_lazy as _, pgettext_lazy
+from django.conf import settings
+from weblog.apps import SETTINGS as blog_settings
+from weblog.models import Category, CategoryTranslation, BlogPost
+import datetime
+
+IS_MULTILINGUAL = blog_settings['multilingual']
+
+MONTHS = (
+ _('January'),
+ _('February'),
+ _('March'),
+ _('April'),
+ _('May'),
+ _('June'),
+ _('July'),
+ _('August'),
+ _('September'),
+ _('October'),
+ _('November'),
+ _('December'),
+)
+
+register = template.Library()
+
+@register.inclusion_tag('weblog/sidebar_categories.html')
+def get_sidebar_categories(selected_cat_slug=None):
+ now = datetime.datetime.now()
+ current_language = translation.get_language()
+ if current_language is None:
+ current_language = settings.LANGUAGE_CODE
+ context_dict = {'categories': [], 'selected_cat_slug': selected_cat_slug}
+ for raw_category in Category.objects.all():
+ next_category = {'name': raw_category.name, 'slug': raw_category.slug}
+ if CategoryTranslation.objects.filter(category=raw_category).count() > 0 and IS_MULTILINGUAL:
+ for category_translation in CategoryTranslation.objects.filter(category=raw_category):
+ if current_language[0:2] == category_translation.language[0:2]:
+ next_category['name'] = category_translation.name
+ context_dict['categories'].append(next_category)
+ if BlogPost.objects.filter(published=True, publish_date__lte=now, categories=None).count() > 0:
+ context_dict['categories'].append({'name': pgettext_lazy('Posts without category', 'Uncategorized'), 'slug': 'misc'})
+ return context_dict
+
+
+@register.inclusion_tag('weblog/sidebar_archive.html')
+def get_sidebar_archive():
+ now = datetime.datetime.now()
+ oldest_post = BlogPost.objects.filter(published=True).reverse()[0]
+ first_year = oldest_post.publish_date.year
+ first_month = oldest_post.publish_date.month
+ newest_post = BlogPost.objects.filter(published=True, publish_date__lte=now)[0]
+ latest_year = newest_post.publish_date.year
+ latest_month = newest_post.publish_date.month
+ c_month = first_month
+ c_year = first_year
+ archive = []
+ while c_year <= latest_year:
+ if BlogPost.objects.filter(publish_date__year=c_year, publish_date__lte=now, published=True).count() > 0:
+ this_years_months = []
+ while (c_year < latest_year or c_month <= latest_month) and c_month <= 12:
+ if BlogPost.objects.filter(publish_date__month=c_month, publish_date__lte=now, published=True).count() > 0:
+ this_years_months.append((c_month, MONTHS[c_month-1]))
+ c_month+=1
+ archive.append((c_year, this_years_months))
+ c_year+=1
+ c_month=1
+ archive.reverse()
+ return {'archive': archive}
diff --git a/weblog/tests.py b/weblog/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/weblog/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/weblog/urls.py b/weblog/urls.py
new file mode 100644
index 0000000..643e8c7
--- /dev/null
+++ b/weblog/urls.py
@@ -0,0 +1,12 @@
+from django.conf.urls import url
+from . import views
+
+app_name = 'weblog'
+urlpatterns = [
+ url(r'^$', views.Index, name='Index'),
+ url(r'^change-language/(?P<language>[-\w]+)/$', views.ChangeLanguage, name='ChangeLanguage'),
+ url(r'^(?P<year>[0-9]{4})/$', views.Index, name='ArchiveIndex'),
+ url(r'^(?P<year>[0-9]{4})/(?P<month>[0-9]{1,2})/$', views.Index, name='ArchiveIndex'),
+ url(r'^(?P<category_slug>[-\w]+)/$', views.Index, name='CategoryIndex'),
+ url(r'^(?P<category_slug>[-\w]+)/(?P<post_slug>[-\w]+)/$', views.PostView, name='PostView'),
+] \ No newline at end of file
diff --git a/weblog/views.py b/weblog/views.py
new file mode 100644
index 0000000..8a05bcc
--- /dev/null
+++ b/weblog/views.py
@@ -0,0 +1,207 @@
+from django.shortcuts import render, get_object_or_404, redirect, reverse
+from django.http import Http404, HttpResponseRedirect
+from django.conf import settings
+from django.utils import translation
+from django.utils.translation import ugettext_lazy as _, pgettext_lazy
+from .apps import SETTINGS as blog_settings
+from .models import BlogPost, Translation, PostComment, Category, CategoryTranslation, PostCommentForm
+import datetime
+
+#Why the hell didn't I just pass the variables to the context_dict in the first place??
+#Need to remove this later
+IS_MULTILINGUAL = blog_settings['multilingual']
+BASE_TEMPLATE = blog_settings['base_template']
+BLOG_TITLE = blog_settings['blog_title']
+SHOW_SIDEBAR = blog_settings['show_sidebar']
+POSTS_PER_PAGE = blog_settings['posts_per_page']
+SHOW_AUTHOR = blog_settings['show_author']
+USE_AUTHORS_USERNAME = blog_settings['use_authors_username']
+ENABLE_COMMENTS = blog_settings['enable_comments']
+ALLOW_ANON_COMMENTS = blog_settings['allow_anon_comments']
+
+def Index(request, **kwargs):
+ context_dict = blog_settings.copy()
+ now = datetime.datetime.now()
+ all_pages = BlogPost.objects.filter(published=True, publish_date__lte=now)
+ category = None
+ if kwargs is not None:
+ category_slug = kwargs.get('category_slug')
+ year = kwargs.get('year')
+ month = kwargs.get('month')
+ if category_slug:
+ if category_slug == 'misc':
+ all_pages = BlogPost.objects.filter(published=True, publish_date__lte=now, categories=None)
+ context_dict['category'] = 'misc'
+ else:
+ category = get_object_or_404(Category, slug=category_slug)
+ context_dict['category'] = category
+ all_pages = BlogPost.objects.filter(published=True, publish_date__lte=now, categories__slug=category_slug)
+ if year:
+ all_pages = BlogPost.objects.filter(published=True, publish_date__lte=now, publish_date__year=year)
+ if month:
+ all_pages = BlogPost.objects.filter(published=True, publish_date__lte=now, publish_date__month=month)
+ post_count = all_pages.count()
+ if post_count < 1:
+ return render(request, 'weblog/index.html', context_dict)
+ page = 0
+ if request.GET.get('page'):
+ page = int(request.GET['page'])-1
+ if page * POSTS_PER_PAGE + 1 > post_count:
+ page = 0
+ context_dict['current_page'] = page+1
+ slice_start = page*POSTS_PER_PAGE
+ slice_end = page*POSTS_PER_PAGE + POSTS_PER_PAGE
+ if slice_end >= post_count:
+ slice_end = post_count
+ if post_count % POSTS_PER_PAGE == 0:
+ last_page = int(post_count/POSTS_PER_PAGE)
+ else:
+ last_page = int(post_count/POSTS_PER_PAGE)+1
+ context_dict['last_page'] = last_page
+ posts_raw = all_pages[slice_start:slice_end]
+ if category_slug:
+ posts_raw = all_pages[slice_start:slice_end]
+ current_language = translation.get_language()
+ if current_language is None:
+ current_language = settings.LANGUAGE_CODE
+ if category_slug:
+ if IS_MULTILINGUAL and category_slug != 'misc':
+ category_translations = CategoryTranslation.objects.filter(category=category)
+ if category_translations.count() > 0:
+ for cat_trans in category_translations:
+ if current_language[0:2] == cat_trans.language[0:2]:
+ context_dict['category'] = cat_trans
+ if category_slug == 'misc':
+ context_dict['breadcrumbs'] = [{'url': reverse('weblog:CategoryIndex', kwargs={'category_slug': category_slug}), 'name': pgettext_lazy('Posts without category', 'Uncategorized')},]
+ else:
+ context_dict['breadcrumbs'] = [{'url': reverse('weblog:CategoryIndex', kwargs={'category_slug': category_slug}), 'name': context_dict['category']},]
+ posts = []
+ for post_raw in posts_raw:
+ post = {'publish_date': post_raw.publish_date, 'url': post_raw.get_absolute_url()}
+ if SHOW_AUTHOR:
+ post['author'] = post_raw.author.get_full_name()
+ if USE_AUTHORS_USERNAME:
+ post['author'] = post_raw.author.get_username()
+ translation_exists = False
+ post_translations = Translation.objects.filter(post=post_raw)
+ if post_translations.count() < 1 or not IS_MULTILINGUAL:
+ post['title'] = post_raw.title
+ post['content'] = post_raw.content
+ post['preview_image'] = post_raw.preview_image
+ if len(post_raw.preview_text) > 5:
+ post['preview_text'] = post_raw.preview_text
+ else:
+ post['preview_text'] = post_raw.content.split('</p>', 1)[0]+'</p>'
+ else:
+ post_trans = None
+ orig_lang = post_raw.original_language
+ if len(orig_lang) < 2:
+ orig_lang = settings.LANGUAGE_CODE[0:2]
+ post['languages'] = [orig_lang,]
+ for post_translation in post_translations:
+ post['languages'].append(post_translation.language)
+ if current_language[0:2] == post_translation.language[0:2]:
+ post_trans = post_translation
+ if post_trans:
+ post['title'] = post_trans.title
+ post['content'] = post_trans.content
+ post['current_language'] = post_trans.language
+ post['preview_image'] = post_trans.preview_image
+ if len(post_trans.preview_text) > 5:
+ post['preview_text'] = post_trans.preview_text
+ else:
+ post['preview_text'] = post_trans.content.split('\n', 1)[0]+'</p>'
+ else:
+ post['title'] = post_raw.title
+ post['content'] = post_raw.content
+ post['current_language'] = orig_lang
+ post['preview_image'] = post_raw.preview_image
+ if len(post_raw.preview_text) > 5:
+ post['preview_text'] = post_raw.preview_text
+ else:
+ post['preview_text'] = post_raw.content.split('</p>', 1)[0]+'</p>'
+ posts.append(post)
+ context_dict['posts'] = posts
+ return render(request, 'weblog/index.html', context_dict)
+
+
+def PostView(request, category_slug, post_slug):
+ post = get_object_or_404(BlogPost, slug=post_slug)
+ context_dict = blog_settings.copy()
+ context_dict['comment_form'] = PostCommentForm()
+ post_translations = Translation.objects.filter(post=post)
+ category = None
+ current_language = translation.get_language()
+ if current_language is None:
+ current_language = settings.LANGUAGE_CODE
+ if category_slug:
+ if category_slug == 'misc':
+ context_dict['category'] = 'misc'
+ else:
+ category = get_object_or_404(Category, slug=category_slug)
+ context_dict['category'] = category
+ if IS_MULTILINGUAL:
+ category_translations = CategoryTranslation.objects.filter(category=category)
+ if category_translations.count() > 0:
+ for cat_trans in category_translations:
+ if current_language[0:2] == cat_trans.language[0:2]:
+ context_dict['category'] = cat_trans
+ if category_slug == 'misc':
+ context_dict['breadcrumbs'] = [{'url': reverse('weblog:CategoryIndex', kwargs={'category_slug': category_slug}), 'name': pgettext_lazy('Posts without category', 'Uncategorized')},]
+ else:
+ context_dict['breadcrumbs'] = [{'url': reverse('weblog:CategoryIndex', kwargs={'category_slug': category_slug}), 'name': context_dict['category']},]
+ if SHOW_AUTHOR:
+ context_dict['post_author'] = post.author.get_full_name()
+ if USE_AUTHORS_USERNAME:
+ context_dict['post_author'] = post.author.get_username()
+ if ENABLE_COMMENTS:
+ context_dict['comments'] = PostComment.objects.filter(post=post)
+ if request.method == 'POST':
+ form = PostCommentForm(request.POST)
+ context_dict['comment_submission'] = True
+ if form.is_valid():
+ comment_content = form.cleaned_data['content']
+ if request.user.is_authenticated():
+ new_comment = PostComment(author=request.user, post=post, content=comment_content)
+ new_comment.save()
+ elif ALLOW_ANON_COMMENTS:
+ new_comment = PostComment(post=post, content=comment_content)
+ new_comment.save()
+ else:
+ context_dict['comment_submission_error'] = _('You need to sign in to submit a comment')
+ else:
+ context_dict['comment_submission_error'] = _('Error submitting comment: Invalid data')
+ context_dict['post'] = post
+ if post.categories.all().count() > 0:
+ context_dict['post_categories'] = []
+ for raw_category in post.categories.all():
+ next_category = {'name': raw_category.name, 'slug': raw_category.slug}
+ if CategoryTranslation.objects.filter(category=raw_category).count() > 0 and IS_MULTILINGUAL:
+ for category_translation in CategoryTranslation.objects.filter(category=raw_category):
+ if current_language[0:2] == category_translation.language[0:2]:
+ next_category['name'] = category_translation.name
+ context_dict['post_categories'].append(next_category)
+ if post_translations.count() < 1 or not IS_MULTILINGUAL:
+ context_dict['breadcrumbs'].append({'url': post.get_absolute_url(), 'name': post.title})
+ return render(request, 'weblog/post.html', context_dict)
+ orig_lang = post.original_language
+ if len(orig_lang) < 2:
+ orig_lang = settings.LANGUAGE_CODE[0:2]
+ context_dict['languages'] = [orig_lang,]
+ for post_translation in post_translations:
+ context_dict['languages'].append(post_translation.language)
+ if current_language[0:2] == post_translation.language[0:2]:
+ context_dict['post_translation'] = post_translation
+ if 'post_translation' in context_dict:
+ context_dict['breadcrumbs'].append({'url': post.get_absolute_url(), 'name': post_translation.title})
+ else:
+ context_dict['breadcrumbs'].append({'url': post.get_absolute_url(), 'name': post.title})
+ return render(request, 'weblog/post.html', context_dict)
+
+def ChangeLanguage(request, language):
+ translation.activate(language)
+ request.session[translation.LANGUAGE_SESSION_KEY] = language
+ if request.GET.get('next'):
+ return HttpResponseRedirect(request.GET['next'])
+ return HttpResponseRedirect(reverse('weblog:Index'))
+ \ No newline at end of file