Журнальная вёрстка   Делаем “красиво” с Django           Алексей Дубков            alex@evid.ru       MoscowDjango, 01/03/...
CMS против• Раньше верстали руками• Сейчас копируют и вставляют• Скучный “Текст”• HTML-редактор не спасает• Скудное оформл...
Что хочется• Перемешивать текст и графику• Делать выноски, плашки• Делать колонки• Расставлять акценты• Галерею, вот прямо...
И так...
В чём идея?• Любой элемент — блок• Блоки: текст + графика• Сверху-вниз• Слева-направо• Блоки независимы друг от друга
Итак, блоки• Они могут быть разных типов• Как-то отсортированы• Привязаны к Статье, Новости и т.д.
# blocks/models.pyfrom django.db import modelsfrom django.contrib.contenttypes.models import ContentTypefrom django.contri...
# blocks/admin.pyfrom django.contrib import adminfrom django.contrib.contenttypes.generic importGenericStackedInlinefrom b...
Вывести блоки• Выбираем блоки для статьи• Склеиваем (CAN_COLLAPSE)• Отдельный рендер для блока• Склеиваем конечный HTML
# blocks/utils.pyfrom django.template import RequestContext, loaderfrom django.contrib.contenttypes.models import ContentT...
# blocks/utils.py    ...    bl = []     # blocks tuple (type, data)    if blocks_count:        it = 0        i = 0        ...
# blocks/utils.py    ...    html =    # result html    if blocks_count:        for (type, item) in bl:            t_name =...
Шаблоны• В простых шаблонах сразу выводятся  переменные {{ title }}, {{ text }}...• В склееных шаблонах нужен цикл• {{ for...
Пример• Делаем статьи• Подключаем админку• Блоки подключаем через inlines• Делаем вывод
# articles/models.pyfrom django.db import modelsclass Article(models.Model):    title = models.CharField(max_length=64)   ...
# articles/admin.pyfrom django.contrib import adminfrom articles.models import Articlefrom blocks.admin import BlockInline...
# articles/views.pydef articles_one(request, id):    obj = get_object_or_404(Article, id=id)    blocks_html = get_blocks_h...
Ньюансы• Как хранить картинки• Утомительная сортировка• Производительность
# blocks/models.pydef image_upload(instance, filename):    return "block/%s/%s" %    (instance.content_object.block_image_...
$(document).ready(function(){$(#block-block-content_type-object_id-group .add-rowa).click(function(){var totalBlocks=$(#id...
Скорость• Производительность низкая• Можно сохранять HTML• Переопределив save_model в админке  сохранять дважды
Минусы• Сложно в обучении• Можно “накакафонить”• Подгонять контент под формат
Спасибо
Журнальная вёрстка в Django
Журнальная вёрстка в Django
Журнальная вёрстка в Django
Журнальная вёрстка в Django
Журнальная вёрстка в Django
Журнальная вёрстка в Django
Журнальная вёрстка в Django
Журнальная вёрстка в Django
Журнальная вёрстка в Django
Журнальная вёрстка в Django
Журнальная вёрстка в Django
Журнальная вёрстка в Django
Upcoming SlideShare
Loading in …5
×

Журнальная вёрстка в Django

3,948 views

Published on

Published in: Technology
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,948
On SlideShare
0
From Embeds
0
Number of Embeds
137
Actions
Shares
0
Downloads
32
Comments
0
Likes
6
Embeds 0
No embeds

No notes for slide

Журнальная вёрстка в Django

  1. 1. Журнальная вёрстка Делаем “красиво” с Django Алексей Дубков alex@evid.ru MoscowDjango, 01/03/2012
  2. 2. CMS против• Раньше верстали руками• Сейчас копируют и вставляют• Скучный “Текст”• HTML-редактор не спасает• Скудное оформление
  3. 3. Что хочется• Перемешивать текст и графику• Делать выноски, плашки• Делать колонки• Расставлять акценты• Галерею, вот прямо сюда
  4. 4. И так...
  5. 5. В чём идея?• Любой элемент — блок• Блоки: текст + графика• Сверху-вниз• Слева-направо• Блоки независимы друг от друга
  6. 6. Итак, блоки• Они могут быть разных типов• Как-то отсортированы• Привязаны к Статье, Новости и т.д.
  7. 7. # blocks/models.pyfrom django.db import modelsfrom django.contrib.contenttypes.models import ContentTypefrom django.contrib.contenttypes import genericclass Block(models.Model): BLOCK_TYPES = ( (11, uT-01: Обычный текст), (21, uP-01: Картинки 250x в 3 колонки),) CAN_COLLAPSE = (21,) content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey( content_type, object_id) block_type = models.IntegerField(choices=BLOCK_TYPES) sort = models.IntegerField(default=20) image = models.ImageField(blank=True) title = models.CharField(max_length=255, blank=True) text = models.TextField(blank=True)
  8. 8. # blocks/admin.pyfrom django.contrib import adminfrom django.contrib.contenttypes.generic importGenericStackedInlinefrom blocks.models import Blockclass BlockInline(GenericStackedInline): model = Block extra = 0 fieldsets = ( (None, { fields: ((block_type, sort,), image, title, text,) }), )
  9. 9. Вывести блоки• Выбираем блоки для статьи• Склеиваем (CAN_COLLAPSE)• Отдельный рендер для блока• Склеиваем конечный HTML
  10. 10. # blocks/utils.pyfrom django.template import RequestContext, loaderfrom django.contrib.contenttypes.models import ContentTypefrom blocks.models import Blockdef get_blocks_html(request, obj): content_type = ContentType.objects.get( model=obj.__class__.__name__) blocks = Block.objects.filter( content_type=content_type, object_id=obj.id).order_by(sort) blocks_count = blocks.count()
  11. 11. # blocks/utils.py ... bl = [] # blocks tuple (type, data) if blocks_count: it = 0 i = 0 while i < blocks_count: type = blocks[i].block_type if type in Block.CAN_COLLAPSE: result = [] it = i for j in blocks[i:]: if j.block_type == type: result.append(j) it += 1 else: break bl.append([type, {blocks:result}]) i = it - 1 else: bl.append([type, blocks[i].__dict__]) i += 1
  12. 12. # blocks/utils.py ... html = # result html if blocks_count: for (type, item) in bl: t_name = "blocks/block-%s.html" % type t = loader.get_template(t_name) render = t.render( RequestContext(request, item)) html += render return html
  13. 13. Шаблоны• В простых шаблонах сразу выводятся переменные {{ title }}, {{ text }}...• В склееных шаблонах нужен цикл• {{ for item in blocks }}
  14. 14. Пример• Делаем статьи• Подключаем админку• Блоки подключаем через inlines• Делаем вывод
  15. 15. # articles/models.pyfrom django.db import modelsclass Article(models.Model): title = models.CharField(max_length=64) pub_date = models.DateField() blocks_html = models.TextField(blank=True) class Meta: ordering = [-pub_date]
  16. 16. # articles/admin.pyfrom django.contrib import adminfrom articles.models import Articlefrom blocks.admin import BlockInlineclass ArticleAdmin(admin.ModelAdmin): save_on_top = True inlines = [BlockInline, ] list_display = ( title, pub_date,)admin.site.register(Article, ArticleAdmin)
  17. 17. # articles/views.pydef articles_one(request, id): obj = get_object_or_404(Article, id=id) blocks_html = get_blocks_html(request, obj) return render_to_response( articles/articles_one.html, {obj: obj,blocks_html: blocks_html,}, context_instance=RequestContext(request))
  18. 18. Ньюансы• Как хранить картинки• Утомительная сортировка• Производительность
  19. 19. # blocks/models.pydef image_upload(instance, filename): return "block/%s/%s" % (instance.content_object.block_image_path(), filename.lower())# artiles/models.pyclass Article(models.Model): ... def block_image_path(self): return "article/%d/%02d/%d" % ( self.pub_date.year, self.pub_date.month, self.id)
  20. 20. $(document).ready(function(){$(#block-block-content_type-object_id-group .add-rowa).click(function(){var totalBlocks=$(#id_block-block-content_type-object_id-TOTAL_FORMS).val();var sortFieldId="#id_block-block-content_type-object_id-"+parseInt(totalBlocks-2)+"-sort";var newSortFieldId="#id_block-block-content_type-object_id-"+parseInt(totalBlocks-1)+"-sort";var lastSortVal=$(sortFieldId).val();var newSortVal=parseInt(lastSortVal)+10;$(newSortFieldId).val(newSortVal);})
  21. 21. Скорость• Производительность низкая• Можно сохранять HTML• Переопределив save_model в админке сохранять дважды
  22. 22. Минусы• Сложно в обучении• Можно “накакафонить”• Подгонять контент под формат
  23. 23. Спасибо

×