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

вторник, октября 03, 2006

Inline layouts

В Rails уже давно есть возможность брать контент экшена не из файла, а передовать его в строке. Таким образом легко сделать простой CMS: берем шаблон из базы и делаем render :inline => . Проблема же построения более менее пригодного CMS заключалась в том, что подобную операцию нельзя было провести с лэйаутами.

Недавно я написал маленький плагин - Nested layouts (http://nested-layouts.rubyforge.org). Я решил, что возможность использования inline лэйаутов будет полезной добавкой к нему.

<% inside_inline_layout @layout_template do %>
content
<% end %>

Так что, кому надо - берите, пользуйте, пишите впечатления.

понедельник, октября 02, 2006

IF/UNLESS блоки в RJS шаблонах

Недавние занятия программированием с Ajax в Rails привели к созданию патча для поддержки создания IF блоков в javascript'е. Основная идея (помимо условий в виде строк) - поддержка элемент-прокси:

page.if page['element_id'].visible do
page['element_id'].hide
end

Проблема в том, что page['element_id'].visible сгенерит код до того, как будет обернуто в IF блок.
Также можно использовать более традиционные методы:

page.unless "$('element_id').visible()" do
page['element_id'].show
end

Патч был отклонен в core, но было предложено сделать плангин для обкатки.

Собственно, вот и он: http://rubyforge.org/projects/js-if-blocks. Инсталировать можно так:

./script/plugin install svn://rubyforge.org/var/svn/js-if-blocks/trunk/js-if-blocks

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

element = page['element_id]
page.if element.visible do
element.hide
end

среда, сентября 13, 2006

Rails javascript generation and conditions

I've recently faced the problem: I need to generate javascript that would insert some HTML block unless it is already there. So, the code should be something like this:

if( !($('block_id')) ) {
// insert block
}

All that should go to RJS template.

First revision:

page << "if( !($('block_id')) ) {"
page.insert_html :before, 'container_id', 'my html'
page << "}"

Next, it would be nice to make use of JavaScriptProxy objects (that are spawn, e.g., by page#[] method). The problem is that HTML is emited when those proxy created or evaluated, thus it's not possible to wrap that javascript code into e.g. "if( ... )"..
Solution, first try:

class << page
def if(expr)
self << "if( #{expr} ) {"
yield if block_given?
self << "}"
end
end

page.if "$('#{element_id}').visible()" do
page[element_id].hide
end

This is better then the first one, but too ugly though. A better solution would include some black magick:

module AcitiveView
module Helpers
class JavaScriptProxy
def respond_to?(name)
return true if name.to_sym == :to_script
super
end

def to_script
@generator.instance_variable_get('@lines').pop.chomp(';')
end
end
end
end

Then:

class << page
def if(expr)
self << "if( #{expr.respond_to?(:to_script) ? expr.to_script : expr} ) {"
yield if block_given?
self << "}"
end
end

page.if(page[element_id].visible) do
...
end

And finally, the more peaceful variant:

module ApplicationHelper
def if_exists(page, element_id)
page << "if( !($('#{element_id}')) ) {"
yield if block_given?
page << "}"
end
end

if_exists page, 'block_id' do
page.insert_html .....
end