How to rename a file with file_column plugin.
Собственно, понадобилось… Время от времени изменять имя файла, загруженного с помощью file_column. Например так: stylesheet.css → stylesheet_1399194798.css.
Вот, что получилось.
Читать дальше »How to rename a file with file_column plugin.
Собственно, понадобилось… Время от времени изменять имя файла, загруженного с помощью file_column. Например так: stylesheet.css → stylesheet_1399194798.css.
Вот, что получилось.
Читать дальше »
Случается, что число чертей или других сущностей (и не обязательно – зловредных) переваливает далеко за 1000+. В моем случае это было количество товаров в тестовом приложении. Ровно 40305. Отобразить такое большое число на странице, не поломав при этом верстку, бывает довольно проблематично. Поэтому я сегодня добавил пару методов для сокращения размера оного.
В дополнение к уже имеющемуся, планирую приобрести, или получить в подарок ;) такую книгу. Пока в «вишлисте».

Ruby - относительно новый объектно-ориентированный язык, разработанный Юкихиро Мацумото в 1995 году и позаимствовавший некоторые особенности у языков LISP, Smalltalk, Perl, CLU и других. Язык активно развивается и применяется в самых разных областях: от системного администрирования до разработки сложных динамических сайтов. Книга является полноценным руководством по Ruby - ее можно использовать и как учебник, и как справочник, и как сборник ответов на вопросы типа "как сделать то или иное в Ruby". В ней приведено свыше 400 примеров, разбитых по различным аспектам программирования, и к которым автор дает обстоятельные комментарии.
Издание предназначено для программистов самого широкого круга и самой разной квалификации, желающих научиться качественно и профессионально работать на Ruby.
В руках уже держал, но приобрести на тот момент еще не решился. И подарить же, блин, не подарили.

Код ruby
simple_colors = {
:aliceblue => "f0f8ff",
:antiquewhite => "faebd7",
:aqua => "00ffff",
:aquamarine => "7fffd4",
:azure => "f0ffff",
:beige => "f5f5dc",
:bisque => "ffe4c4",
:black => "000000",
:blanchedalmond => "ffebcd",
:blue => "0000ff",
:blueviolet => "8a2be2",
:brown => "a52a2a",
:burlywood => "deb887",
:cadetblue => "5f9ea0",
:chartreuse => "7fff00",
:chocolate => "d2691e",
:coral => "ff7f50",
:cornflowerblue => "6495ed",
:cornsilk => "fff8dc",
:crimson => "dc143c",
:cyan => "00ffff",
:darkblue => "00008b",
:darkcyan => "008b8b",
:darkgoldenrod => "b8860b",
:darkgray => "a9a9a9",
:darkgreen => "006400",
:darkkhaki => "bdb76b",
:darkmagenta => "8b008b",
:darkolivegreen => "556b2f",
:darkorange => "ff8c00",
:darkorchid => "9932cc",
:darkred => "8b0000",
:darksalmon => "e9967a",
:darkseagreen => "8fbc8f",
:darkslateblue => "483d8b",
:darkslategray => "2f4f4f",
:darkturquoise => "00ced1",
:darkviolet => "9400d3",
:deeppink => "ff1493",
:deepskyblue => "00bfff",
:dimgray => "696969",
:dodgerblue => "1e90ff",
:feldspar => "d19275",
:firebrick => "b22222",
:floralwhite => "fffaf0",
:forestgreen => "228b22",
:fuchsia => "ff00ff",
:gainsboro => "dcdcdc",
:ghostwhite => "f8f8ff",
:gold => "ffd700",
:goldenrod => "daa520",
:gray => "808080",
:green => "008000",
:greenyellow => "adff2f",
:honeydew => "f0fff0",
:hotpink => "ff69b4",
:indianred => "cd5c5c",
:indigo => "4b0082",
:ivory => "fffff0",
:khaki => "f0e68c",
:lavender => "e6e6fa",
:lavenderblush => "fff0f5",
:lawngreen => "7cfc00",
:lemonchiffon => "fffacd",
:lightblue => "add8e6",
:lightcoral => "f08080",
:lightcyan => "e0ffff",
:lightgoldenrodyellow => "fafad2",
:lightgrey => "d3d3d3",
:lightgreen => "90ee90",
:lightpink => "ffb6c1",
:lightsalmon => "ffa07a",
:lightseagreen => "20b2aa",
:lightskyblue => "87cefa",
:lightslateblue => "8470ff",
:lightslategray => "778899",
:lightsteelblue => "b0c4de",
:lightyellow => "ffffe0",
:lime => "00ff00",
:limegreen => "32cd32",
:linen => "faf0e6",
:magenta => "ff00ff",
:maroon => "800000",
:mediumaquamarine => "66cdaa",
:mediumblue => "0000cd",
:mediumorchid => "ba55d3",
:mediumpurple => "9370d8",
:mediumseagreen => "3cb371",
:mediumslateblue => "7b68ee",
:mediumspringgreen => "00fa9a",
:mediumturquoise => "48d1cc",
:mediumvioletred => "c71585",
:midnightblue => "191970",
:mintcream => "f5fffa",
:mistyrose => "ffe4e1",
:moccasin => "ffe4b5",
:navajowhite => "ffdead",
:navy => "000080",
:oldlace => "fdf5e6",
:olive => "808000",
:olivedrab => "6b8e23",
:orange => "ffa500",
:orangered => "ff4500",
:orchid => "da70d6",
:palegoldenrod => "eee8aa",
:palegreen => "98fb98",
:paleturquoise => "afeeee",
:palevioletred => "d87093",
:papayawhip => "ffefd5",
:peachpuff => "ffdab9",
:peru => "cd853f",
:pink => "ffc0cb",
:plum => "dda0dd",
:powderblue => "b0e0e6",
:purple => "800080",
:red => "ff0000",
:rosybrown => "bc8f8f",
:royalblue => "4169e1",
:saddlebrown => "8b4513",
:salmon => "fa8072",
:sandybrown => "f4a460",
:seagreen => "2e8b57",
:seashell => "fff5ee",
:sienna => "a0522d",
:silver => "c0c0c0",
:skyblue => "87ceeb",
:slateblue => "6a5acd",
:slategray => "708090",
:snow => "fffafa",
:springgreen => "00ff7f",
:steelblue => "4682b4",
:tan => "d2b48c",
:teal => "008080",
:thistle => "d8bfd8",
:tomato => "ff6347",
:turquoise => "40e0d0",
:violet => "ee82ee",
:violetred => "d02090",
:wheat => "f5deb3",
:white => "ffffff",
:whitesmoke => "f5f5f5",
:yellow => "ffff00",
:yellowgreen => "9acd32"
}Код ruby: сортировка по насыщенности
ordered_colors = simple_colors.sort{|a,b| ( a[1][0,2].to_i(16)+a[1][2,2].to_i(16)+a[1][4,2].to_i(16) )<=>(b[1][0,2].to_i(16)+b[1][2,2].to_i(16)+b[1][4,2].to_i(16))}sort класса Hash возвращает массив (Array).Пример: hsh.sort -> anArray
h = { "a" => 20, "b" => 30, "c" => 10 }
h.sort » [["a", 20], ["b", 30], ["c", 10]].rhtml):<style type="text/css">
.colorPick {
width:16px; height:16px; float:left;
border:2px solid #FFF;
margin:1px;
}
</style>
<!-- ... -->
<%
ordered_colors.each do |color|
name = color[0]
value = color[1]
%>
<div class="colorPick"
style="background-color: #<%= value %>"
title="<%= name %>">
</div>
<% end %>

<FORM>) или remote-форма (AJAX). И не хочется в XSLT-шаблонах лишний раз нагружать юзера конструкциями вроде:<form onsubmit="new Ajax.Updater('paypal',
'/mystore/ajax_update_paypal',
{asynchronous:true, evalScripts:true,
onComplete:function(request){ajax_refresh_options()},
parameters:Form.serialize(this)});
return false;" method="post" action="/mystore/ajax_update_paypal">
<!-- Еще туева хуча полей -->
</form>Фрагмент .rxml
# Form:Buy Now
xml.tag!("form-buy_now") do
xml.action("/cart/add/#{@item.id}")
xml.name("add_to_cart")
xml.tag!("button-buynow"){
xml << ( link_to_remote image_tag("/images/buttons/button_buynow.png", :class => "button", :alt => "buy now"), :url => {:controller => "cart", :action => "ajax_check_item", :id => @item.id, :buynow => 1 } )
}
end
Фрагмент XSLT
<xsl:element name="form" >
<!-- form: attributes -->
<xsl:attribute name="action" >
<xsl:value-of select="action" />
</xsl:attribute>
<xsl:attribute name="name" >
<xsl:value-of select="name" />
</xsl:attribute>
<!-- form: fields -->
<xsl:copy-of select="button-buynow/*" />
</xsl:element>
Фрагмент .rxml
xml.tag!("store-search"){
#Form
xml.tag!( "form", :action => url_for({:controller=>"/search", :action=>"index"}), :name=>"searchform", :method => "get" ){
xml.tag!("search_by"){ xml << hidden_field_tag(:search_by_seller,1) }
xml.tag!("seller"){ xml << hidden_field_tag(:seller, @store.name) }
xml.tag!("submit"){
xml << image_submit_tag("/images/template/button_search.gif", {:alt => "search", :class => "imgbutton"})
}
}
#End: Form
}Фрагмент XSLT
<xsl:template match="store-search/form">
<xsl:element name="form">
<!-- form: attributes -->
<xsl:attribute name="action" >
<xsl:value-of select="@action" />
</xsl:attribute>
<xsl:attribute name="name" >
<xsl:value-of select="@name" />
</xsl:attribute>
<xsl:attribute name="method" >
<xsl:value-of select="@method" />
</xsl:attribute>
<!-- form: elements -->
<xsl:copy-of select="search_by/*" />
<xsl:copy-of select="seller/*" />
<table class="compact">
<tr><td align="center" height="30">
<input name="text" id="text" class="field" value="" type="text" />
</td></tr>
<tr><td align="center">
<xsl:copy-of select="submit/*" />
</td></tr>
</table>
</xsl:element>
</xsl:template>
cdata! или cdata_section. Более того, в CDATA можно включать и partials.Пример с cdata!
xml.cdata!("Этот текст не будет проанализирован XML-парсером")
#=> <![CDATA[Этот текст не будет проанализирован XML-парсером]]>Пример с cdata_section
cdata_section("<Это бля не тег!>")
# => <![CDATA[<Это бля не тег!>]]>Пример с partial
xml.cdata!(
render( :partial => "javascript" )
)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE member [
<!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
<!ENTITY b "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
<!ENTITY c "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
<!ENTITY d "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">
<!ENTITY e "&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;">
<!ENTITY f "&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;">
<!ENTITY g "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx">
]>
<member>
&a;
</member>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE body [
<!ENTITY reg "®">
<!ENTITY mdash "—">
<!ENTITY nbsp " ">
<!ENTITY ldquo "“">
<!ENTITY rdquo "”">
<!ENTITY pound "£">
<!ENTITY trade "™">
<!ENTITY euro "€">
<!ENTITY yen "¥">
<!ENTITY copy "©">
]>
...
xml.instruct! и как им пользоваться, я давно знаю, но вот с этими entities была и самая проблема.declare! а хули толку? Там настолько "содержательный" пример применения, что хотелось пристрелить разработчиков документации. Пришлось познать, что есть такое Class: Proc в Ruby.XML DOCTYPE ENTITY средствами ruby on rails (layout.rxml)
xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
entities = {:nbsp => " ", :copy => "©", :reg => "®", :trade => "™", :mdash => "—", :ldquo => "“",
:rdquo => "”", :pound => "£", :yen => "¥", :euro => "€"}
xml.declare! :DOCTYPE, "body".intern do |x|
entities.each do |key, value|
x.declare! :ENTITY, "#{key}".intern, "#{value}"
end
end
.rhtml в .rxml - документ (с последующим отображением его после XSL-трансформации), проделаем следующее:XML: фрагмент store.rxml
# partial
xml.tag!("store-description"){
xml << render( :partial => "store_description" )
}
XSLT: фрагмент store.xsl
<!-- # Render Partial -->Читать дальше »
<xsl:apply-templates select="//store-description" />
<xsl:template match="store-description">
<xsl:copy-of select="node()" />
</xsl:template>
<xsl:for-each>, но лично я предпочитаю использовать шаблоны. Т.е. связку<xsl:apply-templates> и <xsl:template match="">.@store с определенным набором товаров@items = @store.itemsФрагмент кода store.rxml:
# Store items
xml.tag!("items") do
@items.each do |item|
xml.tag!("item", :id => item.id) do
xml.tag! "item-name" do
xml << (link_to truncate(item.name, 20), :controller => "store", :action => "item", :id => item.id)
end
xml.tag! "item-description", truncate(item.description, 100)
xml.tag! "item-price", "#{item.currency}#{item.price}"
end
end # items.each
end
Это сгенерирует следующий XML:
<items>
<item id="13">
<item-name><a href="/customstore/item/13">Lucky Number</a></item-name>
<item-description>Navy lucky number 13</item-description>
<item-price>$12.00</item-price>
</item>
<item id="16">
<item-name><a href="/customstore/item/16">Leather ...</a></item-name>
<item-description>Leather is a material created through the tanning of hides and skins of animals</item-description>
<item-price>$17.00</item-price>
</item>
<item id="75">
<item-name><a href="/customstore/item/75">Adobe Photoshop ...</a></item-name>
<item-description>Lorem ipsum dolor sit amet, conse...</item-description>
<item-price>$23.00</item-price>
</item>
</items>
Применим следующие правила XSL-трансформации:
<xsl:apply-templates select="//items" />
<xsl:template match="items">
<xsl:apply-templates select="item" />
</xsl:template>
<xsl:template match="item">
<div class="item" id="item{@id}">
<h2><xsl:copy-of select="item-name/*" /></h2>
<p><xsl:value-of select="item-description" /></p>
<span class="price"><xsl:value-of select="item-price" /></span>
</div>
</xsl:template>
copy-of item-name ссылкой, используем вывод без родительского тега.
Читать дальше »
ruby-xslt.libxml <http://xmlsoft.org/> и libxslt <http://xmlsoft.org/XSLT/>ruby-xslt на Ubuntusudo apt-get install libxslt1-dev libxml-rubyЧитать дальше »
gem install ruby-xslt
В блоге охотно делюсь примерами как из собственного опыта веб-разработки, коей посвятил уже более 5 лет своей жизни, так и просто интересными находками.
Будь то программирование или верстка, дизайн или настройка шаблонов Blogger – мне интересно все. И так или иначе все это найдет отражение на страницах моего блога.