dropsite 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. data/Rakefile +12 -3
  2. data/bin/dropsite +1 -34
  3. data/dropsite.gemspec +1 -1
  4. data/lib/dropsite/application.rb +93 -0
  5. data/lib/dropsite/dir_renderer.rb +23 -25
  6. data/lib/dropsite/plugins/image_thumbnails/assets/css/image_thumbnails.css +87 -0
  7. data/lib/dropsite/plugins/image_thumbnails/assets/css/reset.css +30 -0
  8. data/lib/dropsite/plugins/image_thumbnails/assets/images/icons/directory-large.png +0 -0
  9. data/lib/dropsite/plugins/image_thumbnails/assets/images/icons/directory.png +0 -0
  10. data/lib/dropsite/plugins/image_thumbnails/assets/images/row-bg.png +0 -0
  11. data/lib/dropsite/plugins/image_thumbnails/image_thumbnails.erb +49 -0
  12. data/lib/dropsite/plugins/image_thumbnails/image_thumbnails.rb +65 -0
  13. data/lib/dropsite/plugins/simple_index/simple_index.erb +1 -1
  14. data/lib/dropsite/plugins/simple_index/simple_index.rb +1 -1
  15. data/lib/dropsite/render_helper.rb +60 -22
  16. data/lib/dropsite/site.rb +30 -28
  17. data/lib/dropsite/site_dir.rb +84 -32
  18. data/lib/dropsite/site_file.rb +12 -11
  19. data/lib/dropsite.rb +34 -9
  20. data/test/fixtures/many_folders_public/one/two/three/four/five/six/seven/eight/file.txt +1 -0
  21. data/test/helper.rb +17 -4
  22. data/test/{test_write_site.rb → integration/test_process_site.rb} +31 -44
  23. data/test/integration/test_process_site_many_folders.rb +18 -0
  24. data/test/integration/test_process_site_with_thumbnails.rb +40 -0
  25. data/test/unit/test_application.rb +19 -0
  26. data/test/unit/test_config_file.rb +34 -0
  27. data/test/{test_render_helper.rb → unit/test_render_helper.rb} +13 -13
  28. data/test/{test_site.rb → unit/test_site.rb} +19 -3
  29. data/test/unit/test_site_dir.rb +31 -0
  30. data/test/{test_site_file.rb → unit/test_site_file.rb} +9 -9
  31. metadata +27 -19
  32. data/lib/dropsite/plugins/simple_index/assets/simple_index.js +0 -3
  33. data/test/test_site_dir.rb +0 -20
data/Rakefile CHANGED
@@ -2,12 +2,21 @@ require 'rake'
2
2
  require 'rake/testtask'
3
3
  require 'rake/rdoctask'
4
4
 
5
- Rake::TestTask.new do |t|
5
+ Rake::TestTask.new("test:units") do |t|
6
6
  t.libs << 'lib'
7
- t.pattern = 'test/**/test_*.rb'
7
+ t.libs << '.'
8
+ t.pattern = 'test/unit/**/test_*.rb'
8
9
  end
9
10
 
10
- task :default => [:test]
11
+ Rake::TestTask.new("test:integration") do |t|
12
+ t.libs << 'lib'
13
+ t.libs << '.'
14
+ t.pattern = 'test/integration/**/test_*.rb'
15
+ end
16
+
17
+ task :test => ['test:units', 'test:integration']
18
+
19
+ task :default => 'test:units'
11
20
 
12
21
  begin
13
22
  require 'rcov/rcovtask'
data/bin/dropsite CHANGED
@@ -1,38 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
-
3
- require 'optparse'
4
-
5
- # TODO: take this out later
6
2
  $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
3
  require 'dropsite'
8
- include Dropsite
9
-
10
- options = {
11
- :quiet => false
12
- }
13
-
14
- OptionParser.new do |opts|
15
- opts.on('-d', '--dropbox-home [PATH]', 'Specify Dropbox directory') {|path| options[:dropbox_home] = path }
16
- opts.on('-q', '--quiet', 'Suppress site processing output') {|| options[:quiet] = true }
17
- opts.on_tail('-h', '--help', 'Show this message') do
18
- puts opts
19
- exit
20
- end
21
- opts.on_tail('--version', 'Show version') do
22
- puts "Dropsite version: #{Dropsite::VERSION}"
23
- exit
24
- end
25
- end.parse!
26
-
27
- options[:dropbox_home] = Dropsite.find_dropbox_dir if not options[:dropbox_home]
28
-
29
- if !options[:dropbox_home] || !File.exist?(options[:dropbox_home])
30
- $stderr.puts 'Dropbox home directory cannot be found or does not exist'
31
- $stderr.puts 'Set valid directory with --dropbox-home DIRECTORY'
32
- exit 1
33
- end
34
-
35
- options[:public_dir] = File.join(options[:dropbox_home], 'Public')
36
4
 
37
- site = Dropsite::Site.new(options)
38
- site.process
5
+ Dropsite::Application.new.run
data/dropsite.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'dropsite'
3
- s.version = '0.2.1'
3
+ s.version = '0.3.0'
4
4
  s.platform = Gem::Platform::RUBY
5
5
 
6
6
  s.description = "creates index pages in your Dropbox public directory"
@@ -0,0 +1,93 @@
1
+ require 'optparse'
2
+ require 'ostruct'
3
+ require 'yaml'
4
+
5
+ module Dropsite
6
+ class Application
7
+ def run
8
+ handle_options
9
+
10
+ options.dropbox_home = Dropsite.dropbox_dir if not options.dropbox_home
11
+
12
+ if !options.dropbox_home || !File.exist?(options.dropbox_home)
13
+ $stderr.puts 'Dropbox home directory cannot be found or does not exist'
14
+ $stderr.puts 'Set valid directory with --dropbox-home DIRECTORY'
15
+ exit 1
16
+ end
17
+
18
+ if options.create_config_dir
19
+ create_config_dir
20
+ else
21
+ options.public_dir = File.join(options.dropbox_home, 'Public')
22
+ cf = ConfigFile.new.read
23
+ options.exclude = cf.exclude if cf.exist?
24
+ site = Dropsite::Site.new(options)
25
+ site.process
26
+ end
27
+ end
28
+
29
+ def options
30
+ @options ||= OpenStruct.new
31
+ end
32
+
33
+ def create_config_dir
34
+ if Dropsite.dropsite_config_dir
35
+ puts "Config directory already exists at: #{Dropsite.dropsite_config_dir}"
36
+ exit
37
+ end
38
+
39
+ config_dir = File.join(Dropsite.dropbox_dir, '.dropsite')
40
+ Dir.mkdir(config_dir)
41
+ File.open(File.join(config_dir, 'config.yml'), 'w') do |f|
42
+ # TODO: put the contents in there
43
+ f.puts ''
44
+ end
45
+ Dir.mkdir(File.join(config_dir, 'plugins'))
46
+ end
47
+
48
+ private
49
+
50
+ def handle_options
51
+ OptionParser.new do |opts|
52
+ opts.on('-d', '--dropbox-home [PATH]', 'Specify Dropbox directory') do |path|
53
+ options.dropbox_home = path
54
+ end
55
+ opts.on('-q', '--quiet', 'Suppress site processing output') do
56
+ options.quiet = true
57
+ end
58
+ opts.on('-c', '--create-config-files', 'Create a dropsite config dir in the Dropbox home') do
59
+ options.create_config_dir = true
60
+ end
61
+ opts.on_tail('-h', '--help', 'Show this message') do
62
+ puts opts
63
+ exit
64
+ end
65
+ opts.on_tail('--version', 'Show version') do
66
+ puts "Dropsite version: #{Dropsite::VERSION}"
67
+ exit
68
+ end
69
+ end.parse!
70
+ end
71
+ end
72
+
73
+ # Wraps the main configuration file. Exists mostly in case of future
74
+ # expansion of configuration options.
75
+ class ConfigFile
76
+ attr_reader :path, :exclude
77
+
78
+ def initialize(path=nil)
79
+ @path = path || File.join(Dropsite.dropsite_config_dir, 'config.yml')
80
+ end
81
+
82
+ def read
83
+ return if not exist?
84
+ config = YAML::load(IO.read(path))
85
+ @exclude = config['exclude']
86
+ self
87
+ end
88
+
89
+ def exist?
90
+ File.exist? path
91
+ end
92
+ end
93
+ end
@@ -3,39 +3,37 @@ require 'erb'
3
3
  module Dropsite
4
4
  class DirRenderer
5
5
  TEMPLATE_EXTENSIONS = ['.erb']
6
-
6
+
7
7
  @@renderers = []
8
-
8
+
9
9
  def self.inherited(subclass)
10
10
  renderer = subclass.new
11
-
11
+
12
12
  plugin_dir = File.dirname(caller[0].split(':')[0])
13
13
  template_file = Dir.entries(plugin_dir).find {|e| TEMPLATE_EXTENSIONS.include? File.extname(e)}
14
14
  renderer.template_path = template_file ? File.join(plugin_dir, template_file) : nil
15
15
  renderer.assets_dir = File.join(plugin_dir, 'assets')
16
16
  @@renderers << renderer
17
17
  end
18
-
19
- def DirRenderer.renderers
18
+
19
+ def self.renderers
20
20
  @@renderers
21
21
  end
22
-
23
- # Find the first renderer that can render the given SiteDir. Non-default (user) plugins
24
- # are searched first.
25
- def DirRenderer.find_renderer(site_dir)
26
- @@renderers.partition {|r| !r.is_default? }.flatten.find {|r| r.can_render?(site_dir)}
27
- end
28
-
29
- def DirRenderer.find_renderer_and_render(site_dir)
30
- DirRenderer.find_renderer(site_dir).render(site_dir)
31
- end
32
-
22
+
33
23
  attr_accessor :template_path, :assets_dir
34
-
35
- # Overridden in subclass if you don't want to just find and use a template
24
+
25
+ # Overridden in subclass to indicate, usually based on the SiteDir contents, whether
26
+ # this renderer can render the SiteDir. This is false by default, unless the renderer
27
+ # is a built_in (included with Dropsite).
28
+ def can_render?(site_dir)
29
+ built_in?
30
+ end
31
+
32
+ # Optionally overridden in subclass to do the work of rendering. By default this will
33
+ # find plugin_name.erb in the plugin directory and use it to render.
36
34
  def render(site_dir)
37
35
  site_dir.rendered_by = self.class
38
-
36
+
39
37
  if File.extname(template_path) == '.erb'
40
38
  @template = @template || ERB.new(IO.read(template_path))
41
39
  @template.result(site_dir.get_binding)
@@ -43,13 +41,13 @@ module Dropsite
43
41
  raise "Don't know how to render: #{template_path}"
44
42
  end
45
43
  end
46
-
47
- # Overriden in subclass or this won't do jack
48
- def can_render?(site_dir)
49
- is_default?
44
+
45
+ # Optionally overridden in subclass to write any files that will be needed to display
46
+ # the page (rendered by the render method) properly. This does nothing by default.
47
+ def write_page_assets(site_dir)
50
48
  end
51
-
52
- def is_default?
49
+
50
+ def built_in?
53
51
  false
54
52
  end
55
53
  end
@@ -0,0 +1,87 @@
1
+ body {
2
+ background-color: white;
3
+ color: #484848;
4
+ font: 13.34px Helvetica, Arial, freesans, clean, sans-serif;
5
+ font-size: 90%;
6
+ text-align: center;
7
+ }
8
+
9
+ #content {
10
+ width: 920px;
11
+ margin-left: auto;
12
+ margin-right: auto;
13
+ text-align: left;
14
+ }
15
+
16
+ #breadcrumbs {
17
+ margin-top: 20px;
18
+ font-size: 140%;
19
+ }
20
+
21
+ #breadcrumbs .sep {
22
+ margin-left: 5px;
23
+ margin-right: 10px;
24
+ }
25
+
26
+ #breadcrumbs .root-link, #breadcrumbs .parent-dir-link {
27
+ text-decoration: none;
28
+ }
29
+
30
+ #breadcrumbs .root-link:hover, .parent-dir-link:hover {
31
+ text-decoration: underline;
32
+ }
33
+
34
+ #breadcrumbs .root-link {
35
+ color: #4183C4;
36
+ font-weight: bold;
37
+ }
38
+
39
+ #breadcrumbs .parent-dir-link {
40
+ color: #4183C4;
41
+ }
42
+
43
+ #breadcrumbs .current-dir {
44
+ color: #000000;
45
+ }
46
+
47
+ #file-list {
48
+ margin-top: 10px;
49
+ width: 100%;
50
+ }
51
+
52
+ #file-list .header {
53
+ background-color: #eaeaea;
54
+ border: 1px solid #e1e1e1;
55
+ color: #999999;
56
+ height: 28px;
57
+ }
58
+
59
+ .thumb-link {
60
+ width: 152px;
61
+ margin: 3px;
62
+ padding: 5px;
63
+ float: left;
64
+ text-align: center;
65
+ border: 2px solid #fff;
66
+ font-family: Monaco, 'Courier New', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
67
+ text-decoration: none;
68
+ }
69
+
70
+ .thumb-link:hover {
71
+ border: 2px solid #4183C4;
72
+ }
73
+
74
+ .thumb-link .dir-container {
75
+ width: 100px;
76
+ height: 100px;
77
+ }
78
+
79
+ .thumb-link .dir-container img {
80
+ margin-top: 30px;
81
+ margin-left: 54px;
82
+ }
83
+
84
+ .image .name {
85
+ margin-left: auto;
86
+ margin-right: auto;
87
+ }
@@ -0,0 +1,30 @@
1
+ body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td {
2
+ margin:0;
3
+ padding:0;
4
+ }
5
+ table {
6
+ border-collapse:collapse;
7
+ border-spacing:0;
8
+ }
9
+ fieldset,img {
10
+ border:0;
11
+ }
12
+ address,caption,cite,code,dfn,em,strong,th,var {
13
+ font-style:normal;
14
+ font-weight:normal;
15
+ }
16
+ ol,ul {
17
+ list-style:none;
18
+ }
19
+ caption,th {
20
+ text-align:left;
21
+ }
22
+ h1,h2,h3,h4,h5,h6 {
23
+ font-size:100%;
24
+ font-weight:normal;
25
+ }
26
+ q:before,q:after {
27
+ content:'';
28
+ }
29
+ abbr,acronym { border:0;
30
+ }
@@ -0,0 +1,49 @@
1
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
2
+ "http://www.w3.org/TR/html4/strict.dtd">
3
+ <%
4
+ def thumb_name(image_file_name)
5
+ File.basename(image_file_name).sub(/\.\w+$/, '') + '-thumb' + File.extname(image_file_name)
6
+ end
7
+ def shorten(file_name)
8
+ if file_name.size < 20
9
+ file_name
10
+ else
11
+ file_name[0..7] + '...' + file_name[-8..-1]
12
+ end
13
+ end
14
+ %>
15
+ <html>
16
+ <head>
17
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8">
18
+ <title>My Dropbox Files<%= " - #{name}" if !root? %></title>
19
+ <%= stylesheet_link_tag 'reset' %>
20
+ <%= stylesheet_link_tag 'image_thumbnails' %>
21
+ </head>
22
+ <body>
23
+ <div id="content">
24
+ <div id="breadcrumbs">
25
+ <a class="root-link" href="<%= back_link('root') %>">my files</a>
26
+ <% each_parent_directory_link_tag(false, {:class => 'parent-dir-link'}) do |tag| %>
27
+ <span class="sep">/</span><%= tag %>
28
+ <% end %>
29
+ <% if !root? %>
30
+ <span class="sep">/</span><span class="current-dir"><%= name %></span>
31
+ <% end %>
32
+ </div>
33
+ <% dirs.sort.each do |dir| %>
34
+ <a class="thumb-link" href="<%= url_for dir %>">
35
+ <div class="dir-container">
36
+ <%= image_tag 'icons/directory-large.png' %>
37
+ </div>
38
+ <div class="name"><%= shorten dir.name %></div>
39
+ </a>
40
+ <% end %>
41
+ <% files.sort.each do |file| %>
42
+ <a class="thumb-link" href="<%= url_for file %>">
43
+ <%= page_asset_image_tag thumb_name(file.name) %>
44
+ <div class="name"><%= shorten file.name %></div>
45
+ </a>
46
+ <% end %>
47
+ </div>
48
+ </body>
49
+ </html>
@@ -0,0 +1,65 @@
1
+ class ImageThumbnails < Dropsite::DirRenderer
2
+ def can_render?(site_dir)
3
+ return false if not thumbnail_generator
4
+ !site_dir.files.empty? && site_dir.files.all? {|e| e.file_type == :image}
5
+ end
6
+
7
+ def write_page_assets(site_dir)
8
+ raise 'No thumbnail generator' if not thumbnail_generator
9
+
10
+ assets_dir = site_dir.page_assets_dir
11
+ site_dir.entries.find_all {|e| e.is_a? SiteFile}.each do |e|
12
+ src_image = e.abs_path
13
+ case thumbnail_generator
14
+ when :image_science
15
+ write_thumb_with_image_science(src_image, assets_dir)
16
+ when :rmagick
17
+ write_thumb_with_rmagick(src_image, assets_dir)
18
+ else
19
+ raise "Unrecognized thumbnail generator: #{thumbnail_generator}"
20
+ end
21
+ end
22
+ end
23
+
24
+ def built_in?
25
+ true
26
+ end
27
+
28
+ def thumbnail_generator
29
+ return @thumbnail_generator_cache if instance_variables.include?('@thumbnail_generator_cache')
30
+
31
+ begin
32
+ require 'image_science'
33
+ return @thumbnail_generator_cache = :image_science
34
+ rescue LoadError
35
+ end
36
+
37
+ begin
38
+ require 'rmagick'
39
+ return @thumbnail_generator_cache = :rmagick
40
+ rescue LoadError
41
+ end
42
+
43
+ return @thumbnail_generator_cache = nil
44
+ end
45
+
46
+ protected
47
+
48
+ def write_thumb_with_image_science(src_image, assets_dir)
49
+ ImageScience.with_image(src_image) do |img|
50
+ img.cropped_thumbnail(100) do |thumb|
51
+ thumb.save(File.join(assets_dir, thumb_file_name(src_image)))
52
+ end
53
+ end
54
+ end
55
+
56
+ def write_thumb_with_rmagick(src_image, assets_dir)
57
+ img = Magick::Image::read(src_image).first
58
+ thumb = img.resize_to_fill(100, 100)
59
+ thumb.write File.join(assets_dir, thumb_file_name(src_image))
60
+ end
61
+
62
+ def thumb_file_name(image_file_name)
63
+ File.basename(image_file_name).sub(/\.\w+$/, '') + '-thumb' + File.extname(image_file_name)
64
+ end
65
+ end
@@ -26,7 +26,7 @@
26
26
  <% @entries.sort.each do |entry| %>
27
27
  <tr class="entry">
28
28
  <td class="icon"><%= image_tag "icons/#{entry.file_type}.png" %></td>
29
- <td class="link"><a href="<%= entry.link %>"><%= entry.name %></a></td>
29
+ <td class="link"><a href="<%= url_for entry %>"><%= entry.name %></a></td>
30
30
  <td class="type"><%= entry.file_type %></td>
31
31
  <td class="size"><%= entry.size %></td>
32
32
  </tr>
@@ -1,5 +1,5 @@
1
1
  class SimpleIndex < Dropsite::DirRenderer
2
- def is_default?
2
+ def built_in?
3
3
  true
4
4
  end
5
5
  end
@@ -4,6 +4,9 @@ module Dropsite
4
4
  module RenderHelper
5
5
  attr_accessor :rendered_by
6
6
 
7
+
8
+ # Helpers for linking to other Dropsite rendered pages
9
+
7
10
  def link
8
11
  # TODO: URL escape links
9
12
  if top_level? && (!is_a? SiteDir)
@@ -20,18 +23,21 @@ module Dropsite
20
23
  end
21
24
  end
22
25
 
23
- def stylesheet_link_tag(stylesheet_name)
24
- stylesheet_name = "#{stylesheet_name}.css" if not stylesheet_name =~ /\.css$/
25
- %{<link rel="stylesheet" href="#{assets_link_base}css/#{stylesheet_name}" type="text/css" media="screen">}
26
- end
27
-
28
- def javascript_include_tag(javascript_file_name)
29
- javascript_file_name = "#{javascript_file_name}.js" if not javascript_file_name =~ /\.js$/
30
- %{<script type="text/javascript" src="#{assets_link_base}js/#{javascript_file_name}"></script>}
31
- end
32
-
33
- def image_tag(image_file_name)
34
- %{<img src="#{assets_link_base}images/#{image_file_name}" />}
26
+ # Creates a relative URL, from the page for the current object, for the given SiteItem.
27
+ # This assumes the current object is a SiteDir.
28
+ def url_for(entry)
29
+ if entry.top_level? && (!entry.is_a? SiteDir)
30
+ entry.name
31
+ else
32
+ if entry.is_a? SiteDir # TODO: do a dynamic renderable test?
33
+ entry.top_level? ? "dropsite/#{entry.path}.html" : "#{name}/#{entry.name}.html".sub(/^\//, '')
34
+ else
35
+ # Builds a link back up to the file in Public root since the pages
36
+ # are built in a parallel directory structure
37
+ dirs_up = entry.path.split(File::SEPARATOR).size - 1
38
+ (['..'] * dirs_up).join('/') + "/#{entry.path}"
39
+ end
40
+ end
35
41
  end
36
42
 
37
43
  def parent_directory_link_tag(levels_up=1, options={})
@@ -51,16 +57,6 @@ module Dropsite
51
57
  end
52
58
  end
53
59
 
54
- def assets_link_base
55
- if root?
56
- "dropsite/dropsite-assets/#{Dropsite.underscorize(rendered_by)}/"
57
- else
58
- # Work our way BACK up the path - crazy, right? Gotta do it though.
59
- dirs_up = path.split(File::SEPARATOR).size - 1
60
- (['..'] * dirs_up).join('/') + "#{'/' if dirs_up > 0}dropsite-assets/#{Dropsite.underscorize(rendered_by)}/"
61
- end
62
- end
63
-
64
60
  # Get a link to a parent page
65
61
  def back_link(levels_up=1)
66
62
  # TODO: factor this out a bit between parent_dir_name
@@ -84,6 +80,48 @@ module Dropsite
84
80
  end
85
81
  end
86
82
 
83
+
84
+ # Helpers for including assets from the plugin assets directory
85
+
86
+ def stylesheet_link_tag(stylesheet_name)
87
+ stylesheet_name = "#{stylesheet_name}.css" if not stylesheet_name =~ /\.css$/
88
+ %{<link rel="stylesheet" href="#{plugin_assets_link_base}css/#{stylesheet_name}" type="text/css" media="screen">}
89
+ end
90
+
91
+ def javascript_include_tag(javascript_file_name)
92
+ javascript_file_name = "#{javascript_file_name}.js" if not javascript_file_name =~ /\.js$/
93
+ %{<script type="text/javascript" src="#{plugin_assets_link_base}js/#{javascript_file_name}"></script>}
94
+ end
95
+
96
+ def image_tag(image_file_name)
97
+ %{<img src="#{plugin_assets_link_base}images/#{image_file_name}" />}
98
+ end
99
+
100
+
101
+ # Helpers for including assets from the page assets (assets for an individual page,
102
+ # created by the write_page_assets method for a given renderer)
103
+
104
+ # Creates an img tag for the given page asset image. This links to a file directly
105
+ # in the page asset directory and an 'image' folder is not assumed.
106
+ def page_asset_image_tag(image_file_name)
107
+ %{<img src="#{page_assets_link_base}#{image_file_name}" />}
108
+ end
109
+
110
+
111
+ def plugin_assets_link_base
112
+ if root?
113
+ "dropsite/dropsite-assets/#{Dropsite.underscorize(rendered_by)}/"
114
+ else
115
+ # Work our way BACK up the path - crazy, right? Gotta do it though.
116
+ dirs_up = path.split(File::SEPARATOR).size - 1
117
+ (['..'] * dirs_up).join('/') + "#{'/' if dirs_up > 0}dropsite-assets/#{Dropsite.underscorize(rendered_by)}/"
118
+ end
119
+ end
120
+
121
+ def page_assets_link_base
122
+ "#{root? ? 'dropsite/' : ''}#{page_assets_dir_name}/"
123
+ end
124
+
87
125
  def get_binding
88
126
  binding
89
127
  end