Irwi - Wiki в Rails-приложениях

Сегодня я хочу представить свой Rails-плагин, позволяющий добавить в приложение функциональность вики (не просто расширение моделей, а полноценную вики которая бы сразу работала)

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

Основными критериями при разработке были:

  • Возможность быстрой интеграции в приложение.
  • Хорошая расширяемость.
  • Отсутствие чужого кода (в смысле кода плагина) в приложении, к чему часто приводит использование генераторов. В этом смысле я пытался равняться на Authlogic.

То, что получилось представляет из себя что-то среднее между генератором (что обеспечивает хорошую расширяемость и модифицируемость) и engine'ом (чтобы можно было легко обновлять его).

Установка и использование

Для работы плагина (в частности истории страниц) необходимо наличие гема diff-lcs. Для форматирования по умолчанию используется RedCloth, однако можно выбрать и другой форматтер. Таким образом:


gem install diff-lcs RedCloth

Для установки плагина достаточно выполнить в директории Rails-приложения:


script/plugin install git://github.com/alno/irwi

После установки необходимо сгенерировать миграцию, моделиь и контроллер... Стойте, это вовсе не значит, что у вас в приложении появится куча чужого кода, который непонятно как поддерживать! Контроллер и модель содержат всего по одной строке вида acts_as_* и генерируется для того, чтобы в последствии Вам было бы проще расширять функциональность. Вся собственная функциональность вики реализуется в файлах плагина, что позволяет безболезненно обновлять ее.

Итак, чтобы сгенерировать необходимые файлы необходимо вызвать соответсвующий генератор:


script/generate irwi_wiki

После вызова генератора в приложение будут произведены следующие изменения:

  • Добавлен WikiPageController и соответствующий хелпер для обработки страниц
  • Добавлены модели WikiPage и WikiPageVersion для представления страниц
  • Будет сгенерирована миграция, создающая таблицы в БД

Также в роуты будет добавлена следующая строка:


  map.wiki_root '/wiki'

Как несложно догадаться, в ней указывается корень wiki в вашем приложении. Вы можете легко его изменить на тот, который Вам больше нравится.

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

Изменение внешнего вида

Изменение внешнего вида можно производить двумя путями:

  • Замена шаблонов
  • Замена стилей в дефолтных шаблонах

Для замены какого-то шаблона (включая partial'ы) необходимо определить шаблон с соответствующим именем в директории видов для вашего контроллера. Ничего необычного, правда? Если вы не знаете, что же туда писать, можете посмотреть на дефолтные шаблоны в исходниках плагина (они там в app/views), благо они крайне простые.

Скорее всего, вы будете применять первый способ, но о первом все же стоит упомянуть. По умолчанию в каждый дефолтный шаблон добавляется CSS с описанием дефолтного стиля. Наверное, вам захочется его выкинуть (и подключить свой собственный в layout'е). Для этого достаточно переопределить в хелпере метод wiki_page_style своим, который возвращает пустую строку. Таким образом вы просто уберете стили из страниц.

Привязка к пользователям

Что необходимо для того, чтобы привязать вики к существующей системе пользователей в приложении?

Самый простой случай, если модель вашего пользователя называется User и у вас в контроллере определен метод current_user, который возвращает текущего пользователя. Согласитесь, это достаточно распространенный случай. В этом случае вики автоматически привяжется к пользователям и считать текущего пользователя автором изменений.

Единственная проблема - на всех страницах имя пользователя будет отображаться как-нибудь вроде User123. Наверное, это все-таки не то, что вы хотите. Чтобы исправить эту ситуацию достаточно определить метод wiki_user в классе WikiPagesHelper. Например, следующим образом:


module WikiPagesHelper
  include Irwi::Helpers::WikiPagesHelper

  def wiki_user( user )
    user ? link_to( user.login, user_path( user ) ) : "Guest"
  end

end

Если же ваша модель называется как-то по-другому, придется добавить еще одну строчку при инициализации приложения:


Irwi.config.user_class_name = 'Account' # Разумеется, если ваша модель называется именно так

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

Ограничение прав на выполнение операций

Скорее всего, Вам захочется добавить ограничение прав на просмотр или редактирование страниц вики (вообще говоря, я считаю, что это весьма неплохая идея). Например, как минимум, дать права на редактирование только зарегистрированным пользователям.

Для этого необходимо всего-навсего переопределить в контроллере три метода, осуществляющие проверку прав: show_allowed?, history_allowed? и edit_allowed?. В каждом из методов необходимо проверить имеет ли текущий пользователь права на совершение действия (просмотр, просмотр истории, редактирование) с текущей страницей (@page) и соответственно вернуть что-то, что расценивается как исттина или как ложь. В случае, если соответствующий метод возвращает ложь, то действие не совершается и в контроллере вызывается метод not_allowed, который по умолчанию рендерит текст об ошибке, но скорее всего вам захочется переопределить и его (например, чтобы редиректить пользователя на страницу логина).

Таким образом, примерный код контроллера может выглядеть следующим образом:


class WikiPagesController < ApplicationController
  
  acts_as_wiki_pages_controller
  
  def show_allowed?
    true # Показывать всем
  end
  
  def history_allowed?
    true # И историю пусть все смотрят
  end
  
  def edit_allowed?
    current_user # А редактируют только те, кто залогинены
  end
  
  def not_allowed
    redirect_to login_path # Всех нарушителей редиректим на страницу логина
  end
  
end

Итого

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

 Подписаться на RSS

 #  #  #  #  #  #  #  #  #  #

Добавить комментарий