Shazburg-webby 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. data/History.txt +176 -0
  2. data/Manifest.txt +171 -0
  3. data/README.txt +92 -0
  4. data/Rakefile +54 -0
  5. data/bin/webby +8 -0
  6. data/bin/webby-gen +8 -0
  7. data/examples/blog/Sitefile +7 -0
  8. data/examples/blog/tasks/blog.rake +72 -0
  9. data/examples/blog/templates/atom_feed.erb +40 -0
  10. data/examples/blog/templates/blog/month.erb +22 -0
  11. data/examples/blog/templates/blog/post.erb +16 -0
  12. data/examples/blog/templates/blog/year.erb +22 -0
  13. data/examples/presentation/Sitefile +10 -0
  14. data/examples/presentation/content/css/uv/twilight.css +137 -0
  15. data/examples/presentation/content/presentation/_sample_code.txt +10 -0
  16. data/examples/presentation/content/presentation/index.txt +63 -0
  17. data/examples/presentation/content/presentation/s5/blank.gif +0 -0
  18. data/examples/presentation/content/presentation/s5/bodybg.gif +0 -0
  19. data/examples/presentation/content/presentation/s5/framing.css +23 -0
  20. data/examples/presentation/content/presentation/s5/iepngfix.htc +42 -0
  21. data/examples/presentation/content/presentation/s5/opera.css +7 -0
  22. data/examples/presentation/content/presentation/s5/outline.css +15 -0
  23. data/examples/presentation/content/presentation/s5/pretty.css +86 -0
  24. data/examples/presentation/content/presentation/s5/print.css +1 -0
  25. data/examples/presentation/content/presentation/s5/s5-core.css +9 -0
  26. data/examples/presentation/content/presentation/s5/slides.css +3 -0
  27. data/examples/presentation/content/presentation/s5/slides.js +553 -0
  28. data/examples/presentation/layouts/presentation.txt +43 -0
  29. data/examples/presentation/templates/_code_partial.erb +13 -0
  30. data/examples/presentation/templates/presentation.erb +40 -0
  31. data/examples/tumblog/Sitefile +9 -0
  32. data/examples/tumblog/content/css/tumblog.css +308 -0
  33. data/examples/tumblog/content/images/tumblog/permalink.gif +0 -0
  34. data/examples/tumblog/content/images/tumblog/rss.gif +0 -0
  35. data/examples/tumblog/content/tumblog/200806/the-noble-chicken/index.txt +12 -0
  36. data/examples/tumblog/content/tumblog/200807/historical-perspectives-on-the-classic-chicken-joke/index.txt +12 -0
  37. data/examples/tumblog/content/tumblog/200807/mad-city-chickens/index.txt +10 -0
  38. data/examples/tumblog/content/tumblog/200807/the-wisdom-of-the-dutch/index.txt +11 -0
  39. data/examples/tumblog/content/tumblog/200807/up-a-tree/index.txt +13 -0
  40. data/examples/tumblog/content/tumblog/index.txt +37 -0
  41. data/examples/tumblog/content/tumblog/rss.txt +37 -0
  42. data/examples/tumblog/layouts/tumblog/default.txt +44 -0
  43. data/examples/tumblog/layouts/tumblog/post.txt +15 -0
  44. data/examples/tumblog/lib/tumblog_helper.rb +32 -0
  45. data/examples/tumblog/tasks/tumblog.rake +30 -0
  46. data/examples/tumblog/templates/atom_feed.erb +40 -0
  47. data/examples/tumblog/templates/tumblog/conversation.erb +12 -0
  48. data/examples/tumblog/templates/tumblog/link.erb +10 -0
  49. data/examples/tumblog/templates/tumblog/photo.erb +13 -0
  50. data/examples/tumblog/templates/tumblog/post.erb +12 -0
  51. data/examples/tumblog/templates/tumblog/quote.erb +11 -0
  52. data/examples/webby/Sitefile +19 -0
  53. data/examples/webby/content/css/background.gif +0 -0
  54. data/examples/webby/content/css/blueprint/print.css +76 -0
  55. data/examples/webby/content/css/blueprint/screen.css +696 -0
  56. data/examples/webby/content/css/coderay.css +96 -0
  57. data/examples/webby/content/css/site.css +184 -0
  58. data/examples/webby/content/css/uv/twilight.css +137 -0
  59. data/examples/webby/content/index.txt +37 -0
  60. data/examples/webby/content/manual/index.txt +430 -0
  61. data/examples/webby/content/reference/index.txt +202 -0
  62. data/examples/webby/content/release-notes/rel-0-9-0/index.txt +73 -0
  63. data/examples/webby/content/robots.txt +6 -0
  64. data/examples/webby/content/script/jquery.corner.js +152 -0
  65. data/examples/webby/content/script/jquery.js +31 -0
  66. data/examples/webby/content/sitemap.txt +31 -0
  67. data/examples/webby/content/tips_and_tricks/index.txt +96 -0
  68. data/examples/webby/content/tutorial/index.txt +131 -0
  69. data/examples/webby/layouts/default.txt +55 -0
  70. data/examples/webby/templates/page.erb +10 -0
  71. data/examples/website/Sitefile +7 -0
  72. data/examples/website/content/css/blueprint/License.txt +21 -0
  73. data/examples/website/content/css/blueprint/Readme.txt +100 -0
  74. data/examples/website/content/css/blueprint/compressed/print.css +76 -0
  75. data/examples/website/content/css/blueprint/compressed/screen.css +696 -0
  76. data/examples/website/content/css/blueprint/lib/forms.css +45 -0
  77. data/examples/website/content/css/blueprint/lib/grid.css +193 -0
  78. data/examples/website/content/css/blueprint/lib/grid.png +0 -0
  79. data/examples/website/content/css/blueprint/lib/ie.css +30 -0
  80. data/examples/website/content/css/blueprint/lib/reset.css +39 -0
  81. data/examples/website/content/css/blueprint/lib/typography.css +116 -0
  82. data/examples/website/content/css/blueprint/plugins/buttons/Readme +31 -0
  83. data/examples/website/content/css/blueprint/plugins/buttons/buttons.css +97 -0
  84. data/examples/website/content/css/blueprint/plugins/buttons/icons/cross.png +0 -0
  85. data/examples/website/content/css/blueprint/plugins/buttons/icons/key.png +0 -0
  86. data/examples/website/content/css/blueprint/plugins/buttons/icons/tick.png +0 -0
  87. data/examples/website/content/css/blueprint/plugins/css-classes/Readme +14 -0
  88. data/examples/website/content/css/blueprint/plugins/css-classes/css-classes.css +24 -0
  89. data/examples/website/content/css/blueprint/plugins/fancy-type/Readme +22 -0
  90. data/examples/website/content/css/blueprint/plugins/fancy-type/fancy-type-compressed.css +5 -0
  91. data/examples/website/content/css/blueprint/plugins/fancy-type/fancy-type.css +74 -0
  92. data/examples/website/content/css/blueprint/print.css +68 -0
  93. data/examples/website/content/css/blueprint/screen.css +22 -0
  94. data/examples/website/content/css/coderay.css +111 -0
  95. data/examples/website/content/css/site.css +67 -0
  96. data/examples/website/content/index.txt +19 -0
  97. data/examples/website/layouts/default.txt +58 -0
  98. data/examples/website/lib/breadcrumbs.rb +28 -0
  99. data/examples/website/templates/_partial.erb +10 -0
  100. data/examples/website/templates/page.erb +18 -0
  101. data/examples/website/templates/presentation.erb +40 -0
  102. data/lib/webby.rb +227 -0
  103. data/lib/webby/apps.rb +12 -0
  104. data/lib/webby/apps/generator.rb +283 -0
  105. data/lib/webby/apps/main.rb +221 -0
  106. data/lib/webby/auto_builder.rb +83 -0
  107. data/lib/webby/builder.rb +183 -0
  108. data/lib/webby/core_ext/enumerable.rb +11 -0
  109. data/lib/webby/core_ext/hash.rb +28 -0
  110. data/lib/webby/core_ext/kernel.rb +21 -0
  111. data/lib/webby/core_ext/string.rb +163 -0
  112. data/lib/webby/core_ext/time.rb +9 -0
  113. data/lib/webby/filters.rb +91 -0
  114. data/lib/webby/filters/basepath.rb +97 -0
  115. data/lib/webby/filters/erb.rb +9 -0
  116. data/lib/webby/filters/haml.rb +18 -0
  117. data/lib/webby/filters/markdown.rb +16 -0
  118. data/lib/webby/filters/outline.rb +308 -0
  119. data/lib/webby/filters/sass.rb +17 -0
  120. data/lib/webby/filters/slides.rb +56 -0
  121. data/lib/webby/filters/textile.rb +16 -0
  122. data/lib/webby/filters/tidy.rb +76 -0
  123. data/lib/webby/helpers.rb +30 -0
  124. data/lib/webby/helpers/capture_helper.rb +141 -0
  125. data/lib/webby/helpers/coderay_helper.rb +69 -0
  126. data/lib/webby/helpers/graphviz_helper.rb +136 -0
  127. data/lib/webby/helpers/tag_helper.rb +65 -0
  128. data/lib/webby/helpers/tex_img_helper.rb +133 -0
  129. data/lib/webby/helpers/ultraviolet_helper.rb +63 -0
  130. data/lib/webby/helpers/url_helper.rb +235 -0
  131. data/lib/webby/link_validator.rb +152 -0
  132. data/lib/webby/renderer.rb +379 -0
  133. data/lib/webby/resources.rb +96 -0
  134. data/lib/webby/resources/db.rb +251 -0
  135. data/lib/webby/resources/file.rb +221 -0
  136. data/lib/webby/resources/layout.rb +63 -0
  137. data/lib/webby/resources/page.rb +118 -0
  138. data/lib/webby/resources/partial.rb +79 -0
  139. data/lib/webby/resources/resource.rb +160 -0
  140. data/lib/webby/resources/static.rb +52 -0
  141. data/lib/webby/stelan/mktemp.rb +135 -0
  142. data/lib/webby/stelan/paginator.rb +150 -0
  143. data/lib/webby/stelan/spawner.rb +339 -0
  144. data/lib/webby/tasks/build.rake +27 -0
  145. data/lib/webby/tasks/create.rake +22 -0
  146. data/lib/webby/tasks/deploy.rake +22 -0
  147. data/lib/webby/tasks/growl.rake +15 -0
  148. data/lib/webby/tasks/heel.rake +28 -0
  149. data/lib/webby/tasks/validate.rake +19 -0
  150. data/spec/core_ext/hash_spec.rb +47 -0
  151. data/spec/core_ext/string_spec.rb +110 -0
  152. data/spec/core_ext/time_spec.rb +19 -0
  153. data/spec/spec.opts +1 -0
  154. data/spec/spec_helper.rb +14 -0
  155. data/spec/webby/apps/generator_spec.rb +111 -0
  156. data/spec/webby/apps/main_spec.rb +75 -0
  157. data/spec/webby/helpers/capture_helper_spec.rb +56 -0
  158. data/spec/webby/resources/file_spec.rb +104 -0
  159. data/spec/webby/resources_spec.rb +17 -0
  160. data/tasks/ann.rake +81 -0
  161. data/tasks/bones.rake +21 -0
  162. data/tasks/gem.rake +126 -0
  163. data/tasks/git.rake +41 -0
  164. data/tasks/manifest.rake +49 -0
  165. data/tasks/notes.rake +28 -0
  166. data/tasks/post_load.rake +39 -0
  167. data/tasks/rdoc.rake +51 -0
  168. data/tasks/rubyforge.rake +57 -0
  169. data/tasks/setup.rb +268 -0
  170. data/tasks/spec.rake +55 -0
  171. data/tasks/website.rake +38 -0
  172. metadata +287 -0
@@ -0,0 +1,65 @@
1
+ require 'erb'
2
+ require 'set'
3
+
4
+ # :stopdoc:
5
+ class ERB
6
+ module Util
7
+ HTML_ESCAPE = { '&' => '&amp;', '"' => '&quot;', '>' => '&gt;', '<' => '&lt;' }
8
+
9
+ def html_escape(s)
10
+ s.to_s.gsub(/[&\"><]/) { |special| HTML_ESCAPE[special] }
11
+ end
12
+ end
13
+ end
14
+ # :startdoc:
15
+
16
+ module Webby::Helpers
17
+
18
+ # Provides methods to generate HTML tags programmatically.
19
+ # By default, they output XHTML compliant tags.
20
+ #
21
+ module TagHelper
22
+ include ERB::Util
23
+
24
+ BOOLEAN_ATTRIBUTES = Set.new(%w(disabled readonly multiple))
25
+
26
+ # Returns an escaped version of +html+ without affecting existing escaped
27
+ # entities.
28
+ #
29
+ # ==== Examples
30
+ # escape_once("1 > 2 &amp; 3")
31
+ # # => "1 &lt; 2 &amp; 3"
32
+ #
33
+ # escape_once("&lt;&lt; Accept & Checkout")
34
+ # # => "&lt;&lt; Accept &amp; Checkout"
35
+ #
36
+ def escape_once( html )
37
+ html.to_s.gsub(/[\"><]|&(?!([a-zA-Z]+|(#\d+));)/) { |special| ERB::Util::HTML_ESCAPE[special] }
38
+ end
39
+
40
+ private
41
+
42
+ def tag_options( options, escape = true )
43
+ unless options.empty?
44
+ attrs = []
45
+ if escape
46
+ options.each do |key, value|
47
+ next if value.nil?
48
+ key = key.to_s
49
+ value = BOOLEAN_ATTRIBUTES.include?(key) ? key : escape_once(value)
50
+ attrs << %Q(#{key}="#{value}")
51
+ end
52
+ else
53
+ attrs = options.map {|key, value| %Q(#{key}="#{value}")}
54
+ end
55
+ %Q( #{attrs.sort * ' '}) unless attrs.empty?
56
+ end
57
+ end
58
+
59
+ end # module TagHelper
60
+
61
+ register(TagHelper)
62
+
63
+ end # module Webby::Helpers
64
+
65
+ # EOF
@@ -0,0 +1,133 @@
1
+ require Webby.libpath(*%w[webby stelan mktemp])
2
+ require 'fileutils'
3
+
4
+ module Webby::Helpers
5
+ module TexImgHelper
6
+
7
+ # The +tex2img+ method converts a a section of mathematical TeX script
8
+ # into an image and embeds the resulting image into the page. The TeX
9
+ # engine must be installed on your system along with the ImageMagick
10
+ # +convert+ program.
11
+ #
12
+ # Options can be passed to the TeX engine via attributes in the
13
+ # +tex2img+ method.
14
+ #
15
+ # <% tex2img( "wave_eq", :path => "images", :alt => "wave equation" ) do -%>
16
+ # $\psi_{tot}(x,-t_0,r) = \frac{1}{(2\pi)^2} \int\!\!\!\int
17
+ # \tilde\Psi_{tot}\left(k_x,\frac{c}{2}\sqrt{k_x^2 + k_r^2},r=0\right)$
18
+ # <% end -%>
19
+ #
20
+ # The supported TeX options are the following:
21
+ #
22
+ # :path : where generated images will be stored
23
+ # [default is "/"]
24
+ # :type : the type of image to generate (png, jpeg, gif)
25
+ # [default is png]
26
+ # :bg : the background color of the image (color name,
27
+ # TeX color spec, or #aabbcc) [default is white]
28
+ # :fg : the foreground color of the image (color name,
29
+ # TeX color spec, or #aabbcc) [default is black]
30
+ # :resolution : the desired resolution in dpi (HxV)
31
+ # [default is 150x150]
32
+ #
33
+ # the following options are passed as-is to the generated <img /> tag
34
+ # :style : CSS styles to apply to the <img />
35
+ # :class : CSS class to apply to the <img />
36
+ # :id : HTML identifier
37
+ # :alt : alternate text for the <img />
38
+ #
39
+ def tex2img( *args, &block )
40
+ opts = args.last.instance_of?(Hash) ? args.pop : {}
41
+ name = args.first
42
+ raise 'TeX graphics must have a name' if name.nil?
43
+
44
+ text = capture_erb(&block)
45
+ return if text.empty?
46
+
47
+ defaults = ::Webby.site.tex2img
48
+ path = opts.getopt(:path, defaults[:path])
49
+ type = opts.getopt(:type, defaults[:type])
50
+ bg = opts.getopt(:bg, defaults[:bg])
51
+ fg = opts.getopt(:fg, defaults[:fg])
52
+ res = opts.getopt(:resolution, defaults[:resolution])
53
+
54
+ # fix color escaping
55
+ fg = fg =~ %r/^[a-zA-Z]+$/ ? fg : "\"#{fg}\""
56
+ bg = bg =~ %r/^[a-zA-Z]+$/ ? bg : "\"#{bg}\""
57
+
58
+ # generate the image filename based on the path, graph name, and type
59
+ # of image to generate
60
+ image_fn = path.nil? ? name.dup : ::File.join(path, name)
61
+ image_fn = ::File.join('', image_fn) << '.' << type
62
+
63
+ # generate the image using convert -- but first ensure that the
64
+ # path exists
65
+ out_dir = ::Webby.site.output_dir
66
+ out_file = ::File.join('..', out_dir, image_fn)
67
+ FileUtils.mkpath(::File.join(out_dir, path)) unless path.nil?
68
+
69
+ tex = <<-TEX
70
+ \\nonstopmode
71
+ \\documentclass{article}
72
+ \\usepackage[T1]{fontenc}
73
+ \\usepackage{amsmath,amsfonts,amssymb,wasysym,latexsym,marvosym,txfonts}
74
+ \\usepackage[pdftex]{color}
75
+ \\pagestyle{empty}
76
+ \\begin{document}
77
+ \\fontsize{12}{24}
78
+ \\selectfont
79
+ \\color{white}
80
+ \\pagecolor{black}
81
+ \\[
82
+ #{text}
83
+ \\]
84
+ \\end{document}
85
+ TEX
86
+ tex.gsub!(%r/\n\s+/, "\n").strip!
87
+
88
+ # make a temporarty directory to store all the TeX files
89
+ pwd = Dir.pwd
90
+ tmpdir = ::Webby::MkTemp.mktempdir('tex2img_XXXXXX')
91
+
92
+ begin
93
+ Dir.chdir(tmpdir)
94
+ File.open('out.tex', 'w') {|fd| fd.puts tex}
95
+ dev_null = test(?e, "/dev/null") ? "/dev/null" : "NUL:"
96
+
97
+ %x[pdflatex -interaction=batchmode out.tex &> #{dev_null}]
98
+
99
+ convert = "\\( -density #{res} out.pdf -trim +repage \\) "
100
+ convert << "\\( -clone 0 -negate -background #{fg} -channel A -combine \\) "
101
+ convert << "\\( -clone 0 -background #{bg} -channel A -combine \\) "
102
+ convert << "-delete 0 -compose dst-over -composite #{out_file}"
103
+ %x[convert #{convert} &> #{dev_null}]
104
+ ensure
105
+ Dir.chdir(pwd)
106
+ FileUtils.rm_rf(tmpdir) if test(?e, tmpdir)
107
+ end
108
+
109
+ # generate the HTML img tag to insert back into the document
110
+ out = "<img src=\"#{image_fn}\""
111
+ %w[class style id alt].each do |atr|
112
+ val = opts.getopt(atr)
113
+ next if val.nil?
114
+ out << " %s=\"%s\"" % [atr, val]
115
+ end
116
+ out << " />\n"
117
+
118
+ # put some guards around the output (specifically for textile)
119
+ out = _guard(out)
120
+
121
+ concat_erb(out, block.binding)
122
+ return
123
+ end
124
+ end # module TexImgHelper
125
+
126
+ if cmd_available?(%w[pdflatex --version]) \
127
+ and cmd_available?(%w[convert --help])
128
+ register(TexImgHelper)
129
+ end
130
+
131
+ end # module Webby::Helpers
132
+
133
+ # EOF
@@ -0,0 +1,63 @@
1
+ # This code was provided by Guillaume Carbonneau -- http://radr.ca/
2
+ # Many thanks for his support of Webby!
3
+
4
+ if try_require 'uv'
5
+
6
+ module Webby::Helpers
7
+ module UltraVioletHelper
8
+
9
+ # The +uv+ method applies syntax highlighting to source code embedded
10
+ # in a webpage. The UltraViolet highlighting engine is used for the HTML
11
+ # markup of the source code. The page sections to be highlighted are given
12
+ # as blocks of text to the +uv+ method.
13
+ #
14
+ # Options can be passed to the UltraViolet engine via attributes in the
15
+ # +uv+ method.
16
+ #
17
+ # <% uv( :lang => "ruby", :line_numbers => true ) do -%>
18
+ # # Initializer for the class.
19
+ # def initialize( string )
20
+ # @str = string
21
+ # end
22
+ # <% end -%>
23
+ #
24
+ # The supported UltraViolet options are the following:
25
+ #
26
+ # :lang : the language to highlight (ruby, c, html, ...)
27
+ # [defaults to 'ruby']
28
+ # :line_numbers : true or false [defaults to false]
29
+ # :theme : see list of available themes in ultraviolet
30
+ # [defaults to 'mac_classic']
31
+ #
32
+ # The defaults can be overridden for an entire site by changing the SITE.uv
33
+ # options hash in the Rakefile.
34
+ #
35
+ def uv( *args, &block )
36
+ opts = args.last.instance_of?(Hash) ? args.pop : {}
37
+
38
+ text = capture_erb(&block)
39
+ return if text.empty?
40
+
41
+ defaults = ::Webby.site.uv
42
+ lang = opts.getopt(:lang, defaults[:lang])
43
+ line_numbers = opts.getopt(:line_numbers, defaults[:line_numbers])
44
+ theme = opts.getopt(:theme, defaults[:theme])
45
+
46
+ out = '<div class="UltraViolet">'
47
+ out << Uv.parse(text, "xhtml", lang, line_numbers, theme)
48
+ out << '</div>'
49
+
50
+ # put some guards around the output (specifically for textile)
51
+ out = _guard(out)
52
+
53
+ concat_erb(out, block.binding)
54
+ return
55
+ end
56
+ end # module UltraVioletHelper
57
+
58
+ register(UltraVioletHelper)
59
+
60
+ end # module Webby::Helpers
61
+ end # try_require
62
+
63
+ # EOF
@@ -0,0 +1,235 @@
1
+ module Webby::Helpers
2
+
3
+ #
4
+ #
5
+ module UrlHelper
6
+
7
+ # call-seq:
8
+ # url_for( name, opts = {} )
9
+ #
10
+ # Creates a URL for the given _name_ and _opts_. If _name_ is a string
11
+ # then it is used as the URL base. If _name_ is a Resource then it is
12
+ # converted to a URL by calling its +url+ method.
13
+ #
14
+ # ==== Options
15
+ #
16
+ # * <tt>:escape</tt> -- determines whether the returned URL will be HTML escaped or not (+true+ by default)
17
+ # * <tt>:anchor</tt> -- specifies the anchor name to be appended to the path
18
+ #
19
+ # ==== Examples
20
+ #
21
+ # <%= url_for('/some/page.html') %>
22
+ # # => /some/page
23
+ #
24
+ # <%= url_for('/some/page.html', :anchor => 'tidbit') %>
25
+ # # => /some/page#tidbit
26
+ #
27
+ # <%= url_for(@page) %>
28
+ # # => /current/page.html
29
+ #
30
+ # <%= url_for(@page, :anchor => 'this&that') %>
31
+ # # => /current/page.html#this&amp;that
32
+ #
33
+ def url_for( *args )
34
+ opts = Hash === args.last ? args.pop : {}
35
+ obj = args.first
36
+
37
+ anchor = opts.delete(:anchor)
38
+ escape = opts.has_key?(:escape) ? opts.delete(:escape) : true
39
+
40
+ url = Webby::Resources::Resource === obj ? obj.url : obj.to_s
41
+ url = escape_once(url) if escape
42
+ url << "#" << anchor if anchor
43
+
44
+ return url
45
+ end
46
+
47
+ # call-seq:
48
+ # url_for_page( :key => value, :url => {} )
49
+ #
50
+ # Creates a URL for the page identified by the set of <em>:key /
51
+ # value</em> pairs. The <em>:url</em> options are passed to the url_for
52
+ # method for final URL creation; see the url_for method for
53
+ # documentation on those options.
54
+ #
55
+ # The Resources::DB#find method is used to locate the page; see the find
56
+ # method for the available options.
57
+ #
58
+ # ==== Examples
59
+ #
60
+ # <%= url_for_page(:title => 'Funny Story', :anchor => 'punchline') %>
61
+ # # => /humor/funny_story.html#punchline
62
+ #
63
+ def url_for_page( opts = {} )
64
+ opts = opts.symbolize_keys
65
+ url_opts = opts.delete(:url)
66
+
67
+ p = @pages.find(opts)
68
+ raise ::Webby::Error,
69
+ "could not find requested page: #{opts.inspect}" if p.nil?
70
+
71
+ self.url_for(p, url_opts)
72
+ end
73
+
74
+ # call-seq:
75
+ # link_to( name, url, :attrs => {} )
76
+ #
77
+ # Create an HTTP anchor tag with
78
+ #
79
+ # url can be a url string, a page, :back, or nothing
80
+ #
81
+ # :attrs are used to generate HTML anchor tag attributes
82
+ #
83
+ # ==== Examples
84
+ #
85
+ # <%= link_to('Google', 'http://www.google.com/', :attrs => {:name => 'google'}) %>
86
+ # # => <a href="http://www.google.com/" name="google">Google</a>
87
+ #
88
+ # <%= link_to('A Page', @page, :anchor => 'blah') %>
89
+ # # => <a href="/a/page.html#blah">A Page</a>
90
+ #
91
+ def link_to( name, *args )
92
+ opts = Hash === args.last ? args.pop : {}
93
+ obj = args.first
94
+ attrs = opts.delete(:attrs)
95
+
96
+ url = case obj
97
+ when String, Webby::Resources::Resource
98
+ self.url_for(obj, opts)
99
+ when ::Webby::Paginator::Page
100
+ self.url_for(obj.url, opts)
101
+ when :back
102
+ 'javascript:history.back()'
103
+ else
104
+ self.url_for(name, opts)
105
+ end
106
+
107
+ if attrs
108
+ html_opts = attrs.stringify_keys
109
+ href = html_opts.has_key? 'href'
110
+ attrs = tag_options(html_opts)
111
+ else
112
+ href = false
113
+ attrs = nil
114
+ end
115
+
116
+ href_attr = href ? nil : %Q(href="#{url}")
117
+ "<a #{href_attr}#{attrs}>#{name || h(url)}</a>"
118
+ end
119
+
120
+ # call-seq:
121
+ # link_to_page( name )
122
+ # link_to_page( :key => value )
123
+ # link_to_page( name, :key => value )
124
+ # link_to_page( page )
125
+ #
126
+ # Creates a link tag of the given _name_ using a URL created by finding
127
+ # the associated page from the key/value pairs. If the key/value pairs are
128
+ # omitted, the _name_ is used in conjunction with the default site +find_by+
129
+ # attribute. Unless changed by the user, the default +find_by+ attribute
130
+ # is the page title.
131
+ #
132
+ # Pages are found using key/value pairs. The key is any of the page
133
+ # attributes, and the value is what that attribute should be. Any number
134
+ # of key/value pairs can be included, but all values must equal the
135
+ # corresponding page attributes for a match to be found -- i.e. the
136
+ # comparisons are joined by AND operations to determine a match.
137
+ #
138
+ # In the absence of any key/value pairs -- just a name was given -- then
139
+ # the default site +find_by+ attribute is used, and the name is compared
140
+ # against this attribute from the page. The default +find_by+ attribue is
141
+ # set in the Rakefile or in the <tt>Webby.site.find_by</tt> parameter.
142
+ #
143
+ # Several options can be passed to the method to determin how URLs are
144
+ # created and to specify any HTML attributes on the returned link tag. The
145
+ # URL options are given as a hash to the <tt>:url</tt> key. The HTML
146
+ # attributes are given as a hash to the <tt>:attrs</tt> key.
147
+ #
148
+ # See the +url_for+ method for a desciption of the <tt>:url</tt> options.
149
+ # See the +link_to+ method for a description of the <tt>:attrs</tt>
150
+ # options.
151
+ #
152
+ # ==== Examples
153
+ #
154
+ # <%= link_to_page('Funny Story', :url => {:anchor => 'punchline'}) %>
155
+ # # => <a href="/humor/funny_story.html#punchline">Funny Story</a>
156
+ #
157
+ # <%= link_to_page('Hilarious', :title => 'Funny Story') %>
158
+ # # => <a href="/humor/funn_story.html">Hilarious</a>
159
+ #
160
+ def link_to_page( *args )
161
+ self.link_to(*_find_page(args))
162
+ end
163
+
164
+ # call-seq:
165
+ # link_to_page_unless_current( name )
166
+ # link_to_page_unless_current( :key => value )
167
+ # link_to_page_unless_current( name, :key => value )
168
+ # link_to_page_unless_current( page )
169
+ #
170
+ # This function operates in the same fashion as the +link_to_page+ fuction
171
+ # with the exception that if the page to be linked to is the current page,
172
+ # then only the _name_ is rendered without an HTML anchor tag.
173
+ #
174
+ # ==== Examples
175
+ #
176
+ # <%= link_to_page_unless_current('Funny Story') %>
177
+ # # => <a href="/humor/funny_story.html">Funny Story</a>
178
+ #
179
+ # <%= link_to_page_unless_current(@page) %>
180
+ # # => This Page
181
+ #
182
+ def link_to_page_unless_current( *args )
183
+ name, page, link_opts = _find_page(args)
184
+ return name if @page == page
185
+
186
+ self.link_to(name, page, link_opts)
187
+ end
188
+
189
+
190
+ private
191
+
192
+ # call-seq:
193
+ # _find_page( name, opts = {} )
194
+ # _find_page( :key => value, [:key => value, ...], opts = {} )
195
+ # _find_page( name, :key => value, [:key => value, ...], opts = {} )
196
+ # _find_page( page, opts = {} )
197
+ #
198
+ # Returns an array of the [name, page, options].
199
+ #
200
+ # ==== Options
201
+ #
202
+ # * <tt>:url</tt> -- hash of options for the +url_for+ method
203
+ # * <tt>:attrs</tt> -- hash of options for the +link_to+ method
204
+ #
205
+ def _find_page( args )
206
+ raise ArgumentError, 'wrong number of arguments (0 for 1)' if args.empty?
207
+
208
+ opts = Hash === args.last ? args.pop : {}
209
+ name = args.first
210
+ link_opts = opts.delete(:url) || {}
211
+ link_opts[:attrs] = opts.delete(:attrs)
212
+
213
+ if Webby::Resources::Resource === name
214
+ p, name = name, nil
215
+ elsif opts.empty? && name
216
+ opts[Webby.site.find_by.to_sym] = name
217
+ p = @pages.find(opts)
218
+ else
219
+ p = @pages.find(opts)
220
+ end
221
+
222
+ raise ::Webby::Error,
223
+ "could not find requested page: #{opts.inspect}" if p.nil?
224
+
225
+ name = p.title || p.filename if name.nil?
226
+ return [h(name), p, link_opts]
227
+ end
228
+
229
+ end # module UrlHelper
230
+
231
+ register(UrlHelper)
232
+
233
+ end # module Webby::Helpers
234
+
235
+ # EOF