Не секрет, что в разработке Django-приложений нет ничего особенного. Точнее, не требуется ничего лишнего. Django - это Python. Значит, нужен текстовый редактор и консоль. И конечно же браузер - но это уже для тестирования. Но для того, чтобы писать было удобно, нужно IDE. Или продвинутый редактор. Emacs - очень продвинутый редактор ;)

Вот так выглядит мой Emacs - ничего лишнего, все нужное. Проверка синтаксиса делается с помощью Flymake + pyflakes (или pylint, pychecker), но не это главное. То, о чем я хочу рассказать - это сниппеты. Как? Легко.

Yasnippet - это оно. Ставить надо полную версию, а не bundle, который в одном файле. Но там же нету сниппетов для Django! Не вопрос - я все сделал. bzr branch lp:django-mode, читаем README, делаем и наслаждаемся. В комплекте еще режим для шаблонов и функции для вставки i18n тегов (C-c C-t в питоновом коде "_(%выделенное%)", в html-шаблонах "{% trans "%выделенное%" %}").

А можно еще скачать мой конфиг (Yasnippet в комплекте же). Короче, чтобы меньше всего париться и получить готовый IDE:

sudo port install tidy # или apt-get, если на Debian/Ubuntu. У меня OS X ;)
sudo pip install pyflakes # easy_install - уныл, но тоже работает
cd ~/Dropbox
bzr branch lp:django-mode
bzr branch lp:~lol2fast4u/+junk/emacs-dir emacs
echo "(add-to-list 'load-path \"~/Dropbox/emacs\") (load-file \"~/Dropbox/emacs/config.el\")" > ~/.emacs

Первую команду, кстати, можно пропустить.

2010-02-11 21:57:45 Теги: django python apps emacs | Комментарии

Допустим, нам нужно использовать один скрипт для нескольких страниц (а это делать нужно, ибо экономия HTTP-запросов. по поводу того, что "качать только что надо сейчас" - ну все равно же кеш). Как определить разные действия в зависимости он страниц?

Да очень просто.

html:
<head> ... <meta name="internal" content="mainpage" /> </head>
js: $(window).load(function (){ ... window.rel = $('meta[name=internal]').attr('content'); }); а теперь в зависимости от этой переменной делаем то, что надо. Например:
if (window.rel == 'mainpage') {
     $('#sidebar').removeClass('noJs').slideDown();
}
else if (window.rel == 'comments') {
     $('.comment').addClass('js');
}

Но самая фишка в том, что умеют шаблоны Django ;) в index.djhtml:

<head>
     ...
     <meta name="internal" content="{% block pagerel %}unknown{% endblock %}" /> {# For Javascripts, etc. #}
</head>

И в наследующих шаблонах ставим все как надо. Например, post.djhtml: {% block pagerel %}blogpost{% endblock %}

Вот и все!
Постовой: Доставка - купить недвижимость в центре москвы свежие комментарии, только на этом сайте подарки 8 марта лучшее у нас, дизель генераторы wilson оценки, справки специалистов.
2010-02-09 17:32:45 Теги: django javascript | Комментарии

Git - одна из самых известных распределенных систем контроля версий (DVCS), изначально созданная для разработчиков ядра Linux. Из-за последнего, она работает на патчах. Патчи, патчи, везде патчи.

В централизованных VCS каждый contributor (как бы перевести нормально??) присылал патч одному из committer'ов, который применял его вручную. Git создавался для облегчения всего этого.

А DVCS создавались для борьбы с патчами. Именно так, да. Любой пользователь создает свою ветку или форк, работает в ней как хочет, а когда все готово - создает merge directive (или pull request), то есть просит объединить ветки. Скажете, что в Git/GitHub так можно? Да, через жопу, но можно, но пользователи Git все равно патчи патчат.

Но самое главное, что бесит в Git - он работает только по одной модели (shared working tree, "общее рабочее дерево"). То есть в папке есть одно рабочее дерево и можно переключаться между ветками командой switch. Такая модель использования придает скорости и занимает меньше места на диске. Но в то же время она абсолютно неудобна в использовании. Вывод? Только для больших проектов.

В Mercurial то же самое, но слегка проще. А вот в Bazaar такой способ работы сильно опционален. rebase - вообще плагин (: Directory is a branch - это очень правильная идеология. Потому что с ее помощью можно сделать то же shared WT, только каждую ветку можно будет просто посмотреть файловым менеджером (не залезая в .скрытые_папки), а можно работать с простыми ветками, если проект небольшой. Вот так вот.

Постовой: разработка фирменного стиля; выделенный сервер в аренду - для больших нагрузок, когда VDS не хватает.
2010-02-08 15:52:12 Теги: python apps vcs | Комментарии

С новым годом, который уже два дня как наступил. Вы все уже начитались этих поздравлений в своих Google Reader'ах и прочих читалках, да и вообще везде. Но не смотря на название, псот совсем о другом.

PyMarkup - это python-модуль для создания разметки. Делается он не столько для простоты, сколько для интеграции с приложением. шаблоны больше не нужны ;)

Идея давно уже лежала в моем Evernote (пользуясь случаем, поздравляю их с 2 миллионами пользователей!), но вот только недавно я взялся за реализацию. Пока оно умеет блоки, картинки и ссылки в виде Python'овых объектов преобразовывать в XHTML... Короче, скоро будет больше и все такое. Документация тоже будет, да.

bzr branch lp:pymarkup && cd pymarkup && sudo python setup.py install

А теперь напишем скрипт, например 1.py:

import pymarkup as p
spam = [p.e.Text('Welcome to TestSite.'),
        p.e.Image('/logo.png', 'logo', id='logo')]
spam.append(p.e.Block(id='wrapper'))
spam.append(p.e.Snippet('<p>This is a test!</p>', parent='wrapper'))
eggs = [p.e.Title('Test')]
print p.Markup(spam, eggs).render('xhtml')
И запустим:
<?xml version="1.0" ?>
<!DOCTYPE html
  PUBLIC '-//W3C//DTD XHTML 1.1//EN'
  'http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd'>
<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>
            Test
        </title>
    </head>
    <body>
        Welcome to TestSite.
        <img alt="logo" id="logo" src="/logo.png"/>
        <div id="wrapper">
            <p>This is a test!</p>
        </div>
    </body>
</html>
Неплохо, да? А скоро будет еще больше, впрочем я это уже написал выше. UPD: теперь уже намного больше умеет. До полного XHTML чуть-чуть осталось ;)
2010-01-02 22:52:31 Теги: beta services django python apps | Комментарии
включи картинки а то жопа будет

Python'ист, Ruby'тель, Perl'овик! Ретвитни, добавь в закладки, поделись на фейсбуке, короче сделай эту картинку популярной!

2009-12-02 00:08:31 Теги: apps hosting fun | Комментарии
...вместо Flash (:

Я считаю, что флеша не должно быть везде и много. В интернете на нем должны быть только загрузчики файлов. Flash надо использовать по назначению - для создания сложных мультфильмов. Веб-приложения вполне могут обойтись без флеш-элементов..

Но как быть с играми? Да, при знании jQuery (а он намного проще ActionScript!!) можно сделать простую игру ;)

Пример - сборка АК, подсказал один товарищ. Надо не так много: средство против лени, фото разобранного автомата (идите в гугл!), графический и текстовый редакторы, нормальный браузер (Safari, Chrome или Firefox).

Я не буду подробно расписывать каждую строчку - скажу лишь, что с помощью jQueryUI мы придаем деталям draggable и создаем цели, куда они droppable. Тут сильно не доделано все - можно деталь поместить не в то место и отображается все это только в консоли. Доработаете и сделаете таймер - будет вам игра :)

<!DOCTYPE HTML>
<html><head><title>AK Game</title>
<script src="http://myfreeweb.ru/media/mfwjs/jquery.1.3.2.min.js" type="application/x-javascript"></script>
<script src="http://myfreeweb.ru/media/mfwjs/jquery-ui-1.7.2.custom.min.js" type="application/x-javascript"></script>
<script type="text/javascript">
$(document).ready(function(){
$('.piece').draggable({ cursor: 'crosshair' });
$('#t_2').droppable({ drop: function(event, ui){
console.log('dropped to 2'); } });
$('#t_3').droppable({ drop: function(event, ui){
console.log('dropped to 3'); } });
$('#t_4').droppable({ drop: function(event, ui){
console.log('dropped to 4'); } });
});
</script>
<style type="text/css">
.target { position: absolute; }
#t_2 { margin: 55px 0px 0px 215px; width: 120px; height: 150px; }
#t_3 { margin: 10px 0px 0px 277px; width: 177px; height: 22px; }
#t_4 { margin: 5px 0px 0px 100px; width: 128px; height: 32px; }
</style></head>
<body>
<div id="ak">
  <div class="target" id="t_2"></div><div class="target" id="t_3"></div><div class="target" id="t_4"></div>
  <img src="1.png" alt="включи картинки!"/>
</div>
<img src="2.png" id="2" class="piece" alt="включи картинки!"/>
<img src="3.png" id="3" class="piece" alt="включи картинки!"/>
<img src="4.png" id="4" class="piece" alt="включи картинки!"/>
</body></html>
СКАЧАТЬ демо (картинки + код выше)
2009-11-30 20:32:47 Теги: test web20 apps javascript markup | Комментарии

Все вебмастера знают о том, как прятать целые страницы от поисковых роботов (robots.txt, meta-теги). Но далеко не все догадываются, что можно запрещать индексирование текста/анкора/добавление в сниппет определенной части страницы.

Это очень полезно, если в сниппеты попадают информационные ссылки и всякие копилефты из подвала, а еще... если индексируется пример статьи, который каждый раз разный (юзер кликает, а там такого нет). Примеры из личного опыта ;)

Итак, все просто для Google. У остальных вряд ли есть что-то подобное.

Это индексируется.
<!-- googleoff: %s -->
Это не индексируется/попадает в сниппет.
<!-- googleon: %s -->
Это тоже индексируется.

где %s - index, anchor, snippet или all. Смотря что нужно отключить.
Например:

ПОРОЛЬ ОТ АСЬКИ ВСЕХ И ОТ МЫЛА: <!--googleoff: snippet-->123456<!--googleon: snippet-->
- тут все понятно, да? Сам пароль не попадает в сниппет - пользователь интересуется, заходит, видит тысячи попандеров, кликает.

Официальная документация - здесь.

Постовой: программирование и дизайн, новости.
Национальная экономика
2009-11-26 22:03:19 Теги: web20 google markup | Комментарии

Меня тут свои люди из хостинговой компании просили отговорить покупать Virtuozzo (: Отговорил.

Я знал о том, что есть свободные альтернативы, но особо не изучал. Оказывается, OpenVZ и тот самый Virtuozzo используют одно и то же ядро системы, а что это значит - догадаться не сложно. Свободы-то и нету! VDS покупается ради того, чтобы делать все, что угодно. Хоть ставить модули ядра.

Гугл и прочие умные сайты привели меня к Xen - самой правильной технологии виртуализации. Не смотря на то, что российские (да и не только) хостинг-провайдеры пока в основном продают VPS на одном ядре (как OpenVZ), все-таки бывает правильный vps хостинг.

Xen работает как обычная виртуальная машина типа всеми любимого VirtualBox, но задействует все серверное железо, а значит, что это лучший вариант для Virtual Dedicated Server. Причем такие виртуальные сервера стоят не дороже OpenVZ'шных. На Xen можно поставить хоть DOS - интересно, под него реально собрать nginx? :)

Технически это устроено не так сложно. В Xen используется паравиртуализация. Это подход, означающий предоставление виртуальным машинам програмный интерфейс, похожий на существующее железо сервера. Запускается на Linux и других Unix-подобных ОС, но запускаться в нем может даже обычный Windows - с помощью аппаратных технологий вроде Intel VT. Короче, это то, что нужно.

Хватит извращаться с установкой Django на общественный хостинг (кстати, вот так работает этот сайт) - покупайте VDS!

2009-11-21 19:11:08 Теги: test web20 hosting | Комментарии

Microsoft выпустил Marketplace для WM 6.0 и 6.1. Я думал, что они действительно исправились и все круто, но нет. Установка этой штуки состоит из кучи лишних нажатий и вообще, им религия мешает ставить его сразу. По ссылке "скачать Marketplace" скачивается... программа для скачивания Marketplace!

Включи картинки
Постовой: приворот
2009-11-18 20:40:35 Теги: test apps winmobile | Комментарии

Slug - короткое название статьи.

У Django есть нужные средства. Но стоит ли нагружать сервер? Да ладно, нагрузки там почти никакой, но удобно ли? Иногда хочется исправить то, что сделано автоматически.

В общем, лучше генерировать на лету с помощью syncTranslit. Наша задача - встроить это в админку Django. На первый взгляд кажется сложным - там же кучи шаблонов и видов, не разберешься в них... Стоп, а подумать?

Оказалось довольно просто: в change_form.html надо заменить

{% if adminform and add %}
<script type="text/javascript">
document.getElementById("{{ adminform.first_field.auto_id }}").focus();
</script>
{% endif %}

на

{% if adminform and add %}
   <script type="application/x-javascript"
     src="http://myfreeweb.ru/media/mfwjs/jquery.1.3.2.min.js"></script>
   <script type="application/x-javascript"
    src="http://myfreeweb.ru/media/mfwjs/jquery.synctranslit.min.js"></script>
   <script type="text/javascript">
    document.getElementById("{{ adminform.first_field.auto_id }}").focus();
    $(document).ready(function () {
    if ($('#id_slug') && $('#id_name')) {
    $('#id_name').syncTranslit({destination: 'id_slug', urlSeparator: '_'});
    }
    });</script>
{% endif %}

И все хорошо :) Конечно, если поля называются не name и slug (самые очевидные названия), то надо поменять их.

2009-11-13 17:34:38 Теги: web20 django javascript | Комментарии