Changesets can be listed by changeset number.
The Git repository is here.
Changeset 233
New tag which allows insertion of a formatted, informative table
for listing drop box contents. Fairly complex use cases available;
see the page_context.rb comments for the new tag (or the diff) for
documentation.
- Comitted by: rool
- Date: Thursday April 24 18:35:06 2008 (over 16 years ago)
Affected files:
rool/rails/radiant/trunk/app/models/page_context.rb:
prev. | current | |
end | ||
# | ||
432 | # <r:linked_parsed_directory_listing dir="search_directory" link_base="foo" link_icon="bar" /> | |
433 | # | |
434 | # Returns a set of HTML tables that enumerate a directory in a parsed | |
435 | # fashion. Certain magic directories are ignored (CVS, .svn). The | |
436 | # directory can contain a file 'config.yml' in subdirectory 'config', | |
437 | # which works as described below. Each table corresponds to a group of | |
438 | # items in a drop box, with a header above naming the group. | |
439 | # | |
440 | # | |
441 | # Drop box display configuration | |
442 | # ============================== | |
443 | # | |
444 | # Filenames of entries in the drop box are converted by looking for | |
445 | # everything up to the first '.' and treating this as a leafname. The | |
446 | # leafname is looked up in the configuration hash. After the '.', | |
447 | # anything up to but not including a filename extension is treated as | |
448 | # a version string. Filename extensions are assumed to be present and | |
449 | # form a three-letter code after a final '.'. For 'tar.gz', use 'tgz'. | |
450 | # | |
451 | # Each entry in the tables of items can have a 'Details' column. | |
452 | # These contain links, formed by appending the leafname as described | |
453 | # above to whatever value is provided in the Radiant tag's "link_base" | |
454 | # attribute. If the attribute is omitted, the column is omitted too. | |
455 | # If included, the links contain the text "Details". To use an icon | |
456 | # instead, provide a path to the icon in the "link_icon" attribute. | |
457 | # | |
458 | # Rails helper methods are used to create human-readable versions of | |
459 | # default strings from the path components. For example, see: | |
460 | # | |
461 | # http://api.rubyonrails.com/classes/ActiveSupport/CoreExtensions/String/Inflections.html | |
462 | # | |
463 | # The configuration file is optional and allows the writer to both | |
464 | # override strings generated with the above method, as well as specify | |
465 | # things which cannot be determined purely from the drop box filenames. | |
466 | # Syntax are as follows: | |
467 | # | |
468 | # appname_1: | |
469 | # config_item_1: config_value | |
470 | # config_item_1: config_value | |
471 | # config_item_1: config_value | |
472 | # | |
473 | # appname_1: | |
474 | # config_item_1: config_value | |
475 | # config_item_1: config_value | |
476 | # config_item_1: config_value | |
477 | # | |
478 | # ...and so-on, i.e. it's a very simple usage of the YAML syntax. | |
479 | # | |
480 | # Items which override values determined from the filename | |
481 | # -------------------------------------------------------- | |
482 | # | |
483 | # name: 'Component display name" | |
484 | # version: 'Version string' | |
485 | # icon: 'Icon filename name' (no path components allowed) | |
486 | # link: 'Details link' (Wiki by default; for links within the | |
487 | # ROOL site, use "/foo/bar/baz.html" - | |
488 | # i.e. do NOT include the host name) | |
489 | # | |
490 | # Items which are optional | |
491 | # ------------------------ | |
492 | # | |
493 | # info: 'One-liner description' (else "-" by default) | |
494 | # group: 'Group name' (groups are sorted alphabetically and | |
495 | # ungrouped items are listed afterwards; | |
496 | # use singular non-abbreviated forms) | |
497 | # | |
498 | # | |
499 | # Icons and overall layout | |
500 | # ======================== | |
501 | # | |
502 | # Icons must be placed in subdirectory 'icons', again within the | |
503 | # drop box, so that it forms a tree as follows: | |
504 | # | |
505 | # dropbox_root | |
506 | # | | |
507 | # +--config | |
508 | # | | | |
509 | # | +--config.yml | |
510 | # | | |
511 | # +--icons | |
512 | # | | | |
513 | # | +--app1.png | |
514 | # | +--app2.png | |
515 | # | +--etc... | |
516 | # | | |
517 | # +--app1.vsnstring.zip | |
518 | # +--app2.vsnstring.zip | |
519 | # +--etc... | |
520 | # | |
521 | # If an icon cannot be found, "icons/_default.png" is tried. If that | |
522 | # doesn't exist either, the relevant table cell will be left blank. | |
523 | # | |
524 | define_tag 'linked_parsed_directory_listing' do |tag| | |
525 | unless dir = tag.attr['dir'] | |
526 | raise TagError.new("`linked_parsed_directory_listing' tag must contain `dir' attribute") | |
527 | end | |
528 | ||
529 | link_base = tag.attr['link_base'] | |
530 | link_icon = tag.attr['link_icon'] | |
531 | ||
532 | parsed_directory_list_in_table(PATH_TO_DOCUMENT_ROOT, dir, link_base, link_icon) | |
533 | end | |
534 | ||
535 | # | |
# <r:find url="value_to_find">...</r:find> | ||
# | ||
# Inside this tag all page related tags refer to the tag found at the 'url' attribute. | ||
... | ... | |
return regexp | ||
end | ||
603 | | |
707 | # Support the various directory listing tags. Returns an array of items | |
708 | # describing a directory contents and the contents of any subdirectories | |
709 | # as a flat unsorted list. The last parameter is 'false' to avoid scanning | |
710 | # to a level beyond the current directory. | |
# | ||
require 'find' | ||
# | ||
607 | | |
608 | ||
609 | | |
714 | def recursive_directory_list(base, dir, recurse = true) | |
715 | # Partly based on: | |
# | ||
# http://www.oreillynet.com/onjava/blog/2006/03/recursive_directory_list_with.html | ||
excludes = [ 'CVS', '.svn' ] | ||
614 | | |
collect = []; | ||
721 | dir = "#{base}#{dir}" | |
722 | first = true | |
617 | | |
618 | ||
Find.find(dir) do |path| | ||
if FileTest.directory?(path) | ||
621 | | |
622 | | |
726 | if (recurse == false) | |
727 | if (first) | |
728 | first = false | |
729 | next | |
730 | else | |
731 | Find.prune | |
732 | end | |
else | ||
624 | | |
734 | if (excludes.include?(File.basename(path))) | |
735 | Find.prune # Don't look any further into this directory. | |
736 | else | |
737 | next | |
738 | end | |
end | ||
else | ||
mod = File.mtime(path) | ||
... | ... | |
end | ||
end | ||
637 | | |
751 | return collect | |
752 | end | |
753 | ||
754 | # Support the linked_directory_listing tag. | |
755 | # | |
756 | def recursive_directory_list_in_li_tags(base, dir) | |
757 | html = '' | |
758 | ||
759 | recursive_directory_list(base, dir).sort do |x, y| | |
#x[:leaf] <=> y[:leaf] | ||
y[:mod] <=> x[:mod] | ||
end.each do |entry| | ||
... | ... | |
rescue | ||
nil | ||
end | ||
783 | ||
784 | # Support the linked_parsed_directory_listing tag. | |
785 | # | |
786 | def parsed_directory_list_in_table( base, dir, link_base, link_icon ) | |
787 | ||
788 | list = recursive_directory_list(base, dir, false) | |
789 | ||
790 | # Load the configuration file, if provided | |
791 | ||
792 | begin | |
793 | configuration = YAML.load_file("#{base}#{dir}/config/config.yml") | |
794 | rescue | |
795 | configuration = {} | |
796 | end | |
797 | ||
798 | # Assemble the configured strings within groups | |
799 | ||
800 | groups = {} | |
801 | ||
802 | list.each do |entry| | |
803 | ||
804 | leaf = entry[:leaf] | |
805 | first_dot = leaf.index('.') || leaf.length | |
806 | last_dot = leaf.rindex('.') || leaf.length | |
807 | base_name = leaf[0...first_dot] | |
808 | config = configuration[base_name] || {} | |
809 | ||
810 | name = config['name'] || base_name.humanize.titleize | |
811 | version = config['version'] || leaf[(first_dot + 1)...last_dot] | |
812 | icon = config['icon'] || "#{base_name}.png" | |
813 | link = config['link'] || "#{link_base}#{name}" | |
814 | info = config['info'] || '-' | |
815 | group = config['group'] || :Ungrouped | |
816 | ||
817 | icon = "#{dir}/icons/#{icon}" | |
818 | ||
819 | unless (File.exist?("#{base}#{icon}")) | |
820 | icon = "#{dir}/icons/_default.png" | |
821 | unless (File.exist?("#{base}#{icon}")) | |
822 | icon = '' | |
823 | end | |
824 | end | |
825 | ||
826 | groups[ group ] = [] if (groups[ group ].nil?) | |
827 | groups[ group ].push( { | |
828 | :name => name, | |
829 | :version => version, | |
830 | :icon => icon, | |
831 | :link => link, | |
832 | :info => info, | |
833 | :raw => entry | |
834 | } ) | |
835 | end | |
836 | ||
837 | html = '' | |
838 | ||
839 | groups.keys.sort do | x, y | | |
840 | ||
841 | # Sort the groups, pushing keys of Symbol class (i.e. ':Ungrouped') | |
842 | # to the end. | |
843 | ||
844 | if ( x.class == Symbol ) | |
845 | 1 | |
846 | elsif( y.class == Symbol ) | |
847 | -1 | |
848 | else | |
849 | x <=> y | |
850 | end | |
851 | ||
852 | end.each do | group_key | | |
853 | ||
854 | # For each sorted key, output a table. | |
855 | ||
856 | count = 0 | |
857 | html << "<h3>#{group_key}</h3>\n" | |
858 | html << "<table width=\"100%\" class=\"parsed_directory_listing\" border=\"0\">\n" | |
859 | html << "<tr><th>Icon</th><th align=\"left\">Name</th><th align=\"left\">Description</th><th>Version</th><th>Size</th>" | |
860 | html << "<th>Details</th>" if (link_base) | |
861 | html << "</tr>\n" | |
862 | ||
863 | # Sort the items inside each group by name and output each in a table | |
864 | # row. | |
865 | ||
866 | groups[group_key].sort do | x, y | | |
867 | ||
868 | x[:name] <=> y[:name] | |
869 | ||
870 | end.each do |entry| | |
871 | ||
872 | row_class = (count % 2 == 0) ? 'even' : 'odd' | |
873 | count += 1 | |
874 | ||
875 | html << "<tr class=\"#{row_class}\"}>" | |
876 | ||
877 | if (entry[:icon].empty?) | |
878 | html << "<td> </td>" | |
879 | else | |
880 | html << "<td align=\"center\"><a href=\"#{entry[:raw][:link]}\" class=\"img\"><img src=\"#{entry[:icon]}\" alt=\"icon\" /></a></td>" | |
881 | end | |
882 | ||
883 | html << "<td><a href=\"#{entry[:raw][:link]}\">#{entry[:name]}</a></td>" | |
884 | html << "<td class=\"can_wrap\">#{entry[:info]}</td>" | |
885 | html << "<td align=\"center\">#{entry[:version]}</td>" | |
886 | html << "<td align=\"center\">#{entry[:raw][:size]}</td>" | |
887 | ||
888 | if (link_base) | |
889 | if (link_icon) | |
890 | html << "<td align=\"center\"><a href=\"#{entry[:link]}\" class=\"img\"><img src=\"#{link_icon}\" alt=\"info\" /></a></td>" | |
891 | else | |
892 | html << "<td align=\"center\"><a href=\"#{entry[:link]}\">Details</a></td>" | |
893 | end | |
894 | end | |
895 | ||
896 | html << "</tr>\n" | |
897 | end | |
898 | ||
899 | html << "</table>\n\n" | |
900 | end | |
901 | ||
902 | html = '<p>There are no files currently available.</p>' if (list.empty?) | |
903 | return html | |
904 | end | |
end |