Archív pro rubriku “Programování”

Průhlednost je cool, stejně jako zaoblené rohy, obrovské Web 2.0 písmo, AJAX a vše další. Pokud vám nic z toho cool nepřijde a za ideální stránku považujete takovou, která vypadá stejně ve Firefoxu nebo v Lynxu, tak nečtěte dál – Lynx průhlednost neumí. Čistě teoreticky není na průhlednosti nic zvláštního, CSS zná vlastnost opacity, kde 1=> úplně viditelný a 0 => úplně transparentní (pozor, že tuto vlastnost nezná třeba Opera 8). IE zná pro změnu filtr alpha, kde udáváte to samé, jenom v procentech a obráceně, tedy 0 => úplně viditelný, 100 => úplně transparentní  (tohle je samozřejmě nesmysl, obráceně to není). Takže úplně základní příklad 50% průhlednosti průhlednosti dostanete takto:

<p id="opaque">Lorem Ipsum</p>
#opaque {
   background-color: #FF3300;
   opacity: .5;
   /* použito kvůli kompatibilitě se staršími verzemi Firefoxu a Mozilly */
   -moz-opacity: .5;
   filter:alpha(opacity=50);
}

Výsledek:

Lorem ipsum dolor sit amet, consectetuer adipiscing elit.

Takto definovaná průhlednost má ale jednu zásadní vadu – dědí se na všechny podřízené prvky. Takže pokud budete chtít mít průhledné pozadí a hezky čitelný text, tak máte smůlu, nejde to. Nepomůže nastavit podřízený prvek zpět na úplně viditelný, přidat !important (klidně i se spoustou dalších vykřičníků), nepomůže nic.

Řešením je přidat do kódu jeden nesémantický prvek a trochu si pohrát s pozicováním prvků. Řekněme, že má jít o jednu položka menu (tohle řešení jde ale samozřejmě použít pro i cokoliv jiného), text bude tedy obalen tagem <a>. Před něj přidáme jeden prázdný div, který bude plnit funkci pozadí a bude mít nastavenou průhlednost. Z něj se logicky na odkaz průhlednost nezdědí, protože odkaz není jeho podřízený prvek. Zbývá už jenom vyřešit překrytí obou prvků. Jako první mě napadlo absolutní pozicování uvnitř relativně pozicovaného prvku (více například u Pixyho), kdy nadřazenému prvku nastavíme position: relative a rozměry. Podřízené prvky (prázdný <div> a odkaz) jsou potom absolutně pozicované na levý horní roh a mají stejnou výšku a šířku jako rodičovský prvek.

Výsledný dokument včetně ukázky pro 0%, 25%, 50% a 75% průhlednost jak na celém bloku včetně textu, tak jenom na pozadí si můžete prohlédnout zde (otevře se v novém okně). Postup funguje ve všech moderních prohlížečích – vyzkoušel jsem IE5.5, IE6 a IE7, Firefox 2 (měl by ale fungovat i pro starší verze), Operu 9 a Safari 3.

Comments 6 Komentářů »

Sitepoint nabízí zdarma ke stažení knihu „Build Your Own Ruby on Rails Web Applications“ na adrese http://rails.sitepoint.com. Nabídka platí po dobu 60 dnů (z nichž 18 už uplynulo, než mě napadlo o tom napsat), pouze zadáte svůj mail a obratem vám přijde odkaz ke stažení. Knížka mi přišla kvalitní, ne tak rozsáhlá jako Agile Web Development with Rails 2nd edition, ale pro začátečníky v Ruby on Rails rozhodně použitelná (trochu více se o tom rozepsal Jamis Buck na svém blogu).

Comments Bez komentářů »

Pokud používáte Ruby on Rails, tak téměř určitě je máte nainstalované z RubyGems – balíčkovacího systému pro Ruby, který umožňuje jednoduchou a pohodlnou instalaci aplikací nebo knihoven. Při postupných updatech gemů se vám může stát, že za chvilku máte od některých hromadu verzí (u Rails se mi to stává běžně). Pokud starší verze nepotřebujete, například kvůli zpětné kompatibilitě, tak se jich můžete rychle zbavit příkazem cleanup:

gem cleanup

Comments Bez komentářů »

Rails obsahují už delší dobu podporu pro stránkování pomocí klasického

@foo_pages, @foo = paginate(:foo, :order => 'bar' )

Problém je, že jde o trochu podivný zápis, vestavěné stránkování je nedoporučované kvůli mizernému výkonu a navíc ve verzi 2.0 bude kompletně odstraněno. Jedna možnost jak ho nahradit je napsat si vlastní, druhá využít skvěle fungujícího ekosystému pluginů. Já jako typický Rails programátor (tedy líný a nesnášející psaní rutinních věcí) jsem sáhl po druhé možnosti. Google po chvilce hledání odhalil skvělý plugin will_paginate. Proč je tak skvělý? Je jednoduchý na používání a dělá přesně co je potřeba.

Instalace klasicky v adresáři vaší aplikace:

ruby script/plugin install svn://errtheblog.com/svn/plugins/will_paginate

Samotné použití je jednoduché – prostě nahradíte volání find() objektu ActiveRecord za volání paginate a předáte mu parametr :page => params[:page], například takhle:

@foos = Foo.paginate(:all, :page => params[:page])

Výchozí počet záznamů na stránku je 15, změnit to můžete buď při volání paginate pomocí parametru :per_page nebo globálně pro určitý model přidáním metody per_page:

class Foo < ActiveRecord::Base
    def self.per_page
        50
    end
    ...
end

Kromě toho samozřejmě můžete používat všechny ostatní parametry známé z find. will_paginate vám poskytne i užitečný helper pro přepínání stránek, který přidáte do view takto:

<%= will_paginate @foos %>

Vzhled helperu můžete kompletně změnit pomocí CSS a autoři pamatovali i na možnost změnit anglické Previous a Next bez potřeby předefinování helperu. Do config/environment.rb jenom přidejte:

WillPaginate::ViewHelpers.pagination_options[:prev_label] = '&laquo; Předchozí'
WillPaginate::ViewHelpers.pagination_options[:next_label] = 'Další &raquo;'

To je vše a můžete vesele stránkovat.

Comments Bez komentářů »

Pokud generujete URL v odesílaných e-mailech, tak logicky potřebujete, aby byly absolutní. Na druhou stranu psát absolutní URL do kódu je nepohodlné kvůli testování. Samozřejmě je možný výsledný URL zkopírovat do prohlížeče a tam ručně změnit adresu, ale to zkrátka není ono. Řešením je nastavit výchozí parametry pro volání url_for.

V ActionMaileru nejsou potřebné proměnné k dispozici, takže je musíte předat při vytváření e-mailu:

class FooController < ApplicationController
	def send_email
		url_options = {:host => request.host, :protocol => request.protocol.gsub('://', '')}
		url_options[:port] = request.port unless [80, 443].include?(request.port)
		mail = FooMailer.create_bar(url_options)
		...
	end
end

Tělo ActionMaileru potom vypadá takto:

class FooMailer < ActionMailer::Base
	include ActionController::UrlWriter
	def bar(url_options)
		...
		default_url_options.merge!(url_options)
	end
end

V šabloně e-mailu potom můžete normálně používat url_for s parametrem :o nly_path => false. Stejně tak musíte vždy explicitně definovat kontroler, neplatí že by byl použitý kontroler, ze kterého bylo voláno vytvoření e-mailu:

<%= link_to('click here',  url_for(:only_path => false, :controller => 'foo', :action => 'index')) %>

Comments Bez komentářů »

Tohle je další věc, která nefunguje out-of-box. Pokud zkusíte url_for nebo cokoliv podobného v šablonách ActionMaileru, nikam se nedostanete. V dokumentaci je navíc poměrně depresivní upozornění, že to zkrátka nejde. Naštěstí to jde, stačí includovat UrlWriter:

class EshopOrderMailer < ActionMailer::Base
	include ActionController::UrlWriter
	....
end

Comments Bez komentářů »

Docela mě překvapilo, že v šablonách pro ActionMailer nejsou dostupné helpery definované v application_helper.rb. Naštěstí řešení je jednoduché, stačí upravit objekt ActionMaileru takto:

class FooMailer < ActionMailer::Base
	helper :application
	....
end

Comments Bez komentářů »

Přestože jsem si už zvykl na konfiguraci připojení k databázi pomocí souboru database.yml, tak semtam je potřeba připojit se i někam jinam. Třeba když píšu migrace na přesun dat z nějakého starého systému, který padl za oběť mému nadšení pro Ruby on Rails a jehož provoz se ehm… ukončuje. Náhodou jsem při tom narazil na web ConnectionStrings – Where do you want to connect today? Podle mě skvělá pomůcka pro programátory používající ADO nebo novější ADO.NET.

Comments Bez komentářů »

Určitě to znáte – vymyslíte nějakou skvělou věc, odladíte si jí ve Firefoxu (všechno funguje jak má), testujete v IE a nefunguje nic. Dnes se mi stalo něco podobného, potřeboval jsem přes AJAX vkládat řádky do tabulky, ale IE stávkovalo a tvrdohlavě vracelo Object Error. Kód vypadal hrozně jednoduše, nebylo na něm co zkazit, takže chyba musela být někde jinde:

<table id="results-table" cellpadding="0" cellspacing="0"></table>

a na serveru:

render :update do |page|
	page.insert_html :bottom, 'results-table', :partial => 'list'
end

Finta je jednoduchá – IE (alespoň verze 6) umí vkládat pouze do <tbody>, takže tohle už funguje:

<table id="results-table" cellspecing="0" cellpadding="0">
	<tbody id="results-table-body"></tbody>
</table>

a:

render :update do |page|
    page.insert_html :bottom, 'results-table-body', :partial => 'list'
end

Comments 1 Komentář »

První oficiální verze webového serveru pro běh Ruby aplikací. V tuhle chvíli je Mongrel pravděpodobně nejlepší volbou pro běh Ruby on Rails aplikací (najdete ho na téměř všech zahraničních hostingách, které Ruby on Rails nabízejí), je snadno konfigurovatelný, dobře spolupracuje s Apachem a zkrátka „just works“. Kupodivu „just works“ i ve Windows, což je spíš výjimka a dokonce je podporován i v RadRails pluginu pro Eclipse.

Comments Bez komentářů »