С запуска текущей версии сайта радио было 3 попытки переделать движок. Первую я уже толком и не помню, там изменения больше касались дизайна. В итоге красивый дизайн было нечем забивать (там предполагалось больше контентных блоков, а копирайтера у нас не было и нету) и на него забили. Второй вариант был на джанге. Я повторил на джанге свой старый движок, на на котором работает где-то по миру десятка два сайтов. В итоге меня самого это заебало и я снова забил. Третья попытка началась вчера, когда я окончательно понял, что фиксить поломанный RSS на старом сайте не поднимется рука, а модные фишки, использующиеся в движке этого блога, можно заюзать и на сайте радио. В итоге, к исходу шаббата второго дня кодирования, у меня есть практически весь функционал старого сайта, плюс моднявые фишки типа аттачей к новостям с рендерингом их же в тексте поста.

Но важно не это, важно другое - делать третью версию сайта - сплошное удовольствие. Те же аттачи к новостям делались через три пизды крайне неудобно в оригинальной джанге (моделька для новостей, моделька для аттачей, файлы на диске с именами типа image________.jpg) и крайне красиво и удобно с использованием кауча - выдернул картинку, аттачнул к документу - счастье есть.

Календарик для новостей - непрерывный оргазм. Зацените вот:

CouchDB-view, помогающая строить архив:

function(doc) {
  if (doc.type == 'news') {
    emit([doc.date.slice(0, 4), doc.date.slice(5, 7), doc.date.slice(8, 10)], doc.title);
  }
}

Фрагмент urls.py:

    url(r'^radio/archive/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/(?P<slug>.*)/', 'main.views.article'),
    url(r'^radio/archive/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/', 'main.views.article'),
    url(r'^radio/archive/(?P<year>\d{4})/(?P<month>\d{2})/', 'main.views.article'),
    url(r'^radio/archive/(?P<year>\d{4})/', 'main.views.article'),
    url(r'^radio/archive/', 'main.views.article'),

Django-view, отвечающая за календарик

@render_to()
def article(request, year = None, month = None, day = None, slug = None):

    startkey = {}
    endkey = None
    
    if year:
        if month:
            if day:
                if slug:
                    doc = request.db['news_%s-%s-%s_%s' % (year, month, day, slug)]
                    return {'TEMPLATE': 'main/archive/entry.html', 'entry': doc}
                else:
                    startkey = [year, month, day]
                    endkey = startkey
            else:
                startkey = [year, month, {}]
                endkey = [year, month]
        else:
            startkey = [year, {}]
            endkey = [year]
            
    entries = request.db.view('news/archive', startkey = startkey, endkey = endkey, descending = True)
    
    return {'TEMPLATE': 'main/archive.html', 'entries': entries}

Шаблон main/archive.html

<ul>
{%for entry in entries %}
{% ifchanged %}</ul><h3><a href="/radio/archive/{{ entry.key.0 }}/">{{ entry.key.0 }}</a></h3><ul>{% endifchanged %}
{% ifchanged %}</ul><h4><a href="/radio/archive/{{ entry.key.0 }}/{{ entry.key.1 }}/">{{ entry.key.1|month_textual }}</a></h4><ul>{% endifchanged %}
    <li><span class="date"><a href="/radio/archive/{{ entry.key.0 }}/{{ entry.key.1 }}/{{ entry.key.2 }}/">{{ entry.key.2 }}/{{ entry.key.1 }}/{{ entry.key.0 }}</a></span> - <span class="title"><a href="/radio/archive/{{ entry.id|permalink }}/">{{ entry.value }}</a></span></li>
{% endfor %}
</ul>

В php-версии кода было в стопиццот раз больше, он был кривой и страшный и работал не полностью. Тут же всё чисто и прозрачно, кода - с гулькин нос, а выборки из базы - найтривиальнейшие.