|Home|Why Use?|Demos|About |Contact|Mail List |Group |Hpricot By Mr _Why |FAQ|Workbench|Workbench-RO|

Hpricot Workbench For Building Fragments Of HTML (Read-Only View)

Fragment Owner Stack Name Fragment Name Input URL Parent Fragment Type Of Expression Arg1 Arg2 Arg3 Arg4 Fragment Text Scraped From Input Source (Parent, or Input URL)
bikle yellowstack f100 http://www.google.com - .search() a - - -

Render The HTML Below:
<a href="http://images.google.com/imghp?tab=wi">Images</a><a href="http://video.google.com/?tab=wv">Video</a><a href="http://news.google.com/nwshp?tab=wn">News</a><a href="http://maps.google.com/maps?tab=wl">Maps</a><a href="http://mail.google.com/mail?tab=wm">Gmail</a><a href="http://www.google.com/intl/en/options/" onclick="this.blur();gbar.tg(event);return false"><u>more</u> <span style="font-size:11px">&#9660;</span></a><a href="http://blogsearch.google.com/?tab=wb">Blog Search</a><a href="http://www.blogger.com/?tab=wj">Blogger</a><a href="http://books.google.com/bkshp?tab=wp">Books</a><a href="http://www.google.com/calendar?tab=wc">Calendar</a><a href="http://docs.google.com/?tab=wo">Documents</a><a href="http://finance.google.com/finance?tab=we">Finance</a><a href="http://groups.google.com/grphp?tab=wg">Groups</a><a href="http://labs.google.com/">Labs</a><a href="http://www.orkut.com/?tab=w0">Orkut</a><a href="http://www.google.com/ptshp?tab=wt">Patents</a><a href="http://picasaweb.google.com/home?tab=
SNIPPED at character number 1024. Use render and then browser-view-source to see all of it.
Show
bikle bluestack f101 http://www.google.com - .search().remove a[@href*=blog] - - -

Render The HTML Below:
<html><head><meta content="text/html; charset=UTF-8" http-equiv="content-type" /><title>Google</title><style><!-- body,td,a,p,.h{font-family:arial,sans-serif} .h{font-size:20px} .h{color:#3366cc} .q{color:#00c} .ts td{padding:0}.ts{border-collapse:collapse}#gbar{float:left;font-weight:bold;height:22px;padding-left:2px}#gbh{border-top:1px solid #c9d7f1;font-size:0;height:0;position:absolute;right:0;top:24px;width:200%}#gbi{background:#fff;border:1px solid;border-color:#c9d7f1 #36c #36c #a2bae7;font-size:13px;top:24px;z-index:1000}#guser{padding-bottom:7px !important}#gbar,#guser{font-size:13px;padding-top:1px !important}.gb1,.gb3{display:inline;height:22px;margin-right:1em;vertical-align:top}#gbi,.gb2{display:none;position:absolute;width:7em}.gb2{z-index:1001}#gbar a,#gbar a:active,#gbar a:visited{color:#00c;font-weight:normal}.gb2 a,.gb3 a{text-decoration:none}.gb2 a{display:block;padding:.2em .5em}#gbar .gb2 a:hover{background:#36c;color:#fff}--></style> <script> <!-- window.google={kEI:"lee4RsbvK4u2iwHPsuH6
SNIPPED at character number 1024. Use render and then browser-view-source to see all of it.
Show
bikle greenstack f103 http://www.google.com - .search() div.gb2 - - -

Render The HTML Below:
<div class="gb2"><a href="http://blogsearch.google.com/?tab=wb">Blog Search</a></div><div class="gb2"><a href="http://www.blogger.com/?tab=wj">Blogger</a></div><div class="gb2"><a href="http://books.google.com/bkshp?tab=wp">Books</a></div><div class="gb2"><a href="http://www.google.com/calendar?tab=wc">Calendar</a></div><div class="gb2"><a href="http://docs.google.com/?tab=wo">Documents</a></div><div class="gb2"><a href="http://finance.google.com/finance?tab=we">Finance</a></div><div class="gb2"><a href="http://groups.google.com/grphp?tab=wg">Groups</a></div><div class="gb2"><a href="http://labs.google.com/">Labs</a></div><div class="gb2"><a href="http://www.orkut.com/?tab=w0">Orkut</a></div><div class="gb2"><a href="http://www.google.com/ptshp?tab=wt">Patents</a></div><div class="gb2"><a href="http://picasaweb.google.com/home?tab=wq">Photos</a></div><div class="gb2"><a href="http://www.google.com/prdhp?tab=wf">Products</a></div><div class="gb2"><a href="http://www.google.com/reader?tab=wy">Reader</a></div><d
SNIPPED at character number 1024. Use render and then browser-view-source to see all of it.
Show
bikle greenstack f104 f103 .search() a - - -

Render The HTML Below:
<a href="http://blogsearch.google.com/?tab=wb">Blog Search</a><a href="http://www.blogger.com/?tab=wj">Blogger</a><a href="http://books.google.com/bkshp?tab=wp">Books</a><a href="http://www.google.com/calendar?tab=wc">Calendar</a><a href="http://docs.google.com/?tab=wo">Documents</a><a href="http://finance.google.com/finance?tab=we">Finance</a><a href="http://groups.google.com/grphp?tab=wg">Groups</a><a href="http://labs.google.com/">Labs</a><a href="http://www.orkut.com/?tab=w0">Orkut</a><a href="http://www.google.com/ptshp?tab=wt">Patents</a><a href="http://picasaweb.google.com/home?tab=wq">Photos</a><a href="http://www.google.com/prdhp?tab=wf">Products</a><a href="http://www.google.com/reader?tab=wy">Reader</a><a href="http://scholar.google.com/schhp?tab=ws">Scholar</a>
SNIPPED at character number 1024. Use render and then browser-view-source to see all of it.
Show
bikle redstack f105 http://www.google.com - .at() a[text()*=Finance] - - -

Render The HTML Below:
<a href="http://finance.google.com/finance?tab=we">Finance</a>

Show
bikle whitestack f106 http://www.google.com - .at().inner_html html/head - - -

Render The HTML Below:
<meta content="text/html; charset=UTF-8" http-equiv="content-type" /><title>Google</title><style><!-- body,td,a,p,.h{font-family:arial,sans-serif} .h{font-size:20px} .h{color:#3366cc} .q{color:#00c} .ts td{padding:0}.ts{border-collapse:collapse}#gbar{float:left;font-weight:bold;height:22px;padding-left:2px}#gbh{border-top:1px solid #c9d7f1;font-size:0;height:0;position:absolute;right:0;top:24px;width:200%}#gbi{background:#fff;border:1px solid;border-color:#c9d7f1 #36c #36c #a2bae7;font-size:13px;top:24px;z-index:1000}#guser{padding-bottom:7px !important}#gbar,#guser{font-size:13px;padding-top:1px !important}.gb1,.gb3{display:inline;height:22px;margin-right:1em;vertical-align:top}#gbi,.gb2{display:none;position:absolute;width:7em}.gb2{z-index:1001}#gbar a,#gbar a:active,#gbar a:visited{color:#00c;font-weight:normal}.gb2 a,.gb3 a{text-decoration:none}.gb2 a{display:block;padding:.2em .5em}#gbar .gb2 a:hover{background:#36c;color:#fff}--></style> <script> <!-- window.google={kEI:"xui4RoO0L5vQigHo4sH1AQ",kEXPI:"1
SNIPPED at character number 1024. Use render and then browser-view-source to see all of it.
Show
bikle orangestack f107 http://www.google.com - display-enumerable() a,[0,999] - - -

Render The HTML Below:
<hr />0<p /><a href="http://images.google.com/imghp?tab=wi">Images</a><hr />1<p /><a href="http://video.google.com/?tab=wv">Video</a><hr />2<p /><a href="http://news.google.com/nwshp?tab=wn">News</a><hr />3<p /><a href="http://maps.google.com/maps?tab=wl">Maps</a><hr />4<p /><a href="http://mail.google.com/mail?tab=wm">Gmail</a><hr />5<p /><a href="http://www.google.com/intl/en/options/" onclick="this.blur();gbar.tg(event);return false"><u>more</u> <span style="font-size:11px">&#9660;</span></a><hr />6<p /><a href="http://blogsearch.google.com/?tab=wb">Blog Search</a><hr />7<p /><a href="http://www.blogger.com/?tab=wj">Blogger</a><hr />8<p /><a href="http://books.google.com/bkshp?tab=wp">Books</a><hr />9<p /><a href="http://www.google.com/calendar?tab=wc">Calendar</a><hr />10<p /><a href="http://docs.google.com/?tab=wo">Documents</a><hr />11<p /><a href="http://finance.google.com/finance?tab=we">Finance</a><hr />12<p /><a href="http://groups.google.com/grphp?tab=wg">Groups</a><hr />13<p /><a href="http://labs
SNIPPED at character number 1024. Use render and then browser-view-source to see all of it.
Show
bikle orangestack f108 f107 display-enumerable() a,[3,2] - - -

Render The HTML Below:
<hr />0<p /><a href="http://maps.google.com/maps?tab=wl">Maps</a><hr />1<p /><a href="http://mail.google.com/mail?tab=wm">Gmail</a>

Show
bikle bluestack f109 http://www.google.com - .search() div.gb2 - - -

Render The HTML Below:
<div class="gb2"><a href="http://blogsearch.google.com/?tab=wb">Blog Search</a></div><div class="gb2"><a href="http://www.blogger.com/?tab=wj">Blogger</a></div><div class="gb2"><a href="http://books.google.com/bkshp?tab=wp">Books</a></div><div class="gb2"><a href="http://www.google.com/calendar?tab=wc">Calendar</a></div><div class="gb2"><a href="http://docs.google.com/?tab=wo">Documents</a></div><div class="gb2"><a href="http://finance.google.com/finance?tab=we">Finance</a></div><div class="gb2"><a href="http://groups.google.com/grphp?tab=wg">Groups</a></div><div class="gb2"><a href="http://labs.google.com/">Labs</a></div><div class="gb2"><a href="http://www.orkut.com/?tab=w0">Orkut</a></div><div class="gb2"><a href="http://www.google.com/ptshp?tab=wt">Patents</a></div><div class="gb2"><a href="http://picasaweb.google.com/home?tab=wq">Photos</a></div><div class="gb2"><a href="http://www.google.com/prdhp?tab=wf">Products</a></div><div class="gb2"><a href="http://www.google.com/reader?tab=wy">Reader</a></div><d
SNIPPED at character number 1024. Use render and then browser-view-source to see all of it.
Show
bikle bluestack f110 f109 .search().append() a <hr> - -

Render The HTML Below:
<div class="gb2"><a href="http://blogsearch.google.com/?tab=wb">Blog Search<hr /></a></div><div class="gb2"><a href="http://www.blogger.com/?tab=wj">Blogger<hr /></a></div><div class="gb2"><a href="http://books.google.com/bkshp?tab=wp">Books<hr /></a></div><div class="gb2"><a href="http://www.google.com/calendar?tab=wc">Calendar<hr /></a></div><div class="gb2"><a href="http://docs.google.com/?tab=wo">Documents<hr /></a></div><div class="gb2"><a href="http://finance.google.com/finance?tab=we">Finance<hr /></a></div><div class="gb2"><a href="http://groups.google.com/grphp?tab=wg">Groups<hr /></a></div><div class="gb2"><a href="http://labs.google.com/">Labs<hr /></a></div><div class="gb2"><a href="http://www.orkut.com/?tab=w0">Orkut<hr /></a></div><div class="gb2"><a href="http://www.google.com/ptshp?tab=wt">Patents<hr /></a></div><div class="gb2"><a href="http://picasaweb.google.com/home?tab=wq">Photos<hr /></a></div><div class="gb2"><a href="http://www.google.com/prdhp?tab=wf">Products<hr /></a></div><div clas
SNIPPED at character number 1024. Use render and then browser-view-source to see all of it.
Show
bikle bluestack f111 f110 .search().wrap() a <h1> - -

Render The HTML Below:
<div class="gb2"><h1><a href="http://blogsearch.google.com/?tab=wb">Blog Search<hr /></a></h1></div><div class="gb2"><h1><a href="http://www.blogger.com/?tab=wj">Blogger<hr /></a></h1></div><div class="gb2"><h1><a href="http://books.google.com/bkshp?tab=wp">Books<hr /></a></h1></div><div class="gb2"><h1><a href="http://www.google.com/calendar?tab=wc">Calendar<hr /></a></h1></div><div class="gb2"><h1><a href="http://docs.google.com/?tab=wo">Documents<hr /></a></h1></div><div class="gb2"><h1><a href="http://finance.google.com/finance?tab=we">Finance<hr /></a></h1></div><div class="gb2"><h1><a href="http://groups.google.com/grphp?tab=wg">Groups<hr /></a></h1></div><div class="gb2"><h1><a href="http://labs.google.com/">Labs<hr /></a></h1></div><div class="gb2"><h1><a href="http://www.orkut.com/?tab=w0">Orkut<hr /></a></h1></div><div class="gb2"><h1><a href="http://www.google.com/ptshp?tab=wt">Patents<hr /></a></h1></div><div class="gb2"><h1><a href="http://picasaweb.google.com/home?tab=wq">Photos<hr /></a></h1></
SNIPPED at character number 1024. Use render and then browser-view-source to see all of it.
Show
bikle redstack f112 http://www.google.com - .at().swap() div.gb2/a <h2>hpricot.com</h2> - -

Render The HTML Below:
<html><head><meta content="text/html; charset=UTF-8" http-equiv="content-type" /><title>Google</title><style><!-- body,td,a,p,.h{font-family:arial,sans-serif} .h{font-size:20px} .h{color:#3366cc} .q{color:#00c} .ts td{padding:0}.ts{border-collapse:collapse}#gbar{float:left;font-weight:bold;height:22px;padding-left:2px}#gbh{border-top:1px solid #c9d7f1;font-size:0;height:0;position:absolute;right:0;top:24px;width:200%}#gbi{background:#fff;border:1px solid;border-color:#c9d7f1 #36c #36c #a2bae7;font-size:13px;top:24px;z-index:1000}#guser{padding-bottom:7px !important}#gbar,#guser{font-size:13px;padding-top:1px !important}.gb1,.gb3{display:inline;height:22px;margin-right:1em;vertical-align:top}#gbi,.gb2{display:none;position:absolute;width:7em}.gb2{z-index:1001}#gbar a,#gbar a:active,#gbar a:visited{color:#00c;font-weight:normal}.gb2 a,.gb3 a{text-decoration:none}.gb2 a{display:block;padding:.2em .5em}#gbar .gb2 a:hover{background:#36c;color:#fff}--></style> <script> <!-- window.google={kEI:"Ne64RvCOIo_MigHy9MD0
SNIPPED at character number 1024. Use render and then browser-view-source to see all of it.
Show
bikle greenstack f114 http://bikle.com - display-comments - - - -

Render The HTML Below:
<hr /><!--[if IE]><link href="/stylesheets/active_scaffold/default/stylesheet-ie.css?1186518030" media="screen" rel="Stylesheet" type="text/css" /><![endif]--><hr /><!-- t1 --><hr /><!-- t1r1 --><hr /><!-- t1r1 --><hr /><!-- t1r2 --><hr /><!-- Google CSE Search Box Begins --><hr /><!-- Google CSE Search Box Ends --><hr /><!-- SiteSearch Google --><hr /><!-- <tr><td nowrap="nowrap" valign="top" align="left" height="32"> <a href="http://www.google.com/"> <img id="googlelogo" src="http://www.google.com/logos/Logo_25wht.gif" border="0" alt="Google" align="middle"></img></a> </td></tr> --><hr /><!-- SiteSearch Google --><hr /><!-- Some Ajax! --><hr /><!-- Some Ajax! --><hr /><!-- t1r2c1 --><hr /><!-- <p /> <span class="r2c2text">You want it sturdy.</span> <p /> <a target="railsapi" href="http://api.rubyonrails.com/"> <img src="http://bornboulder77.googlepages.com/bike1.jpg" height="300" width="400" alt="sturdy"> </a> <p /> <div class="r2c2text10">Ruby on Rails. Oracle. <br />Both Fast and Sturdy. <b
SNIPPED at character number 1024. Use render and then browser-view-source to see all of it.
Show
bikle greenstack f115 f114 remove-comments - - - -

Render The HTML Below:
<hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr />

Show
bikle whitestack f116 http://bikle.com - .search() a[text()*='bikle'] - - -

Render The HTML Below:
<a href="/">http://bikle.com</a><a href="/">http://bikle.com</a>

Show

Source Code Which Serves This Page:

/views/layouts/application.rhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <%= render(:partial => "layouts/head") %>
<body>
<table id="t2" width="98%" border="0">
<tr id="t2r2">
<td id="t2r2c2" valign="top">
  <%= render(:partial => "layouts/t2r2c2") %>
</td> <!-- t2r2c2 end -->
<td id="t2r2c4" valign="top">
<%= render(:partial => "layouts/bcrmbs") %>
<%= yield %>
<hr />
<h3> Source Code Which Serves This Page: </h3>
<%= render(:partial => "layouts/show_source") %>
<hr />
<%= render(:partial => "layouts/bcrmbs") %>
<hr />
</td> <!-- t2r2c4 end -->
<td id="t2r2c6" class="hpricot-color" valign="top">
  <%= render(:partial => "layouts/t2r2c6") %>
</td> <!-- t2r2c6 end -->
</tr> <!-- t2r2 end -->
</table>  <!-- t2 end -->
</body>
</html>

/views/layouts/_head.haml

%head
  %meta{"http-equiv" => "Content-Type", :content => "text/html; charset=utf-8"}
  %title hpricot.com
  %link{:rel => "shortcut icon", :href => "/favicon.ico"}
  = javascript_include_tag("prototype")
  = javascript_include_tag("effects")
  = javascript_include_tag("dragdrop")
  = javascript_include_tag("controls")
  = javascript_include_tag("application")
  = active_scaffold_includes
  = stylesheet_link_tag("application")

/views/layouts/_t2r2c2.haml

/ _t2r2c2.haml
%td#t2r2c2.hpricot-color{:valign => "top"}
  %div.white-color
    %hr
    %a{:href => "/"}
      %img{:src => "/images/hpricot-small.png", :alt => "http://hpricot.com"}
    %hr
    %h2
      = bcrmb('<a href="/">http://hpricot.com</a>')
    %hr
    %p
      %b
        = bcrmb('<a href="/sttc/why_hpricot"> Why Learn/Use Hpricot?</a>')
    %p
      %b
        = bcrmb('<a href="/demos"> Hpricot Demonstrations</a>')
    %p
      %b
        = bcrmb('<a href="/demos/about"> About</a>')
    %p
      %b
        = bcrmb('<a href="/sttc/contact"> Contact</a>')
    %p
      %b
        = bcrmb('<a href="/sttc/maillist"> Mail List</a>')
    %p
      %b
        %a{:href => "http://groups.google.com/group/hpricot", :target => "hp"} http://groups.google.com/group/hpricot
    %p
      %b
        %a{:href => "http://code.whytheluckystiff.net/hpricot", :target => "hp"} http://code.whytheluckystiff.net/hpricot
    %hr
    %p= render(:partial => "layouts/login_status")
    %hr
    %p
      %b
        = bcrmb('<a href="/sttc/workbench_faq"> FAQ for Hpricot Workbench</a>')
    %p
      %b
        = bcrmb('<a href="/frgmnts"> An Hpricot Workbench</a>')
    %p
      %b
        = bcrmb('<a href="/asls/frgmnts"> Hpricot Workbench Public (Read-Only)</a>')
    %p
      %b
        %a{:href => "http://chrispederick.com/work/web-developer", :target => "wd"}
          Hpricot Development Aid:
          %br http://chrispederick.com/work/web-developer
    %p
      %b
        %a{:href => "http://www.getfirebug.com", :target => "wd"}
          Hpricot Development Aid:
          %br http://www.getfirebug.com
    %p
      %b
        %a{:href => "/hpricot_rdoc154/index.html", :target => "hp"} RDoc of Hpricot 0.6
    %p
      %b
        %a{:href => "/app/index.html", :target => "hp"} RDoc of hpricot.com
    %p
      %b
        = bcrmb('<a href="/sttc/disclaimer"> Disclaimer!</a>')
    %hr
    = render(:partial => "/layouts/built_with")
    %hr

/views/layouts/_show_source.rhtml

<%= show_code("views/layouts", "application.rhtml") -%>
<%= show_code("views/layouts", "_head.haml") -%>
<%= show_code("views/layouts", "_t2r2c2.haml") -%>
<%= show_code("views/layouts", "_show_source.rhtml") -%>
<%= show_code("../public/stylesheets/sass", "application.sass") -%>
<%= show_code("../config", "routes.rb") -%>

<%= show_code("controllers", "application.rb") -%>
<%= show_code("controllers", "#{params[:controller]}_controller.rb") -%>
<%= show_code("helpers", "application_helper.rb") -%>
<%= show_code("helpers", "#{params[:controller]}_helper.rb") -%>
<p />
The Hpricot Workbench makes use of these models:
<p />
<%= show_code("models", "exprtype.rb") -%>
<%= show_code("models", "stck.rb") -%>
<%= show_code("models", "frgmnt.rb") -%>
<%= show_code("models", "usr.rb") -%>

/../public/stylesheets/sass/application.sass

td
  :border-style solid
  :border-width 1px
  :border-color black


body
  :background-color white
  :width 98%

.hpricot-color
  :background-color #FF7700

.white-color
  :background-color white

a
  :text-decoration underline
  :color #335500
  :font-weight bold
a:hover
  :text-decoration underline
  :color #FF7700
  :background-color #FFFFFF
a:visited


.redstack
  :background-color red

.greenstack
  :background-color green

.bluestack
  :background-color blue

.yellowstack
  :background-color yellow

.orangestack
  :background-color orange

.whitestack
  :background-color white

.blackstack
  :background-color black

// frgmnt-frgtxt is out of control. I constrain it with scroll bars.
div.frgmnt-frgtxt
  :overflow scroll
  :height 200px
  :width 200px


// Make text message at end of frgtxt more noticeable
span.snipmsg
  :color #1F7F00
  :font-weight bold

// Code

code
  :font-size 120%
  :line-height 140%
  :background-color #ddd

pre
  :background #333
  :color #fffed8
  :border 1px inset #aaa
  :overflow auto
  :padding 3px 5px
  :margin 5px 0

pre code
  :background-color transparent
// Code End

/../config/routes.rb

ActionController::Routing::Routes.draw do |map|
  # The priority is based upon order of creation: first created -> highest priority.

  # Sample of regular route:
  # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
  # Keep in mind you can assign values other than :controller and :action

  # Sample of named route:
  # map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'
  # This route can be invoked with purchase_url(:id => product.id)

  # You can have the root of your site routed by hooking up ''
  # -- just remember to delete public/index.html.
  map.connect '', :controller => "demos", :action => "about"

  # Allow downloading Web Service WSDL as a file with an extension
  # instead of a file named 'wsdl'
  map.connect ':controller/service.wsdl', :action => 'wsdl'

  # Install the default route as the lowest priority.
  map.connect ':controller/:action/:id.:format'
  map.connect ':controller/:action/:id'
end

/controllers/application.rb

# Filters added to this controller apply to all controllers in the application.
# Likewise, all the methods added will be available for all controllers.

require 'usr_system'
require 'rubygems'
require 'hpricot'
require 'open-uri'

class ApplicationController < ActionController::Base
  # Pick a unique cookie name to distinguish our session data from others'
  session :session_key => '_hp12_session_id'
  include ERB::Util
  include UsrSystem
  helper :usr
  before_filter :authenticate_usr
  # I help Hpricot
  Hpricot.buffer_size = 262144

  # Null out the parse() method of  WebAgent::CookieManager so it cannot save cookies
  module Tst
    class WebAgent::CookieManager
      # Empty parse method which nulls out the effect of the real parse()
      def parse x, y
        @index = "nada"
      end # parse
    end # class
  end # module

  # Method for rendering the HTML in a Fragment
  def rndr_frgmnt
    @somehtml = Frgmnt.find(params[:id]).frgtxt
    render(:layout => "layouts/layout4rndr")
  end # rndr_frgmnt

  protected

  # Returns raw HTML.  Usually it gets passed to get_my_hp_elem()
  def get_my_html_from_open_uri(u)
    hdrs = {"User-Agent"=>"Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1", "Accept-Charset"=>"utf-8", "Connection"=>"Keep-Alive", "Accept"=>"text/html"}
    my_html = ""
    begin
      open(u, hdrs).each {|s| my_html << s}
    rescue
      my_html = "<html><body><p /><b>hello world</b></body></html>"
    end
    return my_html
  end # get_my_html_from_open_uri()

  # Returns an Hpricot object from HTML obtained by get_my_html_from_open_uri()
  def get_my_hp_elem(u)
    h0 = Hpricot(get_my_html_from_open_uri(u))
    # remove crap
    # (h0/"script").remove
    return h0
  end # get_my_hp_elem()

  # Repel users who manually tinker with id in the request URL
  def repel_them
    # I dont need to repel_them if id is nil
    return if (params[:id] == nil)

    # Get the model class loaded into an object which can also be a class
    myklass = self.active_scaffold_config.model
    # Use the object-class-beastie to run .find() against the id in the request URL
    the_obj = myklass.find(params[:id])
    # Find out who owns the_obj
    the_usr_id = the_obj.send(:usr_id)
    # Repel them if they dont own the object pointed to by the id in the request URL
    redirect_to("/") unless the_usr_id == session[:usr_id]
  end

end # class

/controllers/asls/frgmnts_controller.rb

class Asls::FrgmntsController < ApplicationController
  skip_before_filter :authenticate_usr
  # active_scaffold creates powerful JS based forms.  See http://activescaffold.com
  active_scaffold do |config|
    config.actions = [:list, :show]
    config.label = "Hpricot Workbench For Building Fragments Of HTML (Read-Only View)"
    config.list.columns = [:usr, :stck, :name, :inputurl, :parent, :exprtype, :arg1, :arg2, :arg3, :arg4, :frgtxt]
    config.show.columns = [:usr, :stck, :name, :inputurl, :parent, :exprtype, :arg1, :arg2, :arg3, :arg4, :frgtxt]

    config.columns[:usr].label = "Fragment Owner"
    config.columns[:stck].label = "Stack Name"
    config.columns[:name].label = "Fragment Name"
    config.columns[:parent].label = "Parent Fragment"
    config.columns[:inputurl].label = "Input URL"
    config.columns[:frgtxt].label = "Fragment Text Scraped From Input Source (Parent, or Input URL)"
    config.columns[:exprtype].label = "Type Of Expression"
  end # active_scaffold

  # Only show frgmnts owned by bikle or the usr (but no one else) in the current session
  def conditions_for_collection
    bikle_usr = Usr.find_by_login("bikle")
    (bikle_usr.nil?) ? (bikle_id = session[:usr_id]) : (bikle_id = bikle_usr.id)
    ['frgmnts.usr_id in (?,?)', bikle_id, [session[:usr_id]]]
    # Above statement generates SQL like this:
    # SELECT * FROM frgmnts WHERE  frgmnts.usr_id in (1, 43)
  end

end

/helpers/application_helper.rb

# Methods in this helper are available to all templates in the application.
module ApplicationHelper

  # An Hpricot based breadcrumb helper.
  # Usage:
  # bcrmb("<a href='/x/y'>About</a> | <a href='/z'>Contact</a>")
  # Loads html into an hpricot and then swaps out any a-tag with a span-tag
  # if the a-tag-href matches the request.path
  def bcrmb(h)
    # get an hpricot from the input-html
    hp =  Hpricot(h)
    # Inside the hpricot, look for an a-tag containing the request.path
    hps = hp.search("a[@href=#{request.path}]")
    if (matched_a_tag = hps.first)
      # I hooked one, get it's text node
      txtnode = matched_a_tag.inner_text
      # Inside the hpricot, swap the a-tag with a span-tag
      matched_a_tag.swap("<span class='bcrmb'>#{txtnode}</span>")
    end
    # Pull html out of the hpricot.
    return hp.to_html
  end # bcrmb


  # Builds a simple a-element from URL
  def inputurl_column(record)
    "<a target='inputurl'  href='#{record.inputurl}'>#{record.inputurl}</a>"
  end # inputurl_column

  # Override the stck column so I can add color to it via CSS
  def stck_column(record)
    "<span class='#{record.stck.name}'>#{record.stck.name}</span>"
  end

  # Override the frgtxt column so I can add links to it and maybe show a subset of the data in it.
  def frgtxt_column(record)
    link_to_rndr = link_to("Render The HTML Below:", {:id => record, :action => "rndr_frgmnt", :controller => "frgmnts"}, {:target => "l"})
    # Use the ERB::Util.h() method below to make sure the HTML is displayed rather than rendered.
    # If they want to render, they can click the link.
    # Notice that I use .slice() to limit the amount of text sent back to the browser.
    # If they want to see all of the text they can .rndr_frgmnt() and use browser-view-source.
    myfrgtxt = (record.frgtxt || "nil")
    if (h(myfrgtxt).length > 1024)
      snipmsg = "<span class='snipmsg'>SNIPPED at character number 1024.  Use render and then browser-view-source to see all of it.</span>"
    else
      snipmsg = ""
    end # if
    return("<div class='frgmnt-frgtxt'> <hr />#{link_to_rndr}<hr />#{h(myfrgtxt.slice(0,1024))} <hr /> #{snipmsg} <hr /></div>")
  end # frgtxt_column()

  # I found this in the AS demo.  They use it to show ruby code which corresponds to scaffold views.
  # This helper is called in a partial here: app/views/layouts/_show_source.rhtml
  # Here is a sample line from app/views/layouts/_show_source.rhtml:
  # <%= show_code("controllers", "#{params[:controller]}_controller.rb") -%>
  def show_code(path, filename, comment = "")
    begin
      file = File.open("#{File.dirname __FILE__}/../../app/#{path}/#{filename}")
<<PRE_BLOCK
<h4>/#{path}/#{filename} #{comment}</h4>
<pre><code class=\"ruby\">#{file.read.gsub("<", "<").gsub(">", ">").strip}</code></pre>
PRE_BLOCK
    rescue
      "#{filename} is missing"
    end # begin, rescue
  end # show_code

end

/helpers/asls/frgmnts_helper.rb

module Asls::FrgmntsHelper
end

The Hpricot Workbench makes use of these models:

/models/exprtype.rb

class Exprtype < ActiveRecord::Base

  # Associations should come after callbacks
  has_many :frgmnts
  # Validations come after associations
  validates_presence_of :name
  validates_uniqueness_of :name, :message => " is already being used.  Pick a different name."
end

/models/stck.rb

class Stck < ActiveRecord::Base

  # Associations should come after callbacks
  has_many :frgmnts
  # Validations come after associations
  validates_presence_of :name
  validates_uniqueness_of :name, :message => " is already being used.  Pick a different name."
end

/models/frgmnt.rb

class Frgmnt < ActiveRecord::Base
  acts_as_tree  :order => "name"
  # Associations should come after callbacks
  belongs_to :usr
  belongs_to :exprtype
  belongs_to :stck
  # Validations come after associations
  validates_presence_of :name
  validates_uniqueness_of :name, :message => " is already being used.  Pick a different name."

  protected

  def validate
    case
    # Ensure we have some input
    when (parent == nil and inputurl == nil)
      errors.add(:parent, ", and Input URL are all nil.  You need one.")
    # We only want 1 input
    when (parent != nil and inputurl != nil)
      errors.add(:parent, "and Input URL are both not nil.  A fragment needs 1 (and only 1!)")
    # We should not scrape ourself
    when (parent == self)
      errors.add(:parent, " == self.  Pick a different parent.")
    # The controller will set name = "record_usr_id_ne_session_usr_id" if
    # I try to update a record I do not own.
    when name == "record_usr_id_ne_session_usr_id"
      errors.add_to_base "You can only update your records, not other's records."
    # display-enumerable needs format like this: table.some-class,[1,5]
    when (exprtype.name == 'display-enumerable()' and  ((arg1 =~ /(.*)?(\,)(\[)(\d+)(,)(\d+)(\])$/) != 0))
      errors.add(:arg1, ' Problem. display-enumerable() needs format like this: table.some-class,[1,5]')
    end # case
  end # validate

end

/models/usr.rb

require 'digest/sha1'

# this model expects a certain database layout and its based on the name/login pattern.
class Usr < ActiveRecord::Base
  CHANGEABLE_FIELDS = ['first_name', 'last_name', 'email']
  attr_accessor :password_needs_confirmation

  after_save '@password_needs_confirmation = false'
  after_validation :crypt_password

  validates_presence_of :login, :on => :create
  validates_length_of :login, :within => 3..40, :on => :create
  validates_uniqueness_of :login, :on => :create
  validates_uniqueness_of :email, :on => :create

  validates_presence_of :password, :if => :validate_password?
  validates_confirmation_of :password, :if => :validate_password?
  validates_length_of :password, { :minimum => 5, :if => :validate_password? }
  validates_length_of :password, { :maximum => 40, :if => :validate_password? }

  # Associations should come after callbacks
  has_many :frgmnts


  def initialize(attributes = nil)
    super
    @password_needs_confirmation = false
  end

  def self.authenticate(login, pass)
    u = find( :first, :conditions => ["login = ? AND verified = TRUE AND deleted = FALSE", login])
    return nil if u.nil?
    find( :first, :conditions => ["login = ? AND salted_password = ? AND verified = TRUE", login, salted_password(u.salt, hashed(pass))])
  end

  def self.authenticate_by_token(id, token)
    # Allow logins for deleted accounts, but only via this method (and
    # not the regular authenticate call)
    logger.info "Attempting authorization of #{id} with #{token}"
    u = find( :first, :conditions => ["id = ? AND security_token = ?", id, token])
    if u
      logger.info "Authenticated by token: #{u.inspect}"
    else
      logger.info "Not authenticated" if u.nil?
    end
    return nil if (u.nil? or u.token_expired?)
    u.update_attributes :verified => true, :token_expiry => Clock.now
    return u
  end

  def token_expired?
    self.security_token and self.token_expiry and (Clock.now >= self.token_expiry)
  end

  def generate_security_token
    if self.security_token.nil? or self.token_expiry.nil? or (Clock.now.to_i + token_lifetime / 2) >= self.token_expiry.to_i
      token = new_security_token
      return token
    else
      return self.security_token
    end
  end

  def change_password(pass, confirm = nil)
    self.password = pass
    self.password_confirmation = confirm.nil? ? pass : confirm
    @password_needs_confirmation = true
  end

  def token_lifetime
    UsrSystem::CONFIG[:security_token_life_hours] * 60 * 60
  end

  # Help Active Scaffold display Usr objects.
  # ref: http://activescaffold.com/tutorials/to_label
  def to_label
    login
  end

  protected

  attr_accessor :password, :password_confirmation

  def validate_password?
    @password_needs_confirmation
  end

  def self.hashed(str)
    return Digest::SHA1.hexdigest("change-me--#{str}--")[0..39]
  end

  def crypt_password
    if @password_needs_confirmation
      write_attribute("salt", self.class.hashed("salt-#{Clock.now}"))
      write_attribute("salted_password", self.class.salted_password(salt, self.class.hashed(@password)))
    end
  end

  def new_security_token
    expiry = Time.at(Clock.now.to_i + token_lifetime)
    write_attribute('security_token', self.class.hashed(self.salted_password + Clock.now.to_i.to_s + rand.to_s))
    write_attribute('token_expiry', expiry)
    update_without_callbacks
    return self.security_token
  end

  def self.salted_password(salt, hashed_password)
    hashed(salt + hashed_password)
  end
end

|Home|Why Use?|Demos|About |Contact|Mail List |Group |Hpricot By Mr _Why |FAQ|Workbench|Workbench-RO|