Wagtail CMS: хлебные крошки

В базовый или включаемый шаблон добавить подобный код:

{% load wagtailcore_tags %}

{% if self.get_ancestors|length > 1 %}
    <ul class="breadcrumb">
        {% for page in self.get_ancestors %}
            {% if not page.is_root %}
                <li><a href="{% pageurl page %}">{{ page.title }}</a></li>
            {% endif %}
        {% endfor %}
        <li>{{ self.title }}</li>
    </ul>
{% endif %}

npm: ошибка при установке пакетов в Vagrant

Во время выполнения команды npm install в расшаренной директории Vagrant (Windows хост, Ubuntu гостевая) происходит ошибка вида protocol error, symlink '../acorn/bin/acorn' -> '/vagrant/node_modules/.bin/acorn'. Эта распространенная проблема при работе с пакетными менеджерами в Vagrant под Windows и связана с некорректной работой симлинков при стандартном VirtualBox-ом механизме синхронизации папок между Windows хостом и Linux гостем. Решается либо сменой способа синхронизации, либо отказом от использования симлинков.

У npm к счастью есть опция отказа от симлинков:

npm install --no-bin-links

Добавляем поддержку Ruby синтаксиса в PhpStorm или PyCharm через TextMate Bundles

У меня в последние годы типична ситуация, когда в веб-проекте используется целая россыпь технологий. Как минимум, это какая-то из бекенд платформ — PHP, Python, Ruby и т.д. + JavaScript на фронте. Такой кейс отлично покрывается IDE от JetBrains — во всех из них поставляется полноценная поддержка JavaScript и других фронтенд технологий, соответствующая уровню WebStorm.

Но по факту, в дополнение к основному бекенд коду чаще имеем еще вспомогательные инструменты — сборка, деплой, виртуализация, оркестрация и т.д. Все эти системы также требуют конфигурирования или программирования и совсем не обязательно с использованием языка самого проекта. Самый распространенный пример — PHP или Python проект + Vagrant, у которого конфиг на Ruby. Ну а самый вырожденный случай в этом смысле — проект на моднейших микросервисах, в котором легко могут быть заюзаны 5 фреймворков на 3 языках.

Так вот в PhpStorm нет встроенной поддержки Ruby даже на уровне подсветки синтаксиса. Аналогично и с остальными IDE JetBrains — всегда поддерживается только одна бекенд технология. Остальные недоступны даже через репозитарий плагинов. Немного странно после использования текстовых редакторов типа Vim, Atom или ST, в которых всегда можно доустановить поддержку любого синтаксиса.

Понятно почему JetBrains так делают — им надо продавать лицензии. Хочешь полноценную поддержку еще одной технологии — плати. Есть даже All Products Pack предложение со скидкой.

Но если мне нужно поправить конфиг Вагранта, то мне совсем не нужна полноценная поддержка Ruby. И ДжетБрейнсы изящно выкрутились из этого противоречия, добавив поддержку плагинов для редактора TextMate — так называемых TextMate Bundles. Репозитария в IDE для них нет — бандлы нужно найти и скачать самому. Все без проблем ищется на гитхабе — называются обычно плагины %что-то%.tmbundle.

Пример бандла для Ruby. Качаем, распаковываем и добавляем в IDE через Settings — Editor — TextMate Bundles. Дополнительно может понадобиться указать сопоставление цветовых схем и перезагрузить среду.

Babun как терминал в PyCharm

Продолжаю осваивать Windows, как бы это забавно не звучало для веб-разработчика в 2K16. Захотелось, чтобы в качестве терминала в PyCharm запускался Babun, а не стандартный cmd.exe.

Делается так:

  • Нужно зайти в настройки Settings — Tools — Terminal.
  • Задать путь к bash.exe в директории установки Babun. По умолчанию C:\Users\YOUR-USER\.babun\cygwin\bin\bash.exe.

Снимок экрана (1)

Windows, Vagrant, Virtualenv — Protocol error

При попытке инициализировать виртуальное окружение в расшареной папке Вагранта под Виндоус получаю ошибку OSError: [Errno 71] Protocol error.

Лечится вызовом виртуаленв с опцией —always-copy.

virtualenv -p python3 env --always-copy

Ansible — установка MySQL 5.5 на CentOS 7

В CentOS 7 по умолчанию доступен для установки только форк MariaDB. Что лучше — Мария или оригинальный мускул в комьюнити редакции — мне в данной задаче не важно. Мне нужно собрать дев среду максимально близкую к продакшену. Для скачивания и установки MySQL Оракл предоставляет rpm мета-пакет, который можно найти тут.

Установить этот пакет в Ansible можно примерно так

- name: Add MySQL repo
yum: name=http://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm state=present

Проблема в том, что в этом пакете прописаны субрепозитории для версий 5.7, 5.6, 5.5 и по-умолчанию активирована 5.7, а мне нужна 5.5. Конфиг лежит в файле /etc/yum.repos.d/mysql-community.repo. Проверить какой именно репозиторий активирован можно так.

$ yum repolist enabled | grep mysql

Yum модуль в Ansible не предоставляет возможности управления субрепозиториями. Но конфиг репозитория — это ini файл. А для работы ini файлами в Ansible модуль есть. Делаем так

- name: Disable default/latest MySQL repository
ini_file:
  dest: /etc/yum.repos.d/mysql-community.repo
  section: "mysql57-community"
  option: enabled
  value: "0"

- name: Enable target MySQL repository
ini_file:
  dest: /etc/yum.repos.d/mysql-community.repo
  section: "mysql55-community"
  option: enabled
  value: "1"

После этого уже можно установить MySQL

- name: Install MySQL
yum: name={{ item }} update_cache={{ update_yum_cache }} state=installed
with_items:
  - mysql
  - mysql-server

Vagrant — не обновляются файлы в расшаренной папке

Сетап такой: Windows 7 на хост машине и CentOS 7 на гостевой машине. Вагрант при таком сочетании выбрал механизм синхронизации расшаренных папок rsync (можно увидеть при старте виртуальной машины). Отлично, но rsync не умеет отслеживать изменения в файлах в реальном времени, только по явной команде. Эта команда Вагрантом вызывается только при старте или перезагрузке машины — vagrant up или vagrant reload соответственно.

Вручную можно вызвать так.

vagrant rsync

Или можно заставить rsync все-таки отслеживать изменения файлов, но тогда придется оставить процесс запущенным в терминале на все время работы с виртуальной машиной

vagrant rsync-auto

Подробности можно найти в блоге Вагранта.

Django: GenericForeignKey — ограничить выбор типов

Django позволяет создавать очень гибкие связи между моделями посредством встроенного приложения contenttypes. Эта функциональность является надстройкой над иерархией приложение-модель и позволяет создавать связь модели с другими моделям разного типа.

Реализуется так:

class MyModel(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')
    ...

По сути такая схема создает ключ из двух полей — тип модели и ID объекта этого типа.

А вот так можно ограничить возможность выбора типа модели:

class MyModel(models.Model):
    limit = models.Q(app_label='app1', model='model1') | models.Q(app_label='app2', model='model2')
    content_type = models.ForeignKey(ContentType, limit_choices_to=limit)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')
    ...

Внимание! Аргументом model конструктора объекта Q должно быть имя модели, приведенное к нижнему регистру, т.е. ‘somemodel’ для модели SomeModel, соответственно.