Показаны сообщения с ярлыком django-cms. Показать все сообщения
Показаны сообщения с ярлыком django-cms. Показать все сообщения

5 янв. 2011 г.

Надо работать

Итак друзья, в связи с сильно затянувшимися новогодними каникулами и полным отсутствием денег, ищу любую оплачиваемую удаленную работу “по специальности” (можно и не удаленную, но тогда в Тюмени или в Москве в с предоставлением жилья). Под “специальностью” надо понимать django, python, SEO, HTML/CSS верстка, javascript’овые фичи и пр. Люблю и немного умею оптимизировать проекты под высокие нагрузки. Работал со большинством реляционных систем управления базами данных.

Рассмотрю любые предложения. Пишите: markeev@gmail.com.




24 дек. 2010 г.

Django и django-cms

Сегодня (или вчера?) вышли 2 важных для меня промежуточных релиза: первый Django 1.3 beta 1 и django-cms-2.1-rc-1. Нужно ли говорить, что django-cms 2.1 мы все ждем уже почти год? В последнее время сообщество, работающее на этом проект сильно перетрясли. За последний месяц там появилось 2 мейнтейнера и вообще как-то все оживилось и все зашевелилось. Правда, не обошлось и без казусов – на сколько я понял в порыве интенсификации развития версии 2.1 убили переводы к 2.0.2 версии (на трансфикс) для русского языка.

Попутно с первой бета к django вышли 2 секуритификса для версии 1.1 и 1.2, т.е. 1.2.4 и 1.1.3. Такие вещи я ставлю не глядя, за что меня конечно нужно срочно гнобить в комментариях.

UPD. Почему мы ждали django-cms? Потому что там есть Frontend Editing.




22 окт. 2010 г.

Updates: django-reversion и cmsplugin_gallery

Хочу акцентировать ваше внимание на двух инструментах для django-cms:

http://github.com/etianen/django-reversion (вообще, можно использовать в проектах на джанго без django-cms) – позволяет хранить ревизии объектов, в django-cms используется для восстановления удаленных страниц.

http://www.django-cms.org/en/extensions/gallery-plugin/detail/ – галерея с Drag&Drop для 2.1 версии, которая все никак не появиться…




18 июн. 2010 г.

Всякие интересности…

Не могу больше скрывать от всех эти ссылки – слишком уж интересные.

http://www.slideshare.net/digi604/django-cmskey – интересная презентация Django-CMS.

http://www.google.com/talk/service/badge/New - Google Talk chatback badge – бесплатный онлайн чат от гугла (как у меня в блоге “чат со мной”).

http://www.google.com/talk/service/a/concepter.ru/badge/New – версия предыдущего chatback badge для доменов в Google Apps (нужно заменить concepter.ru на название вашего домена)

http://javascript.ru/blog/mycoding/Izuchaem-ExtJS – интересная объемная статья по изучению ExtJS, который теперь вообще-то sencha

http://pyplanet.org/ - “виртуальная площадка на русском языке для обмена опыта между начинающими программистами и гуру питона” - растет и развивается, так что поглядывайте!

http://www.tyumen-city.ru/dom/index.php - информационно-справочной системой «Ваш дом» для Тюменцев - нужные адреса, телефоны, границы избирательных округов, время приема граждан депутатами Тюменской городской Думы («Ваш депутат», «Участковые», «Квартальные», «Управляющие компании», «Поликлиники»).




19 мая 2010 г.

Ширина Django-tinymce редактора в django-cms

Столкнулся с очередной неприятностью – в django-cms с подключенным tinymce редактор по умолчанию фиксированной ширины. Решение много проще, чем я в начале думал. Оказывается, django-tinymce использует переопределение дефолтного конфига через Ваш файл настроек проекта. Пример моего конфига:


TINYMCE_JS_URL = MEDIA_URL + 'js/tinymce/jscripts/tiny_mce/tiny_mce.js'

TINYMCE_JS_ROOT = MEDIA_ROOT + 'js/tinymce/jscripts/tinymce/jscripts/tiny_mce'

TINYMCE_DEFAULT_CONFIG = {

    'theme'"advanced",

    'width'"100%",

    'height'"500px",

}


16 мая 2010 г.

Как определить раздел в django-cms?

На одном из django-сайтов, активно использующих django-cms, понадобилось менять флэшку в зависимости от раздела. Не придумал ничего лучше смотреть кусок пути:


{% ifequal request.path_info|slice:":10" '/ekologiya' %}

...

{% endifequal %}


Дело в том, что в джанго-цмс у страниц может быть множество потомков, потому то и приходиться смотреть на кусок uri.

Может быть Вам известен более правильный путь? (более, т.к. этот тоже работает :) )

 

ЗЫ. Конкурс на угадывание сайта, для которого это понадобилось: приз – ссылка с 3 моих сайтов (кому только они нужны?) на сайт угадавшего.

14 мая 2010 г.

www.russned.tv

Вот и подошел к  концу первый этап разработки www.russned.tv – это видеохостинг на django. Из названия ясно, что сайт сделан для наших друзей - Русской недели. При разработке использована куча всяких django-приложений:

  • django-cms (с кучищей плагинов)
  • django-profile (понадобиться для регистрации и, поздней, для добавления роликов пользователями)
  • django-ratings
  • django-ajaxcomments
  • + набор собственных приложений, которые теперь переносятся из проекта в проект.

У некоторых роликов есть полная avi-версия.

Django-сообществу возможно, будут интересны следующие куски кода этого проекта:

1. Список последних просмотренных роликов


videos = MyVideo.objects.annotate(last=Max('videoview__when')).order_by('-last')[:limit]


Между прочим, универсальный вариант GROUP BY средствами django ORM’а.

2. Ролики отсортированные по соотношению рейтинга к кол-ву голосов:


videos = MyVideo.objects.extra(select={

        'a_rating''rating_score/rating_votes'

    }).order_by('-a_rating')[:limit]


Это специфика использования djangoratings – кто использовал поймет ;)

3. Ролики с сортировкой по кол-ву комментариев (только откомментированные):


videos = MyVideo.objects.annotate(comments_count=Count('comments')).\

        exclude(comments_count=0).order_by('-comments_count')[:limit]


В основе файл models:


class MyVideo(models.Model):

    ...

    title = models.CharField(_(u'название'), max_length=250, unique=True)

    desc = models.TextField(_(u'описание'), max_length=250, null=True, blank=True)

    category = models.ForeignKey(Category, verbose_name=_(u'категория'), blank=True, null=True)

    tags = TagAutocompleteField()



    rating = RatingField(range=5, weight=1, can_change_vote=True, allow_anonymous=False)



    comments = generic.GenericRelation(Comment, content_type_field="content_type", object_id_field="object_pk")



class VideoView(models.Model):

    video = models.ForeignKey(MyVideo)

    when = models.DateTimeField(auto_now_add=True)

    user = models.ForeignKey(User, null=True, blank=True, editable=False)


Смотрите, качайте, советуйте друзьям! www.russned.tv.

28 мар. 2010 г.

django-cms 2.1.0 beta

24-го марта тихо и незаметно вышла 2.1.0 beta версия django-cms (отличная система управления контентом на django, о которой я уже писал). Список изменений обширен, но остановиться хочется лишь на нескольких:

  • добавлено inline редактирование placeholder’ов страниц (об этом уже было отличное видео целых 5 месяцев назад)
  • инструмент для управления менюшками вынесли в отдельных продукт (с этим кстати, связано нарушение обратной совместимости – тэг меню нужно грузить отдельно, приложение подключать).
  • переделаны примеры шаблонов.
  • переделан виджет смены языков.

Остальные изменения затрагивают, в основном, меню и исправления всевозможных багов.

На странице с изменениями есть рекомендации по переходу на новую версию.

Скачать можно по адресу: http://www.django-cms.org/en/downloads/.




18 февр. 2010 г.

Автодополнение тэгов в django

Я очарован ещё одним django-приложением django-tagging-autocomplete. Сделать autocomplete(автодополнение/подсказоньки) тэгов с помощью этого приложения очень и очень просто.

4 шага со страницы проекта на Google Code (django-tagging у нас уже установлен, так?):

1. Установите django-tagging-autocomplete. Например так:


easy_install django-tagging-autocomplete


2. Скачайте jquery-autocomplete, положите в папку с вашим media контентом (надо сохранить структуру папок из архива). За нахождение библиотеки отвечает опция TAGGING_AUTOCOMPLETE_JS_BASE_URL, то есть можно её переопределить у себя в settings.

3. Добавляем "tagging_autocomplete" в installed apps в settings.

4. Добавляем строку в urls.py:


(r'^tagging_autocomplete/', include('tagging_autocomplete.urls')),


Использовать так:



from django.db import models

from tagging_autocomplete.models import TagAutocompleteField



class SomeModel(models.Model):

        tags = TagAutocompleteField()








и вот так для форм:




from django import forms

from tagging.forms import TagField

from tagging_autocomplete.widgets import TagAutocomplete



class SomeForm(forms.Form):

    tags = TagField(widget=TagAutocomplete())




Во фронт части надо как-то подключать скрипты jquery-autocomplete. Наверное, можно через form.media, но я тупо написал:





<script src="http://cdn.jquerytools.org/1.1.2/full/jquery.tools.min.js"></script>

<link href="/media/jquery.autocomplete.css" type="text/css" media="all" rel="stylesheet" /> 

<script type="text/javascript" src="/media/jquery.autocomplete.js"></script> 





Естественно, данное решение можно использовать и в django-cms. Если интересно, могу написать как.




16 февр. 2010 г.

Django-cms, WYMEditor: свои стили.

По умолчанию набор стилей ограничен. Вот я и решил добавить свой стиль “center”, центрующий контент. На скрине он “PARA: Center”. Смысл “PARA” я не понимаю, но оставляю как есть.

after

Все доступные настройки данного плагина хранятся в cms/plugins/text/settings.py.

Я добавил в свой settings.py проекта следующие строки:


WYM_CLASSES = ",\n".join([

    "{'name': 'date', 'title': 'PARA: Date', 'expr': 'p'}",

    "{'name': 'hidden-note', 'title': 'PARA: Hidden note', 'expr': 'p[@class!=\"important\"]'}",



    "{'name': 'center', 'title': 'PARA: Center', 'expr': 'p'}",

])



WYM_STYLES = ",\n".join([

    "{'name': '.hidden-note', 'css': 'color: #999; border: 2px solid #ccc;'}",

    "{'name': '.date', 'css': 'background-color: #ff9; border: 2px solid #ee9;'}",



    "{'name': '.center', 'css': 'border: 2px solid #ee9; text-align:center;'}",

])


Приведенные WYM_STYLES определяют то, как контент будет выглядеть в редакторе. Менеджеры контента любят, когда он меняется динамически и WYSWYG оправдывает свое название.

И прописал стиль в css:


.center { text-align: center; }


Естественно, все это можно было сделать иначе…




28 дек. 2009 г.

Снипет для пользовательского контента в шаблонах

Очень простой и, наверняка, не слишком правильный способ вставлять html-хуки в шаблоны, содержимым которых может управлять пользователь:


# models.py:



class Snippet(models.Model):

    id          = models.AutoField(primary_key=True)

    title       = models.CharField(u'название', max_length=50)

    text        = models.TextField(u'текст', max_length=5000)

    template    = models.CharField(u'шаблон',   max_length=250, blank=True, null=True)

    def __unicode__(self): return u'%s (%s)'%(self.title, self.template)

    class Meta:

        verbose_name = u'снипет'

        verbose_name_plural = u'снипеты'



# tampletetags/realtor_tags.py:



@register.simple_tag

def get_snippet(title, **kwargs):

    from realtor.models import Snippet

    try:

        return Snippet.objects.get(title=title).text

    except:

        return u''

get_snippet.is_safe = True



# в шаблонах:



{% load realtor_tags %}



{% get_snippet 'realtor-top-left' %}


20 дек. 2009 г.

Django CMS – show_menu

UPD: Начиная с версии 2.1.0 beta загрузка меню тэгов происходит по новому (см. http://www.django-cms.org/news/2010/03/24/django-cms-210-beta-released/).

Сегодня попытаюсь рассказать о template tag’е show_menu в django-cms. Сам разбирался с ним методом научного тыка.

{% show_menu %}


Тэг генерирует меню навигации для текущей (выбранной, открытой) страницы.

Параметры

Show_menu принимает следующие необязательные параметры:
start_level - начальный уровень навигации,
end_level конечный уровень навигации,
extra_inactive – начальный уровень “дополнительной” навигации,
extra_active - конечный уровень “дополнительной” навигации
“Дополнительная” - это навигация по страницам, которые не являются прямыми потомками и предками текущей страницы.
Для этого тэга можно переопределить шаблон вывода, создав в шаблонах своего проекта свой шаблон cms/menu.html или передав в ещё один дополнительный параметр template. Пример:

{% show_menu 0 100 0 100 "my_new_cool_menu.html" %}


Играемся с уровнями навигации

Для тестирования работы тэга возьмем сайт-пример demo.concepter.ru, о котором я уже писал раньше. (UPD: сайта demo.concepter.ru больше нет). Итак, имеет исходное дерево сайта:
  • root 1
    • 1 level child (p, n)
      • 2 level child (p, n) of 1
      • 2 level child (p) of 1
    • 1 level child (p)
      • 2 level child (p, n) of 1 level child (p)
    • 1 level child
    • 1 level child (n)
  • root 2
    • 1 level child (p, n) of root 2
      • 2 level child (p, n) of 1 of root 2
    • 1 level child (p) of root 2
буквы в скобках – статусы. p – страница опубликована, n – “в навигации”.
На главной странице вызваны show_menu со следующими параметрами:

1. {% show_menu 0 100 100 100 %} - Вся навигация



2. {% show_menu 0 100 0 100 %} - Навигация по активному дереву



3. {% show_menu 0 100 0 1 %} - Навигация с одним дополнительным уровнем



4. {% show_menu 0 0 0 0 %} - Корневая навигация



5. {% show_menu 1 1 100 100 %} - Навигация первого уровня



6. {% show_menu 1 1 0 100 %} - Навигация по первому уровню (только активное дерево)



7. {% show_menu 0 1 100 100 %} - Навигация по перевому и второму уровню


Под активным деревом в данном случае понимаем дерево, в которое входит выбранная страница. Например, потомков root 1 активным деревом будет все, что ниже root 1 и root 1, включительно.

Независимые от активной страницы блоки навигации

Естественно, что вся навигация (1), корневая навигация (4), навигация первого уровня (5) и навигация 0-1 уровней (7) не будут меняться с изменением активной страницы (т.е. при переходе на новую страницу). Потому сразу покажу, как они выглядят для всех страниц:

Complete navigation

Level 0 navigation

Level 1 navigation

Level 0-1 navigation

Навигацию по активному дереву


{% show_menu 0 100 0 100 %}


Далее посмотрим какие страницы попадут в навигацию по активному дереву в зависимости от смены страницы.
1. root 1
2. root 2
Активное дерево развернуто, а не активное – нет. В навигации все страницы с параметрами страница “опубликована” и “в навигации”.

Навигация с одним дополнительным уровнем


{% show_menu 0 100 0 1 %}


1. root 1
2. root 2
3. 1 level child (p, n)
4. 1 level child (p, n) of root 2
В навигации есть все, что опубликовано и одновременно присутствует в навигации. Тэг честно вываливает 1 дополнительный уровень к текущей странице (потомки).

Навигация по первому уровню (только активное дерево)


{% show_menu 1 1 0 100 %}


Такой тип навигации можно использовать в паре с навигацией 0-го уровня для генерации двухуровневого меню на главной странице, как тут:
image
image
Естественно, там сделано не так, но для примера подойдет.
Далее пары “Активная страница” + содержимое навигации:
root 1 + 1 level child (p, n)
root 2 + 1 level child (p, n) of root 2
1 level child (p, n) + 1 level child (p, n)
2 level child (p, n) of 1 + 1 level child (p, n)
1 level child (p, n) of root 2 + 1 level child (p, n) of root 2
2 level child (p, n) of 1 of root 2 + 1 level child (p, n) of root 2
Очевидно, что в навигации данного типа меню присутствует первый уровень активного дерева. Как всегда, в неё попали только опубликованные страницы со статусом “в навигации”.

Резюме

С помощью данного тэга можно выстраивать навигацию любой сложности и вложенности, главное не запутаться в уровнях и активных деревьях.
Без параметров тэг инициализируется с 0 100 и 0 100, так что в некоторых случаях можно использовать просто {% show_menu %}.
Помимо show_menu в django-cms есть ещё show_menu_below_id, show_sub_menu и show_breadcrumb, использование которых может существенно сэкономить время и нервы. Хотя, какие там нервы? Django-cms – полнеищий fun.
Читайте все тоже самое, но на английском на странице http://www.django-cms.org/en/documentation/2.0/navigation/.