HashCode

An organizer of symbols

Archive for July, 2007

RailsTree 0.8.5

Tuesday, July 10th, 2007

Estava procurando uma tree para utilizar em rails e não achei, aí migrei a tree que tinhamos desenvolvido baseado no javascript do Geir Landr[2003] do formj para um plugin rails.
Exemplo de árvore dos dois estilos por padrão.
Gnome Style(default)

Explorer Style

tree2.png

Mac X/Acqua Style
Me mande que coloco aqui :-)
Anatomia
Após a instalação o railstree adiciona os seguintes arquivos no RAILS_ROOT

/lib/node.rb                 # o nó
/lib/tree.rb                 # a tree que também é um nó(raíz)
/public/images/tree/*.gif    # imagens(pasta,documento,etc)
/public/javascripts/tree.js  # O script da árvore
/public/stylesheets/tree.css # humm! o estilo.

Talvez o estilo da sua aplicações interfira diretamente no esboço da árvore.
Gnome Style é o default, para usar o Explorer Style descompacte img_tree_explorer.tar.gz em /public/images/tree
Instalação
Via svn
Adicione o repositório

script/plugin source svn://rubyforge.org/var/svn/railstree/vendor/plugins

Depois instale com

script/plugin install tree

Via local
Descompacte o arquivo railstree0.8.5.zip no diretório vendor/plugins do seu Rails. Entre no diretório tree e execute

ruby install.rb

O railstree funciona em conjunto com os scripts de ajax e javascripts default do rails, portando adicione na sua view o no seu layout os scripts

  <%= javascript_include_tag 'prototype' %>
  <%= javascript_include_tag 'effects' %>
  <%= javascript_include_tag 'dragdrop' %>
  <%= javascript_include_tag 'controls' %>

e depois o script e o css do railstree

  <%= stylesheet_link_tag 'tree' %>
  <%= javascript_include_tag 'tree' %>

ficando assim

  <%= stylesheet_link_tag 'tree' %>
  <%= javascript_include_tag 'tree' %>
  <%= javascript_include_tag 'prototype' %>
  <%= javascript_include_tag 'effects' %>
  <%= javascript_include_tag 'dragdrop' %>
  <%= javascript_include_tag 'controls' %>

Já tá pronto pra funcionar
Usando
A idéia é básica. Um nó pode ter filhos ou não. Para criar sua estrutura siga sempre a lógica de colocar um nó dentro do outro e um objeto da classe Tree para impressão dos dados na tela.
Exemplo:

a=Node.new(:label => 'A', :url => '/letras/a') # nome , link
b=Node.new(:label => 'B', :url => '/letras/b')
c=Node.new(:label => 'C', :url => '/letras/c')
d=Node.new(:label => 'D', :url => '/letras/d')
e=Node.new(:label => 'E', :url => '/letras/e')
f=Node.new(:label => 'F', :url => '/letras/f') # nó em filho
a << b  #adicionando b em a
c << a  #adicionando a em c
d << e  #adicionando e em d

tree=Tree.new(:label => 'Root',:url=> '/letras/todas')
tree << c  #Taca 'c' na raiz da tree
tree << d  #Taca 'd' na raiz da tree
tree << f  #Taca 'f'(sem filho) na raiz da tree

Podemos passar blocos para os nós. Exemplo da mesma estrutura acima, usando blocos


tree=Tree.new(:label => "Root",:url =>"/letras/todas") do |t|
    t << Node.new(:label => "C",:url =>"/letras/c") do |n|
      n << Node.new(:label => "A",:url =>"/letras/a") {|a| a << Node.new(:label => "B",:url =>"/letras/b")}
    end
 end

tree << Node.new(:label => "D",:url =>"/letras/d") {|d| d << Node.new(:label => "E",:url =>"/letras/E") }
tree << Node.new(:label => "F",:url =>"/letras/f")

E que Deus continue inspirando Yukihiro Matsumoto
Vc escolhe!
Tem mais uma, todo o node tem nodes e aceita um bloco(opcional)

a=Node.new("A","/letras/a")
 a.nodes do |n|
   #faça algo com os filhos
end

Personalizando…
Você poderá mudar os ícones de um nó fechado ou aberto, fazer referênciar pelo atributo href de uma âncora ou onclick para acessar uma função em javascript, falar para o nó aparecer aberto ou fechado, etc.

Mudando os ícones


a=Node.new(:label => "A",:url => "/letras/a")
a.icon='/images/db.png'
a.icon_open='/images/outroicone.png'

Exemplo, esse código


  tabelas1=%w(starttelephony startvoip customers  gateways)
  tabelas2=%w(teste1 teste2 ) 

  d1=Node.new(:label => "radius", :icon => "/images/data.png", :open => true)
  d2=Node.new(:label => "teste", :icon => "/images/data.png", :open => false)

  tabelas1.each do |t|
    no=Node.new(:label => t, :icon => "/images/table_sql.png")
    d1 << no
  end

  tabelas1.each do |t|
    no=Node.new(:label => t, :icon => "/images/table_sql.png")
    d1 << no
  end

  tabelas2.each do |t|
    no=Node.new(:label => t, :url => 'link aqui', :icon => "/images/table_sql.png")
    d2 << no
  end

  tr = Tree.new(:label => "Databases[solaris]")
  tr << d1
  tr << d2

Gera isto:
tree3.png

Falando para um node aparecer aberto ou fechado(se tiver filhos!)


# :open => true ou false, esse valor é passado para o javascript
a=Node.new(:label => "A",:url => "/letras/a", :open => true)
#ou
a.open=true

Link e eventos

Temos o atributo variável event_name que pode ser qualquer coisa que vc quer mais trabalha em conjunto com o atributo href, não obstante para criar um link teremos o seguinte:


Node.new(:label => "A",:url => "/letras/a")

é a mesma coisa de fazer isso


Node.new(:label => "A",:href => '/letra/a', :event_name => :href)

isso vai criar uma tag assim para o nó
<a href=’/letras/a’ > A </a>

Hummm!
Então para criar um nó que chama um javascript pode ser assim


Node.new(:label => "A", :url => "alert('nossa que doído!')", :event_name => :onclick )

#ou

a=Node.new
a.label="A"
a.url="alert('nossa que doído!')"
a.event_name= :onclick

Link for Rails
Tem um esquema legal, que é usar a mesmo mecanismo de link do Rails o link_to e o link_to_remote.
É necessário a adição da opção :base referenciando uma instância de qualquer controller para que o mecanismo interno do método url_for(rails) funcione adequadamente.

link_to

Node.new  :label => "Criar usuário",
          :link_to => {
            :base =&gt; @controller,
            :controller =&gt; "usuarios",
            :action =&gt; "adicionar" ,
            :id =&gt; 1
          }

assumindo que @controller é uma instância do controller, se tiver dentro de um controller troque @controller por self ficando :base => self.
Para um roteamento padrão do Rails isso é a mesmo coisa de


n=Node.new(:label => "Criar usuário",url => "/usuarios/adicionar/1")

Pode também fazer requisições em ajax utilizando a criação padrão do link_to_remote mais :base.

link_to_remote

Node.new  :label => "Adicionar usuário ",
          :link_to_remote => {
            :base =&gt; @controller,
            :controller =&gt; "usuarios",
            :update =&gt; "id_do_div",
            :url =&gt;{ :action =&gt; 'adicionar', :c=&gt; 'variavel C', :a =&gt; 'variavel A'}
          }
 }

Montando uma árvore de diretório
Vou demonstrar aqui gerando o path do RAILS_ROOT

 Tree.for(RAILS_ROOT)

Pronto. Isso gera
tree4.png

Extra Sintaxe

t=Tree.new(:label => 'Raiz')
t.child(:label => 'Pai').child(:label => 'filho').child(:label => 'espirito santo').child(:label => 'amem')

amem.png
ou para um filho


t.child(:label => 'Pai'){ |p| p.child(:label => 'filho') }
#ou
t.child Node.new(:label => 'Pai').child Node.new(:label => 'filho')

Para vários irmão


t.child Node.new(:label => 'a'),Node.new(:label => 'b'), Node.new(:label => 'c')

ou

t.mknodes(5) do |n,s|
      n.label="Link #{s}"
      n.url="/link/#{s}"
end

Obs.: Sugestão do Ronie Uliana

Obs2.: Criação dos nodes passando Hash foi sugestão do Marcelo Júnior

rghost - Plugin ou Gem?

Tuesday, July 10th, 2007

Você escolhe!!
rghost_plugin.png
Pra quem pediu, disponibilizei o rghost como plugin no repositório do rghost no RubyForge só descompactar no RAILS_ROOT/lib e reiniciar a aplicação.

Impressão direta via TCP/IP com RubyGhost

Tuesday, July 10th, 2007

Geralmente as impressoras de médio e grande porte disponibilizam uma porta TCP conhecida como ‘porta bruta’ de número 9100. Demonstrarei aqui uma forma de imprimir diretamente neste tipo de printer, para o nosso exemplo usaremos o driver postscript genérico da Adobe(PS-Adobe-3.0).
Models Contas e Clientes

class Contas < ActiveRecord::Base
  belongs_to :clientes
end
class Clientes < ActiveRecord::Base
  has_one :contas
end

Configurando as colunas

require 'rghost'
clientes=Clientes.find :all, :include => :contas, :limit => 10000

grid=DataGrid::RailsGrid.new :width => 4 , :align => :center
grid.col :codigo, :title => "Código do Cliente", :width => 5
grid.col :nome, :title => "Nome"
grid.col :created_on, :title => "Data de Cadastro ", :format => :eurodate
grid.col lambda { contas.login }, :title => "Login"
grid.data(clientes)

Criando o documento com dados do ActiveRecord

doc=Document.new :paper => :A4, :landscape => true, :duplex => true
doc.before_page_create do
  set Image.for("/tmp/fatura.eps")
end
doc.set grid
doc.done

Enviando o documento

printer = TCPSocket.open('192.168.1.70', 9100)
printer.write doc.render_stream(:ps)

Deve ter saído lá na impressora… :)

Para mais informações no RGhost - RubyForge . Documentação em português no RubyForge