Merge branch 'master' of ssh://yeti.esilibrary.com/home/evergreen/evergreen-equinox...
authorsenator <lebbeous@esilibrary.com>
Wed, 16 Mar 2011 19:20:19 +0000 (15:20 -0400)
committersenator <lebbeous@esilibrary.com>
Wed, 16 Mar 2011 19:20:19 +0000 (15:20 -0400)
242 files changed:
Open-ILS/examples/apache/eg_vhost.conf
Open-ILS/examples/oils_web.xml.example
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm [new file with mode: 0644]
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm [new file with mode: 0644]
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Container.pm [new file with mode: 0644]
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm [new file with mode: 0644]
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm [new file with mode: 0644]
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm [new file with mode: 0644]
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb/CGI_utf8.pm [new file with mode: 0644]
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb/I18NFilter.pm [new file with mode: 0644]
Open-ILS/web/css/skin/default/opac/contentslider.css [new file with mode: 0644]
Open-ILS/web/css/skin/default/opac/semiauto.css [new file with mode: 0644]
Open-ILS/web/css/skin/default/opac/style.css [new file with mode: 0644]
Open-ILS/web/images/KCLS_logo_horiz.gif [new file with mode: 0644]
Open-ILS/web/images/acct-btn-hover.png [new file with mode: 0644]
Open-ILS/web/images/acct-btn.png [new file with mode: 0644]
Open-ILS/web/images/acct_checked_out_off.gif [new file with mode: 0644]
Open-ILS/web/images/acct_checked_out_on.gif [new file with mode: 0644]
Open-ILS/web/images/acct_favs_off.gif [new file with mode: 0644]
Open-ILS/web/images/acct_favs_on.gif [new file with mode: 0644]
Open-ILS/web/images/acct_fines_off.jpg [new file with mode: 0644]
Open-ILS/web/images/acct_fines_on.jpg [new file with mode: 0644]
Open-ILS/web/images/acct_holds_off.gif [new file with mode: 0644]
Open-ILS/web/images/acct_holds_on.gif [new file with mode: 0644]
Open-ILS/web/images/acct_lists_off.gif [new file with mode: 0644]
Open-ILS/web/images/acct_lists_on.gif [new file with mode: 0644]
Open-ILS/web/images/acct_payments_off.jpg [new file with mode: 0644]
Open-ILS/web/images/acct_payments_on.jpg [new file with mode: 0644]
Open-ILS/web/images/acct_prefs_off.gif [new file with mode: 0644]
Open-ILS/web/images/acct_prefs_on.gif [new file with mode: 0644]
Open-ILS/web/images/acct_sum_fines_bl.png [new file with mode: 0644]
Open-ILS/web/images/acct_sum_fines_br.png [new file with mode: 0644]
Open-ILS/web/images/acct_sum_fines_tl.png [new file with mode: 0644]
Open-ILS/web/images/acct_sum_fines_tr.png [new file with mode: 0644]
Open-ILS/web/images/acct_summary_off.gif [new file with mode: 0644]
Open-ILS/web/images/acct_summary_on.gif [new file with mode: 0644]
Open-ILS/web/images/add_mylist.gif [new file with mode: 0644]
Open-ILS/web/images/add_mylist_sel.gif [new file with mode: 0644]
Open-ILS/web/images/add_mylist_sel.kcls.gif [new file with mode: 0644]
Open-ILS/web/images/add_search_row_btn.gif [new file with mode: 0644]
Open-ILS/web/images/adv_row_close_btn.png [new file with mode: 0644]
Open-ILS/web/images/adv_search.png [new file with mode: 0644]
Open-ILS/web/images/adv_search_hover.png [new file with mode: 0644]
Open-ILS/web/images/adv_search_off.gif [new file with mode: 0644]
Open-ILS/web/images/adv_search_on.gif [new file with mode: 0644]
Open-ILS/web/images/another_search.png [new file with mode: 0644]
Open-ILS/web/images/another_search_hover.png [new file with mode: 0644]
Open-ILS/web/images/arrow-down.gif [new file with mode: 0644]
Open-ILS/web/images/arrow-right.gif [new file with mode: 0644]
Open-ILS/web/images/arrow-right.png [new file with mode: 0644]
Open-ILS/web/images/asknow_available.gif [new file with mode: 0644]
Open-ILS/web/images/banner-bg.png [new file with mode: 0644]
Open-ILS/web/images/banner1.jpg [new file with mode: 0644]
Open-ILS/web/images/btnCancel.png [new file with mode: 0644]
Open-ILS/web/images/btnSubmit.png [new file with mode: 0644]
Open-ILS/web/images/button-bg.png [new file with mode: 0644]
Open-ILS/web/images/cancel_btn.gif [new file with mode: 0644]
Open-ILS/web/images/cd-small.png [new file with mode: 0644]
Open-ILS/web/images/clipboard.png [new file with mode: 0644]
Open-ILS/web/images/dash-corner-left1.png [new file with mode: 0644]
Open-ILS/web/images/dash-corner-left2.png [new file with mode: 0644]
Open-ILS/web/images/dash-corner-mid1.png [new file with mode: 0644]
Open-ILS/web/images/dash-corner-mid2.png [new file with mode: 0644]
Open-ILS/web/images/dash-corner-right1.png [new file with mode: 0644]
Open-ILS/web/images/dash-corner-right2.png [new file with mode: 0644]
Open-ILS/web/images/dash-divider.jpg [new file with mode: 0644]
Open-ILS/web/images/dropdown-hover.gif [new file with mode: 0644]
Open-ILS/web/images/dropdown.gif [new file with mode: 0644]
Open-ILS/web/images/expert_search_off.gif [new file with mode: 0644]
Open-ILS/web/images/expert_search_on.gif [new file with mode: 0644]
Open-ILS/web/images/faqs-btn.png [new file with mode: 0644]
Open-ILS/web/images/go-btn-hover.png [new file with mode: 0644]
Open-ILS/web/images/go-btn.png [new file with mode: 0644]
Open-ILS/web/images/go_but_long.gif [new file with mode: 0644]
Open-ILS/web/images/golive.jpg [new file with mode: 0644]
Open-ILS/web/images/gray-arrow.png [new file with mode: 0644]
Open-ILS/web/images/green_check.png [new file with mode: 0644]
Open-ILS/web/images/header_left.gif [new file with mode: 0644]
Open-ILS/web/images/header_right.gif [new file with mode: 0644]
Open-ILS/web/images/hp-links-left.jpg [new file with mode: 0644]
Open-ILS/web/images/hp-links-mid.jpg [new file with mode: 0644]
Open-ILS/web/images/hp-links-right.jpg [new file with mode: 0644]
Open-ILS/web/images/locations.jpg [new file with mode: 0644]
Open-ILS/web/images/login-bg.jpg [new file with mode: 0644]
Open-ILS/web/images/login-bg2.jpg [new file with mode: 0644]
Open-ILS/web/images/login-box-bg.jpg [new file with mode: 0644]
Open-ILS/web/images/login-btn-hover.png [new file with mode: 0644]
Open-ILS/web/images/login-btn.gif [new file with mode: 0644]
Open-ILS/web/images/login-btn.png [new file with mode: 0644]
Open-ILS/web/images/login-btn2.png [new file with mode: 0644]
Open-ILS/web/images/logout-btn-hover.png [new file with mode: 0644]
Open-ILS/web/images/logout-btn.png [new file with mode: 0644]
Open-ILS/web/images/media_3dobject.jpg [new file with mode: 0644]
Open-ILS/web/images/media_book.jpg [new file with mode: 0644]
Open-ILS/web/images/media_bookoncassette.jpg [new file with mode: 0644]
Open-ILS/web/images/media_bookoncassettecd.jpg [new file with mode: 0644]
Open-ILS/web/images/media_bookoncd.jpg [new file with mode: 0644]
Open-ILS/web/images/media_cassettewithbook.jpg [new file with mode: 0644]
Open-ILS/web/images/media_cdrom.jpg [new file with mode: 0644]
Open-ILS/web/images/media_cdwithbook.jpg [new file with mode: 0644]
Open-ILS/web/images/media_downloadebook.jpg [new file with mode: 0644]
Open-ILS/web/images/media_downloadmusic.jpg [new file with mode: 0644]
Open-ILS/web/images/media_downloadvideo.jpg [new file with mode: 0644]
Open-ILS/web/images/media_dvd.jpg [new file with mode: 0644]
Open-ILS/web/images/media_eaudio.jpg [new file with mode: 0644]
Open-ILS/web/images/media_ebooktext.jpg [new file with mode: 0644]
Open-ILS/web/images/media_equipment.jpg [new file with mode: 0644]
Open-ILS/web/images/media_films.jpg [new file with mode: 0644]
Open-ILS/web/images/media_games.jpg [new file with mode: 0644]
Open-ILS/web/images/media_kit.jpg [new file with mode: 0644]
Open-ILS/web/images/media_language.jpg [new file with mode: 0644]
Open-ILS/web/images/media_largeprint.jpg [new file with mode: 0644]
Open-ILS/web/images/media_magazines.jpg [new file with mode: 0644]
Open-ILS/web/images/media_map.jpg [new file with mode: 0644]
Open-ILS/web/images/media_microform.jpg [new file with mode: 0644]
Open-ILS/web/images/media_musiccassete.jpg [new file with mode: 0644]
Open-ILS/web/images/media_musiccassette.jpg [new file with mode: 0644]
Open-ILS/web/images/media_musiccd.jpg [new file with mode: 0644]
Open-ILS/web/images/media_musicrecord.jpg [new file with mode: 0644]
Open-ILS/web/images/media_newspaper.jpg [new file with mode: 0644]
Open-ILS/web/images/media_online.jpg [new file with mode: 0644]
Open-ILS/web/images/media_onlinejournal.jpg [new file with mode: 0644]
Open-ILS/web/images/media_podcasts.jpg [new file with mode: 0644]
Open-ILS/web/images/media_printedmusic.jpg [new file with mode: 0644]
Open-ILS/web/images/media_projectedmedia.jpg [new file with mode: 0644]
Open-ILS/web/images/media_sheetmusic.jpg [new file with mode: 0644]
Open-ILS/web/images/media_slide.jpg [new file with mode: 0644]
Open-ILS/web/images/media_software.jpg [new file with mode: 0644]
Open-ILS/web/images/media_streamingaudio.jpg [new file with mode: 0644]
Open-ILS/web/images/media_streamingvideo.jpg [new file with mode: 0644]
Open-ILS/web/images/media_vhs.jpg [new file with mode: 0644]
Open-ILS/web/images/num_search_off.gif [new file with mode: 0644]
Open-ILS/web/images/num_search_on.gif [new file with mode: 0644]
Open-ILS/web/images/one_land.gif [new file with mode: 0644]
Open-ILS/web/images/pay-fines-btn-hover.png [new file with mode: 0644]
Open-ILS/web/images/pay-fines-btn.png [new file with mode: 0644]
Open-ILS/web/images/pay_fines_btn.gif [new file with mode: 0644]
Open-ILS/web/images/place_hold.gif [new file with mode: 0644]
Open-ILS/web/images/plus_sign.png [new file with mode: 0644]
Open-ILS/web/images/projectedmedia.jpg [new file with mode: 0644]
Open-ILS/web/images/question-mark.png [new file with mode: 0644]
Open-ILS/web/images/questions.png [new file with mode: 0644]
Open-ILS/web/images/rdetail_arrow.png [new file with mode: 0644]
Open-ILS/web/images/reset_form_btn.gif [new file with mode: 0644]
Open-ILS/web/images/reviews.gif [new file with mode: 0644]
Open-ILS/web/images/save-btn.png [new file with mode: 0644]
Open-ILS/web/images/save_btn.gif [new file with mode: 0644]
Open-ILS/web/images/search_btn.gif [new file with mode: 0644]
Open-ILS/web/images/starz.png [new file with mode: 0644]
Open-ILS/web/images/sub_checked_hist_off.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_checked_hist_on.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_checked_out_off.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_checked_out_on.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_holds_hist_off.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_holds_hist_on.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_holds_off.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_holds_on.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_prefs_info_off.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_prefs_info_on.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_prefs_notify_off.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_prefs_notify_on.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_prefs_search_off.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_prefs_search_on.jpg [new file with mode: 0644]
Open-ILS/web/images/submit_btn.gif [new file with mode: 0644]
Open-ILS/web/images/tool_back.gif [new file with mode: 0644]
Open-ILS/web/images/tool_back.png [new file with mode: 0644]
Open-ILS/web/images/tool_font.gif [new file with mode: 0644]
Open-ILS/web/images/tool_forward.gif [new file with mode: 0644]
Open-ILS/web/images/tool_forward.png [new file with mode: 0644]
Open-ILS/web/images/tool_help.gif [new file with mode: 0644]
Open-ILS/web/images/tool_help.png [new file with mode: 0644]
Open-ILS/web/images/tool_home.gif [new file with mode: 0644]
Open-ILS/web/images/tool_home.png [new file with mode: 0644]
Open-ILS/web/images/tool_mail.gif [new file with mode: 0644]
Open-ILS/web/images/tool_print.gif [new file with mode: 0644]
Open-ILS/web/images/tool_print.png [new file with mode: 0644]
Open-ILS/web/images/utils-corner-left.png [new file with mode: 0644]
Open-ILS/web/images/utils-corner-mid.png [new file with mode: 0644]
Open-ILS/web/images/utils-corner-right.jpg [new file with mode: 0644]
Open-ILS/web/images/utils-corner-right.png [new file with mode: 0644]
Open-ILS/web/images/utils-corner.jpg [new file with mode: 0644]
Open-ILS/web/images/view_my_list.png [new file with mode: 0644]
Open-ILS/web/images/view_my_list_hover.png [new file with mode: 0644]
Open-ILS/web/js/ui/default/opac/simple.js [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/base.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/common.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/home.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/login.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/marc_attrs.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/myopac/_links.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/myopac/bookbags.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/myopac/circs.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/myopac/fines.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/myopac/holds.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/myopac/main.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/myopac/prefs.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/myopac/update_email.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/place_hold.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/record.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/results.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/advanced.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/home.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/login.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/mylist.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/myopac/circs.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/myopac/holds.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/myopac/lists.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/myopac/main.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/myopac/prefs.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/myopac/update_email.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/advanced/global_row.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/advanced/search.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/anon_list.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/audience_selector.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/base.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/cn_browse.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/filtersort.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/format_selector.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/header.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/homesearch.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/language_selector.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/login/form.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/marc_misc.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/myopac/base.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/org_selector.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/place_hold.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/qtype_selector.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/record/body.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/record/cn_details.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/record/copyinfo.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/record/extras.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/record/summary.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/result/lowhits.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/result/table.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/searchbar.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/tips.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/topnav.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/utils.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/place_hold.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/record.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/results.tt2 [new file with mode: 0644]

index 7fea97c..7fb1354 100644 (file)
@@ -169,26 +169,6 @@ RewriteRule . - [E=locale:%1]
 
 </Location>
 
-<Location /js/>
-    # ----------------------------------------------------------------------------------
-    # Some mod_deflate fun
-    # ----------------------------------------------------------------------------------
-    <IfModule mod_deflate.c>
-        SetOutputFilter DEFLATE
-
-        BrowserMatch ^Mozilla/4 gzip-only-text/html
-        BrowserMatch ^Mozilla/4\.0[678] no-gzip
-        BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
-
-        SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary
-
-        <IfModule mod_headers.c>
-            Header append Vary User-Agent env=!dont-vary
-        </IfModule>
-    </IfModule>
-
-</Location>
-
 # ----------------------------------------------------------------------------------
 # Force SSL on the OPAC's "My Account" page
 # ----------------------------------------------------------------------------------
@@ -554,7 +534,40 @@ RewriteRule ^/openurl$ ${openurl:%1} [NE,PT]
     Options +ExecCGI
     PerlSendHeader On
     allow from all
+    <IfModule mod_deflate.c>
+        SetOutputFilter DEFLATE
+        BrowserMatch ^Mozilla/4 gzip-only-text/html
+        BrowserMatch ^Mozilla/4\.0[678] no-gzip
+        BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
+        SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary
+        <IfModule mod_headers.c>
+            Header append Cache-Control "public"
+            Header append Vary User-Agent env=!dont-vary
+        </IfModule>
+    </IfModule>
 </Location>
+<LocationMatch ^/(images|css|js)/>
+    # should pick up the default expire time from eg.conf...
+    <IfModule mod_deflate.c>
+        SetOutputFilter DEFLATE
+        BrowserMatch ^Mozilla/4 gzip-only-text/html
+        BrowserMatch ^Mozilla/4\.0[678] no-gzip
+        BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
+        SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary
+        <IfModule mod_headers.c>
+            Header append Cache-Control "public"
+            Header append Vary User-Agent env=!dont-vary
+        </IfModule>
+    </IfModule>
+</LocationMatch>
+<Location /eg/opac>
+    PerlSetVar OILSWebContextLoader "OpenILS::WWW::EGCatLoader"
+    # Expire the HTML quickly since we're loading dynamic data for each page
+    ExpiresActive On
+    ExpiresByType text/html "access plus 5 seconds"
+</Location>
+
+
 # Note: the template processor will decline handling anything it does not
 # have an explicit configuration for, which means it will fall back to 
 # Apache to serve the file.  However, in the interest of speed, go ahead 
index 60f1573..0728082 100644 (file)
@@ -9,8 +9,24 @@
         files have the following filename extension -->
     <default_template_extension>tt2</default_template_extension>
 
-    <!-- media_prefix can be a remote server.  
-         E.g. <media_prefix>http://static.example.com/media</media_prefix> -->
+    <!-- Media Prefix.  Allows static files to be served from an alternate domain/server
+
+            Examples:
+
+                # local URL path
+                <media_prefix>/media</media_prefix> 
+
+                # server w/ path.  
+                <media_prefix>static.example.com/media</media_prefix> 
+
+                ===
+                In the first 2 examples, the request protocol (http vs https) will
+                match the protocol of the current page
+                ===
+
+                # full-qualified with static protocol
+                <media_prefix>http://static.example.com/media</media_prefix> 
+     -->
     <media_prefix/>
 
     <!-- If set to true, all output will be parsed as XML before delivery to the client.  
         XML parsing adds overhead, so this should only be used for debugging -->
     <force_valid_xml>false</force_valid_xml>
 
+    <!-- Turn on template-toolkit debugging, which reports on undefined blocks, macros, etc. -->
+    <debug_template>false</debug_template>
+
+    <!-- 
+        Supported locales.  Locales with no message catalog will use the native template strings.
+        All locales will fall back to native strings when a given string is not in the catalog
+    -->
+    <locales>
+        <en_US/>
+        <en_CA>/openils/var/data/locale/messages.en_CA.po</en_CA>
+        <fr_CA>/openils/var/data/locale/messages.fr_CA.po</fr_CA>
+    </locales>
+
     <!-- Where templates can be found.  Paths will be checked in the order entered here.
          It's possible to override individual or sets of templates by putting them into
          a path in front of the default template path -->
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm
new file mode 100644 (file)
index 0000000..ebfbbec
--- /dev/null
@@ -0,0 +1,289 @@
+package OpenILS::WWW::EGCatLoader;
+use strict; use warnings;
+use XML::LibXML;
+use URI::Escape;
+use Digest::MD5 qw(md5_hex);
+use Apache2::Const -compile => qw(OK DECLINED FORBIDDEN HTTP_INTERNAL_SERVER_ERROR REDIRECT HTTP_BAD_REQUEST);
+use OpenSRF::AppSession;
+use OpenSRF::EX qw/:try/;
+use OpenSRF::Utils qw/:datetime/;
+use OpenSRF::Utils::JSON;
+use OpenSRF::Utils::Logger qw/$logger/;
+use OpenILS::Application::AppUtils;
+use OpenILS::Utils::CStoreEditor qw/:funcs/;
+use OpenILS::Utils::Fieldmapper;
+use DateTime::Format::ISO8601;
+use CGI qw(:all -utf8);
+
+# EGCatLoader sub-modules 
+use OpenILS::WWW::EGCatLoader::Util;
+use OpenILS::WWW::EGCatLoader::Account;
+use OpenILS::WWW::EGCatLoader::Search;
+use OpenILS::WWW::EGCatLoader::Record;
+use OpenILS::WWW::EGCatLoader::Container;
+
+my $U = 'OpenILS::Application::AppUtils';
+
+use constant COOKIE_SES => 'ses';
+
+sub new {
+    my($class, $apache, $ctx) = @_;
+
+    my $self = bless({}, ref($class) || $class);
+
+    $self->apache($apache);
+    $self->ctx($ctx);
+    $self->cgi(new CGI);
+
+    OpenILS::Utils::CStoreEditor->init; # just in case
+    $self->editor(new_editor());
+
+    return $self;
+}
+
+
+# current Apache2::RequestRec;
+sub apache {
+    my($self, $apache) = @_;
+    $self->{apache} = $apache if $apache;
+    return $self->{apache};
+}
+
+# runtime / template context
+sub ctx {
+    my($self, $ctx) = @_;
+    $self->{ctx} = $ctx if $ctx;
+    return $self->{ctx};
+}
+
+# cstore editor
+sub editor {
+    my($self, $editor) = @_;
+    $self->{editor} = $editor if $editor;
+    return $self->{editor};
+}
+
+# CGI handle
+sub cgi {
+    my($self, $cgi) = @_;
+    $self->{cgi} = $cgi if $cgi;
+    return $self->{cgi};
+}
+
+
+# -----------------------------------------------------------------------------
+# Perform initial setup, load common data, then load page data
+# -----------------------------------------------------------------------------
+sub load {
+    my $self = shift;
+
+    $self->init_ro_object_cache;
+
+    my $stat = $self->load_common;
+    return $stat unless $stat == Apache2::Const::OK;
+
+    my $path = $self->apache->path_info;
+
+    (undef, $self->ctx->{mylist}) = $self->fetch_mylist unless
+        $path =~ /opac\/my(opac\/lists|list)/;
+
+    return $self->load_simple("home") if $path =~ /opac\/home/;
+    return $self->load_simple("advanced") if $path =~ /opac\/advanced/;
+    return $self->load_rresults if $path =~ /opac\/results/;
+    return $self->load_record if $path =~ /opac\/record/;
+
+    return $self->load_mylist_add if $path =~ /opac\/mylist\/add/;
+    return $self->load_mylist_del if $path =~ /opac\/mylist\/del/;
+    return $self->load_mylist if $path =~ /opac\/mylist/;
+    return $self->load_cache_clear if $path =~ /opac\/cache\/clear/;
+
+    # ----------------------------------------------------------------
+    # Logout and login require SSL
+    # ----------------------------------------------------------------
+    if($path =~ /opac\/login/) {
+        return $self->redirect_ssl unless $self->cgi->https;
+        return $self->load_login;
+    }
+
+    if($path =~ /opac\/logout/) {
+        #return Apache2::Const::FORBIDDEN unless $self->cgi->https; 
+        $self->apache->log->warn("catloader: logout called in non-secure context from " . 
+            ($self->ctx->{referer} || '<no referer>')) unless $self->cgi->https;
+        return $self->load_logout;
+    }
+
+    # ----------------------------------------------------------------
+    #  Everything below here requires SSL + authentication
+    # ----------------------------------------------------------------
+    return $self->redirect_auth
+        unless $self->cgi->https and $self->editor->requestor;
+
+    return $self->load_place_hold if $path =~ /opac\/place_hold/;
+    return $self->load_myopac_holds if $path =~ /opac\/myopac\/holds/;
+    return $self->load_myopac_circs if $path =~ /opac\/myopac\/circs/;
+    return $self->load_myopac_fines if $path =~ /opac\/myopac\/main/;
+    return $self->load_myopac_update_email if $path =~ /opac\/myopac\/update_email/;
+    return $self->load_myopac_bookbags if $path =~ /opac\/myopac\/lists/;
+    return $self->load_myopac_bookbag_update if $path =~ /opac\/myopac\/list\/update/;
+    return $self->load_myopac if $path =~ /opac\/myopac/;
+
+    return Apache2::Const::OK;
+}
+
+
+# -----------------------------------------------------------------------------
+# Redirect to SSL equivalent of a given page
+# -----------------------------------------------------------------------------
+sub redirect_ssl {
+    my $self = shift;
+    my $new_page = sprintf('https://%s%s', $self->apache->hostname, $self->apache->unparsed_uri);
+    return $self->generic_redirect($new_page);
+}
+
+# -----------------------------------------------------------------------------
+# If an authnticated resource is requested w/o auth, redirect to the login page,
+# then return to the originally requrested resource upon successful login.
+# -----------------------------------------------------------------------------
+sub redirect_auth {
+    my $self = shift;
+    my $login_page = sprintf('https://%s%s/login', $self->apache->hostname, $self->ctx->{opac_root});
+    my $redirect_to = uri_escape($self->apache->unparsed_uri);
+    return $self->generic_redirect("$login_page?redirect_to=$redirect_to");
+}
+
+# -----------------------------------------------------------------------------
+# Fall-through for loading a basic page
+# -----------------------------------------------------------------------------
+sub load_simple {
+    my ($self, $page) = @_;
+    $self->ctx->{page} = $page;
+    return Apache2::Const::OK;
+}
+
+# -----------------------------------------------------------------------------
+# Tests to see if the user is authenticated and sets some common context values
+# -----------------------------------------------------------------------------
+sub load_common {
+    my $self = shift;
+
+    my $e = $self->editor;
+    my $ctx = $self->ctx;
+
+    $ctx->{referer} = $self->cgi->referer;
+    $ctx->{path_info} = $self->cgi->path_info;
+    $ctx->{opac_root} = $ctx->{base_path} . "/opac"; # absolute base url
+    $ctx->{is_staff} = ($self->apache->headers_in->get('User-Agent') =~ 'oils_xulrunner');
+
+    # capture some commonly accessed pages
+    $ctx->{home_page} = 'http://' . $self->apache->hostname . $self->ctx->{opac_root} . "/home";
+    $ctx->{logout_page} = 'https://' . $self->apache->hostname . $self->ctx->{opac_root} . "/logout";
+
+    if($e->authtoken($self->cgi->cookie(COOKIE_SES))) {
+
+        if($e->checkauth) {
+
+            $ctx->{authtoken} = $e->authtoken;
+            $ctx->{authtime} = $e->authtime;
+            $ctx->{user} = $e->requestor;
+
+            $ctx->{user_stats} = $U->simplereq(
+                'open-ils.actor', 
+                'open-ils.actor.user.opac.vital_stats', 
+                $e->authtoken, $e->requestor->id);
+
+        } else {
+
+            # For now, keep an eye out for any pages being unceremoniously redirected to logout...
+            $self->apache->log->info("catloader: loading " . $ctx->{path_info} . 
+                "; auth session " .  $e->authtoken . " no longer valid; redirecting to logout");
+
+            return $self->load_logout;
+        }
+    }
+
+    return Apache2::Const::OK;
+}
+
+
+# -----------------------------------------------------------------------------
+# Log in and redirect to the redirect_to URL (or home)
+# -----------------------------------------------------------------------------
+sub load_login {
+    my $self = shift;
+    my $cgi = $self->cgi;
+    my $ctx = $self->ctx;
+
+    $ctx->{page} = 'login';
+
+    my $username = $cgi->param('username');
+    my $password = $cgi->param('password');
+    my $org_unit = $cgi->param('loc') || $ctx->{aou_tree}->()->id;
+    my $persist = $cgi->param('persist');
+
+    # initial log form only
+    return Apache2::Const::OK unless $username and $password;
+
+       my $seed = $U->simplereq(
+        'open-ils.auth', 
+               'open-ils.auth.authenticate.init', $username);
+
+    my $args = {       
+        username => $username, 
+        password => md5_hex($seed . md5_hex($password)), 
+        type => ($persist) ? 'persist' : 'opac' 
+    };
+
+    my $bc_regex = $ctx->{get_org_setting}->($org_unit, 'opac.barcode_regex');
+
+    $args->{barcode} = delete $args->{username} 
+        if $bc_regex and $username =~ /$bc_regex/;
+
+       my $response = $U->simplereq(
+        'open-ils.auth', 'open-ils.auth.authenticate.complete', $args);
+
+    if($U->event_code($response)) { 
+        # login failed, report the reason to the template
+        $ctx->{login_failed_event} = $response;
+        return Apache2::Const::OK;
+    }
+
+    # login succeeded, redirect as necessary
+
+    my $acct = $self->apache->unparsed_uri;
+    $acct =~ s#/login#/myopac/main#;
+
+    return $self->generic_redirect(
+        $cgi->param('redirect_to') || $acct,
+        $cgi->cookie(
+            -name => COOKIE_SES,
+            -path => '/',
+            -secure => 1,
+            -value => $response->{payload}->{authtoken},
+            -expires => ($persist) ? CORE::time + $response->{payload}->{authtime} : undef
+        )
+    );
+}
+
+# -----------------------------------------------------------------------------
+# Log out and redirect to the home page
+# -----------------------------------------------------------------------------
+sub load_logout {
+    my $self = shift;
+
+    # If the user was adding anyting to an anonymous cache 
+    # while logged in, go ahead and clear it out.
+    $self->clear_anon_cache;
+
+    return $self->generic_redirect(
+        $self->ctx->{home_page},
+        $self->cgi->cookie(
+            -name => COOKIE_SES,
+            -path => '/',
+            -value => '',
+            -expires => '-1h'
+        )
+    );
+}
+
+1;
+
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm
new file mode 100644 (file)
index 0000000..e92a4bd
--- /dev/null
@@ -0,0 +1,603 @@
+package OpenILS::WWW::EGCatLoader;
+use strict; use warnings;
+use Apache2::Const -compile => qw(OK DECLINED FORBIDDEN HTTP_INTERNAL_SERVER_ERROR REDIRECT HTTP_BAD_REQUEST);
+use OpenSRF::Utils::Logger qw/$logger/;
+use OpenILS::Utils::CStoreEditor qw/:funcs/;
+use OpenILS::Utils::Fieldmapper;
+use OpenILS::Application::AppUtils;
+my $U = 'OpenILS::Application::AppUtils';
+
+
+# context additions: 
+#   user : au object, fleshed
+sub load_myopac {
+    my $self = shift;
+    $self->ctx->{page} = 'myopac';
+
+    $self->ctx->{user} = $self->editor->retrieve_actor_user([
+        $self->ctx->{user}->id,
+        {
+            flesh => 1,
+            flesh_fields => {
+                au => [qw/card home_ou addresses ident_type/]
+                # ...
+            }
+        }
+    ]);
+
+    return Apache2::Const::OK;
+}
+
+
+sub fetch_user_holds {
+    my $self = shift;
+    my $hold_ids = shift;
+    my $ids_only = shift;
+    my $flesh = shift;
+    my $available = shift;
+    my $limit = shift;
+    my $offset = shift;
+
+    my $e = $self->editor;
+
+    my $circ = OpenSRF::AppSession->create('open-ils.circ');
+
+    if(!$hold_ids) {
+
+        $hold_ids = $circ->request(
+            'open-ils.circ.holds.id_list.retrieve.authoritative', 
+            $e->authtoken, 
+            $e->requestor->id
+        )->gather(1);
+    
+        $hold_ids = [ grep { defined $_ } @$hold_ids[$offset..($offset + $limit - 1)] ] if $limit or $offset;
+    }
+
+
+    return $hold_ids if $ids_only or @$hold_ids == 0;
+
+    my $args = {
+        suppress_notices => 1,
+        suppress_transits => 1,
+        suppress_mvr => 1,
+        suppress_patron_details => 1,
+        include_bre => $flesh ? 1 : 0
+    };
+
+    # ----------------------------------------------------------------
+    # Collect holds in batches of $batch_size for faster retrieval
+
+    my $batch_size = 8;
+    my $batch_idx = 0;
+    my $mk_req_batch = sub {
+        my @ses;
+        my $top_idx = $batch_idx + $batch_size;
+        while($batch_idx < $top_idx) {
+            my $hold_id = $hold_ids->[$batch_idx++];
+            last unless $hold_id;
+            my $ses = OpenSRF::AppSession->create('open-ils.circ');
+            my $req = $ses->request(
+                'open-ils.circ.hold.details.retrieve', 
+                $e->authtoken, $hold_id, $args);
+            push(@ses, {ses => $ses, req => $req});
+        }
+        return @ses;
+    };
+
+    my $first = 1;
+    my(@collected, @holds, @ses);
+
+    while(1) {
+        @ses = $mk_req_batch->() if $first;
+        last if $first and not @ses;
+
+        if(@collected) {
+            # If desired by the caller, filter any holds that are not available.
+            if ($available) {
+                @collected = grep { $_->{hold}->{status} == 4 } @collected;
+            }
+            while(my $blob = pop(@collected)) {
+                $blob->{marc_xml} = XML::LibXML->new->parse_string($blob->{hold}->{bre}->marc) if $flesh;
+                push(@holds, $blob);
+            }
+        }
+
+        for my $req_data (@ses) {
+            push(@collected, {hold => $req_data->{req}->gather(1)});
+            $req_data->{ses}->kill_me;
+        }
+
+        @ses = $mk_req_batch->();
+        last unless @collected or @ses;
+        $first = 0;
+    }
+
+    # put the holds back into the original server sort order
+    my @sorted;
+    for my $id (@$hold_ids) {
+        push @sorted, grep { $_->{hold}->{hold}->id == $id } @holds;
+    }
+
+    return \@sorted;
+}
+
+sub handle_hold_update {
+    my $self = shift;
+    my $action = shift;
+    my $e = $self->editor;
+
+
+    my @hold_ids = $self->cgi->param('hold_id'); # for non-_all actions
+    @hold_ids = @{$self->fetch_user_holds(undef, 1)} if $action =~ /_all/;
+
+    my $circ = OpenSRF::AppSession->create('open-ils.circ');
+
+    if($action =~ /cancel/) {
+
+        for my $hold_id (@hold_ids) {
+            my $resp = $circ->request(
+                'open-ils.circ.hold.cancel', $e->authtoken, $hold_id, 6 )->gather(1); # 6 == patron-cancelled-via-opac
+        }
+
+    } else {
+        
+        my $vlist = [];
+        for my $hold_id (@hold_ids) {
+            my $vals = {id => $hold_id};
+
+            if($action =~ /activate/) {
+                $vals->{frozen} = 'f';
+                $vals->{thaw_date} = undef;
+
+            } elsif($action =~ /suspend/) {
+                $vals->{frozen} = 't';
+                # $vals->{thaw_date} = TODO;
+            }
+            push(@$vlist, $vals);
+        }
+
+        $circ->request('open-ils.circ.hold.update.batch.atomic', $e->authtoken, undef, $vlist)->gather(1);
+    }
+
+    $circ->kill_me;
+    return undef;
+}
+
+sub load_myopac_holds {
+    my $self = shift;
+    my $e = $self->editor;
+    my $ctx = $self->ctx;
+    
+
+    my $limit = $self->cgi->param('limit') || 0;
+    my $offset = $self->cgi->param('offset') || 0;
+    my $action = $self->cgi->param('action') || '';
+    my $available = int($self->cgi->param('available') || 0);
+
+    $self->handle_hold_update($action) if $action;
+
+    $ctx->{holds} = $self->fetch_user_holds(undef, 0, 1, $available, $limit, $offset);
+
+    return Apache2::Const::OK;
+}
+
+sub load_place_hold {
+    my $self = shift;
+    my $ctx = $self->ctx;
+    my $e = $self->editor;
+    my $cgi = $self->cgi;
+    $self->ctx->{page} = 'place_hold';
+
+    $ctx->{hold_target} = $cgi->param('hold_target');
+    $ctx->{hold_type} = $cgi->param('hold_type');
+    $ctx->{default_pickup_lib} = $e->requestor->home_ou; # XXX staff
+
+    if($ctx->{hold_type} eq 'T') {
+        $ctx->{record} = $e->retrieve_biblio_record_entry($ctx->{hold_target});
+    }
+    # ...
+
+    $ctx->{marc_xml} = XML::LibXML->new->parse_string($ctx->{record}->marc);
+
+    if(my $pickup_lib = $cgi->param('pickup_lib')) {
+
+        my $args = {
+            patronid => $e->requestor->id,
+            titleid => $ctx->{hold_target}, # XXX
+            pickup_lib => $pickup_lib,
+            depth => 0, # XXX
+        };
+
+        my $allowed = $U->simplereq(
+            'open-ils.circ',
+            'open-ils.circ.title_hold.is_possible',
+            $e->authtoken, $args
+        );
+
+        if($allowed->{success} == 1) {
+            my $hold = Fieldmapper::action::hold_request->new;
+
+            $hold->pickup_lib($pickup_lib);
+            $hold->requestor($e->requestor->id);
+            $hold->usr($e->requestor->id); # XXX staff
+            $hold->target($ctx->{hold_target});
+            $hold->hold_type($ctx->{hold_type});
+            # frozen, expired, etc..
+
+            my $stat = $U->simplereq(
+                'open-ils.circ',
+                'open-ils.circ.holds.create',
+                $e->authtoken, $hold
+            );
+
+            if($stat and $stat > 0) {
+                # if successful, return the user to the requesting page
+                $self->apache->log->info("Redirecting back to " . $cgi->param('redirect_to'));
+                return $self->generic_redirect;
+
+            } else {
+                $ctx->{hold_failed} = 1;
+            }
+        } else { # hold *check* failed
+            $ctx->{hold_failed} = 1; # XXX process the events, etc
+            $ctx->{hold_failed_event} = $allowed->{last_event};
+        }
+
+        # hold permit failed
+        $logger->info('hold permit result ' . OpenSRF::Utils::JSON->perl2JSON($allowed));
+    }
+
+    return Apache2::Const::OK;
+}
+
+
+sub fetch_user_circs {
+    my $self = shift;
+    my $flesh = shift; # flesh bib data, etc.
+    my $circ_ids = shift;
+    my $limit = shift;
+    my $offset = shift;
+
+    my $e = $self->editor;
+
+    my @circ_ids;
+
+    if($circ_ids) {
+        @circ_ids = @$circ_ids;
+
+    } else {
+
+        my $circ_data = $U->simplereq(
+            'open-ils.actor', 
+            'open-ils.actor.user.checked_out',
+            $e->authtoken, 
+            $e->requestor->id
+        );
+
+        @circ_ids =  ( @{$circ_data->{overdue}}, @{$circ_data->{out}} );
+
+        if($limit or $offset) {
+            @circ_ids = grep { defined $_ } @circ_ids[0..($offset + $limit - 1)];
+        }
+    }
+
+    return [] unless @circ_ids;
+
+    my $cstore = OpenSRF::AppSession->create('open-ils.cstore');
+
+    my $qflesh = {
+        flesh => 3,
+        flesh_fields => {
+            circ => ['target_copy'],
+            acp => ['call_number'],
+            acn => ['record']
+        }
+    };
+
+    $e->xact_begin;
+    my $circs = $e->search_action_circulation(
+        [{id => \@circ_ids}, ($flesh) ? $qflesh : {}], {substream => 1});
+
+    my @circs;
+    for my $circ (@$circs) {
+        push(@circs, {
+            circ => $circ, 
+            marc_xml => ($flesh and $circ->target_copy->call_number->id != -1) ? 
+                XML::LibXML->new->parse_string($circ->target_copy->call_number->record->marc) : 
+                undef  # pre-cat copy, use the dummy title/author instead
+        });
+    }
+    $e->xact_rollback;
+
+    # make sure the final list is in the correct order
+    my @sorted_circs;
+    for my $id (@circ_ids) {
+        push(
+            @sorted_circs,
+            (grep { $_->{circ}->id == $id } @circs)
+        );
+    }
+
+    return \@sorted_circs;
+}
+
+
+sub handle_circ_renew {
+    my $self = shift;
+    my $action = shift;
+    my $ctx = $self->ctx;
+
+    my @renew_ids = $self->cgi->param('circ');
+
+    my $circs = $self->fetch_user_circs(0, ($action eq 'renew') ? [@renew_ids] : undef);
+
+    # TODO: fire off renewal calls in batches to speed things up
+    my @responses;
+    for my $circ (@$circs) {
+
+        my $evt = $U->simplereq(
+            'open-ils.circ', 
+            'open-ils.circ.renew',
+            $self->editor->authtoken,
+            {
+                patron_id => $self->editor->requestor->id,
+                copy_id => $circ->{circ}->target_copy,
+                opac_renewal => 1
+            }
+        );
+
+        # TODO return these, then insert them into the circ data 
+        # blob that is shoved into the template for each circ
+        # so the template won't have to match them
+        push(@responses, {copy => $circ->{circ}->target_copy, evt => $evt});
+    }
+
+    return @responses;
+}
+
+
+sub load_myopac_circs {
+    my $self = shift;
+    my $e = $self->editor;
+    my $ctx = $self->ctx;
+
+    $ctx->{circs} = [];
+    my $limit = $self->cgi->param('limit') || 0; # 0 == unlimited
+    my $offset = $self->cgi->param('offset') || 0;
+    my $action = $self->cgi->param('action') || '';
+
+    # perform the renewal first if necessary
+    my @results = $self->handle_circ_renew($action) if $action =~ /renew/;
+
+    $ctx->{circs} = $self->fetch_user_circs(1, undef, $limit, $offset);
+
+    my $success_renewals = 0;
+    my $failed_renewals = 0;
+    for my $data (@{$ctx->{circs}}) {
+        my ($resp) = grep { $_->{copy} == $data->{circ}->target_copy->id } @results;
+
+        if($resp) {
+            my $evt = ref($resp->{evt}) eq 'ARRAY' ? $resp->{evt}->[0] : $resp->{evt};
+            $data->{renewal_response} = $evt;
+            $success_renewals++ if $evt->{textcode} eq 'SUCCESS';
+            $failed_renewals++ if $evt->{textcode} ne 'SUCCESS';
+        }
+    }
+
+    $ctx->{success_renewals} = $success_renewals;
+    $ctx->{failed_renewals} = $failed_renewals;
+
+    return Apache2::Const::OK;
+}
+
+sub load_myopac_fines {
+    my $self = shift;
+    my $e = $self->editor;
+    my $ctx = $self->ctx;
+    $ctx->{"fines"} = {
+        "circulation" => [],
+        "grocery" => [],
+        "total_paid" => 0,
+        "total_owed" => 0,
+        "balance_owed" => 0
+    };
+
+    my $limit = $self->cgi->param('limit') || 0;
+    my $offset = $self->cgi->param('offset') || 0;
+
+    my $cstore = OpenSRF::AppSession->create('open-ils.cstore');
+
+    # TODO: This should really be a ML call, but the existing calls 
+    # return an excessive amount of data and don't offer streaming
+
+    my %paging = ($limit or $offset) ? (limit => $limit, offset => $offset) : ();
+
+    my $req = $cstore->request(
+        'open-ils.cstore.direct.money.open_billable_transaction_summary.search',
+        {
+            usr => $e->requestor->id,
+            balance_owed => {'!=' => 0}
+        },
+        {
+            flesh => 4,
+            flesh_fields => {
+                mobts => ['circulation', 'grocery'],
+                mg => ['billings'],
+                mb => ['btype'],
+                circ => ['target_copy'],
+                acp => ['call_number'],
+                acn => ['record']
+            },
+            order_by => { mobts => 'xact_start' },
+            %paging
+        }
+    );
+
+    while(my $resp = $req->recv) {
+        my $mobts = $resp->content;
+        my $circ = $mobts->circulation;
+
+        my $last_billing;
+        if($mobts->grocery) {
+            my @billings = sort { $a->billing_ts cmp $b->billing_ts } @{$mobts->grocery->billings};
+            $last_billing = pop(@billings);
+        }
+
+        # XXX TODO switch to some money-safe non-fp library for math
+        $ctx->{"fines"}->{$_} += $mobts->$_ for (
+            qw/total_paid total_owed balance_owed/
+        );
+
+        push(
+            @{$ctx->{"fines"}->{$mobts->grocery ? "grocery" : "circulation"}},
+            {
+                xact => $mobts,
+                last_grocery_billing => $last_billing,
+                marc_xml => ($mobts->xact_type ne 'circulation' or $circ->target_copy->call_number->id == -1) ?
+                    undef :
+                    XML::LibXML->new->parse_string($circ->target_copy->call_number->record->marc),
+            } 
+        );
+    }
+
+     return Apache2::Const::OK;
+}       
+
+sub load_myopac_update_email {
+    my $self = shift;
+    my $e = $self->editor;
+    my $ctx = $self->ctx;
+    my $email = $self->cgi->param('email') || '';
+
+    unless($email =~ /.+\@.+\..+/) { # TODO better regex?
+        $ctx->{invalid_email} = $email;
+        return Apache2::Const::OK;
+    }
+
+    my $stat = $U->simplereq(
+        'open-ils.actor', 
+        'open-ils.actor.user.email.update', 
+        $e->authtoken, $email);
+
+    my $url = $self->apache->unparsed_uri;
+    $url =~ s/update_email/prefs/;
+
+    return $self->generic_redirect($url);
+}
+
+sub load_myopac_bookbags {
+    my $self = shift;
+    my $e = $self->editor;
+    my $ctx = $self->ctx;
+
+    my $rv = $self->load_mylist;
+    return $rv if $rv ne Apache2::Const::OK;
+
+    my $args = {
+        order_by => {cbreb => 'name'},
+        limit => $self->cgi->param('limit') || 10,
+        offset => $self->cgi->param('limit') || 0
+    };
+
+    $ctx->{bookbags} = $e->search_container_biblio_record_entry_bucket([
+        {owner => $self->editor->requestor->id, btype => 'bookbag'},
+        # XXX what to do about the possibility of really large bookbags here?
+        {"flesh" => 1, "flesh_fields" => {"cbreb" => ["items"]}, %$args}
+    ]) or return $e->die_event;
+
+    # get unique record IDs
+    my %rec_ids = ();
+    foreach my $bbag (@{$ctx->{bookbags}}) {
+        foreach my $item_id (map { $_->id } @{$bbag->items}) {
+            $rec_ids{$item_id} = 1;
+        }
+    }
+
+    $ctx->{bookbags_marc_xml} = $self->fetch_marc_xml_by_id(keys %rec_ids);
+
+    return Apache2::Const::OK;
+}
+
+
+# actions are create, delete, show, hide, rename, add_rec, delete_item
+# CGI is action, list=list_id, add_rec=bre_id, del_item=bucket_item_id, name=new_bucket_name
+sub load_myopac_bookbag_update {
+    my $self = shift;
+    my $e = $self->editor;
+    my $cgi = $self->cgi;
+    my $action = $cgi->param('action');
+    my $list_id = $cgi->param('list');
+    my $add_rec = $cgi->param('add_rec');
+    my @del_item = $cgi->param('del_item');
+    my $shared = $cgi->param('shared');
+    my $name = $cgi->param('name');
+    my $success = 0;
+    my $list;
+
+    if($action eq 'create') {
+        $list = Fieldmapper::container::biblio_record_entry_bucket->new;
+        $list->name($name);
+        $list->owner($e->requestor->id);
+        $list->btype('bookbag');
+        $list->pub($shared ? 't' : 'f');
+        $success = $U->simplereq('open-ils.actor', 
+            'open-ils.actor.container.create', $e->authtoken, 'biblio', $list)
+
+    } else {
+
+        $list = $e->retrieve_container_biblio_record_entry_bucket($list_id);
+
+        return Apache2::Const::HTTP_BAD_REQUEST unless 
+            $list and $list->owner == $e->requestor->id;
+    }
+
+    if($action eq 'delete') {
+        $success = $U->simplereq('open-ils.actor', 
+            'open-ils.actor.container.full_delete', $e->authtoken, 'biblio', $list_id);
+
+    } elsif($action eq 'show') {
+        unless($U->is_true($list->pub)) {
+            $list->pub('t');
+            $success = $U->simplereq('open-ils.actor', 
+                'open-ils.actor.container.update', $e->authtoken, 'biblio', $list);
+        }
+
+    } elsif($action eq 'hide') {
+        if($U->is_true($list->pub)) {
+            $list->pub('f');
+            $success = $U->simplereq('open-ils.actor', 
+                'open-ils.actor.container.update', $e->authtoken, 'biblio', $list);
+        }
+
+    } elsif($action eq 'rename') {
+        if($name) {
+            $list->name($name);
+            $success = $U->simplereq('open-ils.actor', 
+                'open-ils.actor.container.update', $e->authtoken, 'biblio', $list);
+        }
+
+    } elsif($action eq 'add_rec') {
+        my $item = Fieldmapper::container::biblio_record_entry_bucket_item->new;
+        $item->bucket($list_id);
+        $item->target_biblio_record_entry($add_rec);
+        $success = $U->simplereq('open-ils.actor', 
+            'open-ils.actor.container.item.create', $e->authtoken, 'biblio', $item);
+
+    } elsif($action eq 'del_item') {
+        foreach (@del_item) {
+            $success = $U->simplereq(
+                'open-ils.actor',
+                'open-ils.actor.container.item.delete', $e->authtoken, 'biblio', $_
+            );
+            last unless $success;
+        }
+    }
+
+    return $self->generic_redirect if $success;
+
+    $self->ctx->{bucket_action} = $action;
+    $self->ctx->{bucket_action_failed} = 1;
+    return Apache2::Const::OK;
+}
+
+1
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Container.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Container.pm
new file mode 100644 (file)
index 0000000..38a9755
--- /dev/null
@@ -0,0 +1,125 @@
+package OpenILS::WWW::EGCatLoader;
+use strict; use warnings;
+use Apache2::Const -compile => qw(OK DECLINED FORBIDDEN HTTP_INTERNAL_SERVER_ERROR REDIRECT HTTP_BAD_REQUEST);
+use OpenSRF::Utils::Logger qw/$logger/;
+use OpenILS::Utils::CStoreEditor qw/:funcs/;
+use OpenILS::Utils::Fieldmapper;
+use OpenILS::Application::AppUtils;
+my $U = 'OpenILS::Application::AppUtils';
+
+use constant COOKIE_ANON_CACHE => 'anoncache';
+use constant ANON_CACHE_MYLIST => 'mylist';
+
+# Retrieve the users cached records AKA 'My List'
+# Returns an empty list if there are no cached records
+sub fetch_mylist {
+    my ($self, $with_marc_xml) = @_;
+
+    my $list = [];
+    my $cache_key = $self->cgi->cookie(COOKIE_ANON_CACHE);
+
+    if($cache_key) {
+
+        $list = $U->simplereq(
+            'open-ils.actor',
+            'open-ils.actor.anon_cache.get_value', 
+            $cache_key, ANON_CACHE_MYLIST);
+
+        if(!$list) {
+            $cache_key = undef;
+            $list = [];
+        }
+    }
+
+    $self->apache->log->info("Found anon-cache list [@$list]");
+    my $marc_xml;
+    if ($with_marc_xml) {
+        $marc_xml = $self->fetch_marc_xml_by_id($list);
+    }
+
+    return ($cache_key, $list, $marc_xml);
+}
+
+
+# Adds a record (by id) to My List, creating a new anon cache + list if necessary.
+sub load_mylist_add {
+    my $self = shift;
+    my $rec_id = $self->cgi->param('record');
+
+    my ($cache_key, $list) = $self->fetch_mylist;
+    push(@$list, $rec_id);
+
+    $cache_key = $U->simplereq(
+        'open-ils.actor',
+        'open-ils.actor.anon_cache.set_value', 
+        $cache_key, ANON_CACHE_MYLIST, $list);
+
+    return $self->mylist_action_redirect($cache_key);
+}
+
+# Removes a record ID from My List
+sub load_mylist_del {
+    my $self = shift;
+    my @rec_ids = $self->cgi->param('record');
+
+    my ($cache_key, $list) = $self->fetch_mylist;
+    return $self->mylist_action_redirect unless $cache_key;
+
+    my @keep;
+    foreach my $id (@$list) { push(@keep, $id) unless grep { $id eq $_ } @rec_ids; }
+
+    $cache_key = $U->simplereq(
+        'open-ils.actor',
+        'open-ils.actor.anon_cache.set_value', 
+        $cache_key, ANON_CACHE_MYLIST, \@keep
+    );
+
+    return $self->mylist_action_redirect($cache_key);
+}
+
+sub load_cache_clear {
+    my $self = shift;
+    $self->clear_anon_cache;
+    return $self->mylist_action_redirect;
+}
+
+# Wipes the entire anonymous cache, including My List
+sub clear_anon_cache {
+    my $self = shift;
+    my $field = shift;
+
+    my $cache_key = $self->cgi->cookie(COOKIE_ANON_CACHE) or return;
+
+    $U->simplereq(
+        'open-ils.actor',
+        'open-ils.actor.anon_cache.delete_session', $cache_key)
+        if $cache_key;
+
+}
+
+# Called after an anon-cache / My List action occurs.  Redirect
+# to the redirect_url (cgi param) or referrer or home.
+sub mylist_action_redirect {
+    my $self = shift;
+    my $cache_key = shift;
+
+    return $self->generic_redirect(
+        undef, 
+        $self->cgi->cookie(
+            -name => COOKIE_ANON_CACHE,
+            -path => '/',
+            -value => ($cache_key) ? $cache_key : '',
+            -expires => ($cache_key) ? undef : '-1h'
+        )
+    );
+}
+
+sub load_mylist {
+    my ($self) = shift;
+    (undef, $self->ctx->{mylist}, $self->ctx->{mylist_marc_xml}) =
+        $self->fetch_mylist(1);
+
+    return Apache2::Const::OK;
+}
+
+1;
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm
new file mode 100644 (file)
index 0000000..c3716d5
--- /dev/null
@@ -0,0 +1,128 @@
+package OpenILS::WWW::EGCatLoader;
+use strict; use warnings;
+use Apache2::Const -compile => qw(OK DECLINED FORBIDDEN HTTP_INTERNAL_SERVER_ERROR REDIRECT HTTP_BAD_REQUEST);
+use OpenSRF::Utils::Logger qw/$logger/;
+use OpenILS::Utils::CStoreEditor qw/:funcs/;
+use OpenILS::Utils::Fieldmapper;
+use OpenILS::Application::AppUtils;
+my $U = 'OpenILS::Application::AppUtils';
+
+# context additions: 
+#   record : bre object
+sub load_record {
+    my $self = shift;
+    $self->ctx->{page} = 'record';
+
+    my $org = $self->cgi->param('loc') || $self->ctx->{aou_tree}->()->id;
+    my $depth = $self->cgi->param('depth') || 0;
+    my $copy_limit = int($self->cgi->param('copy_limit') || 20);
+    my $copy_offset = int($self->cgi->param('copy_offset') || 0);
+
+    my $rec_id = $self->ctx->{page_args}->[0]
+        or return Apache2::Const::HTTP_BAD_REQUEST;
+
+    # run copy retrieval in parallel to bib retrieval
+    my $copy_rec = OpenSRF::AppSession->create('open-ils.cstore')->request(
+        'open-ils.cstore.json_query.atomic', 
+        $self->mk_copy_query($rec_id, $org, $depth, $copy_limit, $copy_offset));
+
+    $self->ctx->{record} = $self->editor->retrieve_biblio_record_entry($rec_id);
+    $self->ctx->{marc_xml} = XML::LibXML->new->parse_string($self->ctx->{record}->marc);
+
+    $self->ctx->{copies} = $copy_rec->gather(1);
+    $self->ctx->{copy_limit} = $copy_limit;
+    $self->ctx->{copy_offset} = $copy_offset;
+
+    return Apache2::Const::OK;
+}
+
+sub mk_copy_query {
+    my $self = shift;
+    my $rec_id = shift;
+    my $org = shift;
+    my $depth = shift;
+    my $copy_limit = shift;
+    my $copy_offset = shift;
+
+    my $query = {
+        select => {
+            acp => ['id', 'barcode', 'circ_lib', 'create_date', 'age_protect', 'holdable'],
+            acpl => [
+                {column => 'name', alias => 'copy_location'},
+                {column => 'holdable', alias => 'location_holdable'}
+            ],
+            ccs => [
+                {column => 'name', alias => 'copy_status'},
+                {column => 'holdable', alias => 'status_holdable'}
+            ],
+            acn => [
+                {column => 'label', alias => 'call_number_label'},
+                {column => 'id', alias => 'call_number'}
+            ],
+            circ => ['due_date'],
+        },
+        from => {
+            acp => {
+                acn => {},
+                acpl => {},
+                ccs => {},
+                circ => {type => 'left'},
+                aou => {}
+            }
+        },
+        where => {
+            '+acp' => {
+                deleted => 'f',
+                call_number => {
+                    in => {
+                        select => {acn => ['id']},
+                        from => 'acn',
+                        where => {record => $rec_id}
+                    }
+                },
+                circ_lib => {
+                    in => {
+                        select => {aou => [{
+                            column => 'id', 
+                            transform => 'actor.org_unit_descendants', 
+                            result_field => 'id', 
+                            params => [$depth]
+                        }]},
+                        from => 'aou',
+                        where => {id => $org}
+                    }
+                }
+            },
+            '+acn' => {deleted => 'f'},
+            '+circ' => {checkin_time => undef}
+        },
+
+        # Order is: copies with circ_lib=org, followed by circ_lib name, followed by call_number label
+        order_by => [
+            {class => 'aou', field => 'name'}, 
+            {class => 'acn', field => 'label'}
+        ],
+
+        limit => $copy_limit,
+        offset => $copy_offset
+    };
+
+    # Filter hidden items if this is the public catalog
+    unless($self->ctx->{is_staff}) { 
+        $query->{where}->{'+acp'}->{opac_visible} = 't';
+        $query->{where}->{'+acpl'}->{opac_visible} = 't';
+        $query->{where}->{'+ccs'}->{opac_visible} = 't';
+    }
+
+    return $query;
+    #return $self->editor->json_query($query);
+}
+
+sub mk_marc_html {
+    my($self, $rec_id) = @_;
+
+    $self->ctx->{marc_html} = $U->simplereq(
+        'open-ils.search', 'open-ils.search.biblio.record.html', $rec_id);
+}
+
+1;
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm
new file mode 100644 (file)
index 0000000..7a4d491
--- /dev/null
@@ -0,0 +1,157 @@
+package OpenILS::WWW::EGCatLoader;
+use strict; use warnings;
+use Apache2::Const -compile => qw(OK DECLINED FORBIDDEN HTTP_INTERNAL_SERVER_ERROR REDIRECT HTTP_BAD_REQUEST);
+use OpenSRF::Utils::Logger qw/$logger/;
+use OpenILS::Utils::CStoreEditor qw/:funcs/;
+use OpenILS::Utils::Fieldmapper;
+use OpenILS::Application::AppUtils;
+my $U = 'OpenILS::Application::AppUtils';
+
+
+sub _prepare_biblio_search_basics {
+    my ($cgi) = @_;
+
+    return $cgi->param('query') unless $cgi->param('qtype');
+
+    my %parts;
+    my @part_names = qw/qtype contains query/;
+    $parts{$_} = [ $cgi->param($_) ] for (@part_names);
+
+    my @chunks = ();
+    for (my $i = 0; $i < scalar @{$parts{'qtype'}}; $i++) {
+        my ($qtype, $contains, $query) = map { $parts{$_}->[$i] } @part_names;
+
+        next unless $query =~ /\S/;
+        push(@chunks, $qtype . ':') unless $qtype eq 'keyword' and $i == 0;
+
+        # This stuff probably will need refined or rethought to better handle
+        # the weird things Real Users will surely type in.
+        $contains = "" unless defined $contains; # silence warning
+        if ($contains eq 'nocontains') {
+            $query =~ s/"//g;
+            $query = ('"' . $query . '"') if index $query, ' ';
+            $query = '-' . $query;
+        } elsif ($contains eq 'phrase') {
+            $query =~ s/"//g;
+            $query = ('"' . $query . '"') if index $query, ' ';
+        } elsif ($contains eq 'exact') {
+            $query =~ s/[\^\$]//g;
+            $query = '^' . $query . '$';
+        }
+        push @chunks, $query;
+    }
+
+    return join(' ', @chunks);
+}
+
+sub _prepare_biblio_search {
+    my ($cgi, $ctx) = @_;
+
+    my $query = _prepare_biblio_search_basics($cgi);
+
+    $query = ('#' . $_ . ' ' . $query) foreach ($cgi->param('modifier'));
+
+    foreach (grep /^fi:/, $cgi->param) {
+        /:(\w+)$/ or next;
+        my $term = join(",", $cgi->param($_));
+        $query .= " $1($term)" if length $term;
+    }
+
+    if ($cgi->param('sort')) {
+        my ($axis, $desc) = split /\./, $cgi->param('sort');
+        $query .= " sort($axis)";
+        $query .= '#descending' if $desc;
+    }
+
+    if ($cgi->param('pubdate') && $cgi->param('date1')) {
+        if ($cgi->param('pubdate') eq 'between') {
+            $query .= ' between(' . $cgi->param('date1');
+            $query .= ',' .  $cgi->param('date2') if $cgi->param('date2');
+            $query .= ')';
+        } elsif ($cgi->param('pubdate') eq 'is') {
+            $query .= ' between(' . $cgi->param('date1') .
+                ',' .  $cgi->param('date1') . ')';  # sic, date1 twice
+        } else {
+            $query .= ' ' . $cgi->param('pubdate') .
+                '(' . $cgi->param('date1') . ')';
+        }
+    }
+
+    my $site = $cgi->param('loc');
+    if (defined($site) and ($site ne $ctx->{aou_tree}->()->id) and not $query =~ /site\(\d+\)/) {
+        $query .= " site($site)";
+    }
+    if (defined($cgi->param('depth')) and not $query =~ /depth\(\d+\)/) {
+        my $depth = defined $cgi->param('depth') ?
+            $cgi->param('depth') : $ctx->{find_aou}->($site)->ou_type->depth;
+        $query .= " depth($depth)";
+    }
+
+    return $query;
+}
+
+# context additions: 
+#   page_size
+#   hit_count
+#   records : list of bre's and copy-count objects
+sub load_rresults {
+    my $self = shift;
+    my $cgi = $self->cgi;
+    my $ctx = $self->ctx;
+    my $e = $self->editor;
+
+    $ctx->{page} = 'rresult';
+    my $page = $cgi->param('page') || 0;
+    my $facet = $cgi->param('facet');
+    my $limit = $cgi->param('limit') || 10; # TODO user settings
+    my $offset = $page * $limit;
+
+    my $query = _prepare_biblio_search($cgi, $ctx);
+    # Limit and offset will stay here. Everything else should be part of
+    # the query string, not special args.
+    my $args = {'limit' => $limit, 'offset' => $offset};
+
+    # Stuff these into the TT context so that templates can use them in redrawing forms
+    $ctx->{processed_search_query} = $query;
+
+    $query = "$query $facet" if $facet; # TODO
+
+    my $results;
+
+    try {
+
+        my $method = 'open-ils.search.biblio.multiclass.query';
+        $method .= '.staff' if $ctx->{is_staff};
+        $results = $U->simplereq('open-ils.search', $method, $args, $query, 1);
+
+    } catch Error with {
+        my $err = shift;
+        $logger->error("multiclass search error: $err");
+        $results = {count => 0, ids => []};
+    };
+
+    my $rec_ids = [map { $_->[0] } @{$results->{ids}}];
+
+    $ctx->{records} = [];
+    $ctx->{search_facets} = {};
+    $ctx->{page_size} = $limit;
+    $ctx->{hit_count} = $results->{count};
+
+    return Apache2::Const::OK if @$rec_ids == 0;
+
+    my ($facets, @data) = $self->get_records_and_facets($rec_ids, $results->{facet_key});
+
+    # shove recs into context in search results order
+    for my $rec_id (@$rec_ids) {
+        push(
+            @{$ctx->{records}},
+            grep { $_->{bre}->id == $rec_id } @data
+        );
+    }
+
+    $ctx->{search_facets} = $facets;
+
+    return Apache2::Const::OK;
+}
+
+1;
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm
new file mode 100644 (file)
index 0000000..35e41fc
--- /dev/null
@@ -0,0 +1,216 @@
+package OpenILS::WWW::EGCatLoader;
+use strict; use warnings;
+use Apache2::Const -compile => qw(OK DECLINED FORBIDDEN HTTP_INTERNAL_SERVER_ERROR REDIRECT HTTP_BAD_REQUEST);
+use OpenSRF::Utils::Logger qw/$logger/;
+use OpenILS::Utils::CStoreEditor qw/:funcs/;
+use OpenILS::Utils::Fieldmapper;
+use OpenILS::Application::AppUtils;
+my $U = 'OpenILS::Application::AppUtils';
+
+our %cache = (
+    map => {aou => {}}, # others added dynamically as needed
+    list => {},
+    org_settings => {}
+);
+
+sub init_ro_object_cache {
+    my $self = shift;
+    my $e = $self->editor;
+    my $ctx = $self->ctx;
+
+    # fetch-on-demand-and-cache subs for commonly used public data
+    my @public_classes = qw/ccs aout cifm citm clm cmf crahp/;
+
+    for my $hint (@public_classes) {
+
+        my ($class) = grep {
+            $Fieldmapper::fieldmap->{$_}->{hint} eq $hint
+        } keys %{ $Fieldmapper::fieldmap };
+
+        my $ident_field =  $Fieldmapper::fieldmap->{$class}->{identity};
+
+           $class =~ s/Fieldmapper:://o;
+           $class =~ s/::/_/g;
+
+        # copy statuses
+        my $list_key = $hint . '_list';
+        my $find_key = "find_$hint";
+
+        $ctx->{$list_key} = sub {
+            my $method = "retrieve_all_$class";
+            $cache{list}{$hint} = $e->$method() unless $cache{list}{$hint};
+            return $cache{list}{$hint};
+        };
+    
+        $cache{map}{$hint} = {} unless $cache{map}{$hint};
+
+        $ctx->{$find_key} = sub {
+            my $id = shift;
+            return $cache{map}{$hint}{$id} if $cache{map}{$hint}{$id}; 
+            ($cache{map}{$hint}{$id}) = grep { $_->$ident_field eq $id } @{$ctx->{$list_key}->()};
+            return $cache{map}{$hint}{$id};
+        };
+
+    }
+
+    $ctx->{aou_tree} = sub {
+
+        # fetch the org unit tree
+        unless($cache{aou_tree}) {
+            my $tree = $e->search_actor_org_unit([
+                           {   parent_ou => undef},
+                           {   flesh            => -1,
+                                   flesh_fields    => {aou =>  ['children']},
+                                   order_by        => {aou => 'name'}
+                           }
+                   ])->[0];
+
+            # flesh the org unit type for each org unit
+            # and simultaneously set the id => aou map cache
+            sub flesh_aout {
+                my $node = shift;
+                my $ctx = shift;
+                $node->ou_type( $ctx->{find_aout}->($node->ou_type) );
+                $cache{map}{aou}{$node->id} = $node;
+                flesh_aout($_, $ctx) foreach @{$node->children};
+            };
+            flesh_aout($tree, $ctx);
+
+            $cache{aou_tree} = $tree;
+        }
+
+        return $cache{aou_tree};
+    };
+
+    # Add a special handler for the tree-shaped org unit cache
+    $ctx->{find_aou} = sub {
+        my $org_id = shift;
+        $ctx->{aou_tree}->(); # force the org tree to load
+        return $cache{map}{aou}{$org_id};
+    };
+
+    # turns an ISO date into something TT can understand
+    $ctx->{parse_datetime} = sub {
+        my $date = shift;
+        $date = DateTime::Format::ISO8601->new->parse_datetime(cleanse_ISO8601($date));
+        return sprintf(
+            "%0.2d:%0.2d:%0.2d %0.2d-%0.2d-%0.4d",
+            $date->hour,
+            $date->minute,
+            $date->second,
+            $date->day,
+            $date->month,
+            $date->year
+        );
+    };
+
+    # retrieve and cache org unit setting values
+    $ctx->{get_org_setting} = sub {
+        my($org_id, $setting) = @_;
+
+        $cache{org_settings}{$org_id} = {} 
+            unless $cache{org_settings}{$org_id};
+
+        $cache{org_settings}{$org_id}{$setting} = 
+            $U->ou_ancestor_setting_value($org_id, $setting)
+                unless exists $cache{org_settings}{$org_id}{$setting};
+
+        return $cache{org_settings}{$org_id}{$setting};
+    };
+}
+
+sub generic_redirect {
+    my $self = shift;
+    my $url = shift;
+    my $cookie = shift; # can be an array of cgi.cookie's
+
+    $self->apache->print(
+        $self->cgi->redirect(
+            -url => $url || 
+                $self->cgi->param('redirect_to') || 
+                $self->ctx->{referer} || 
+                $self->ctx->{home_page},
+            -cookie => $cookie
+        )
+    );
+
+    return Apache2::Const::REDIRECT;
+}
+
+sub get_records_and_facets {
+    my ($self, $rec_ids, $facet_key) = @_;
+
+    my $cstore = OpenSRF::AppSession->create('open-ils.cstore');
+    my $bre_req = $cstore->request(
+        'open-ils.cstore.direct.biblio.record_entry.search', {id => $rec_ids}
+    );
+
+    my $search = OpenSRF::AppSession->create('open-ils.search');
+    my $facet_req = $search->request(
+        'open-ils.search.facet_cache.retrieve', $facet_key, 10
+    ) if $facet_key;
+
+    my @data;
+    while (my $resp = $bre_req->recv) {
+        my $bre = $resp->content;
+
+        # XXX farm out to multiple cstore sessions before loop,
+        # then collect after
+        my $copy_counts = $self->editor->json_query(
+            {from => ['asset.record_copy_count', 1, $bre->id, 0]}
+        )->[0];
+
+        push @data, {
+            bre => $bre,
+            marc_xml => XML::LibXML->new->parse_string($bre->marc),
+            copy_counts => $copy_counts
+        };
+    }
+
+    $cstore->kill_me;
+
+    my $facets;
+    if ($facet_key) {
+        $facets = $facet_req->gather(1);
+
+        $facets->{$_} = {
+            cmf => $self->ctx->{find_cmf}->($_),
+            data => $facets->{$_}
+        } for keys %$facets;    # quick-n-dirty
+    } else {
+        $facets = undef;
+    }
+
+    return ($facets, @data);
+}
+
+sub fetch_marc_xml_by_id {
+    my ($self, $id_list) = @_;
+    $id_list = [$id_list] unless ref($id_list);
+
+    {
+        no warnings qw/numeric/;
+        $id_list = [map { int $_ } @$id_list];
+        $id_list = [grep { $_ > 0} @$id_list];
+    };
+
+    return {} if scalar(@$id_list) < 1;
+
+    # I'm just sure there needs to be some more efficient way to get all of
+    # this.
+    my $results = $self->editor->json_query({
+        "select" => {"bre" => ["id", "marc"]},
+        "from" => {"bre" => {}},
+        "where" => {"id" => $id_list}
+    }) or return $self->editor->die_event;
+
+    my $marc_xml = {};
+    for my $r (@$results) {
+        $marc_xml->{$r->{"id"}} =
+            (new XML::LibXML)->parse_string($r->{"marc"});
+    }
+
+    return $marc_xml;
+}
+
+1;
index ec765af..67e419d 100644 (file)
@@ -7,6 +7,7 @@ use File::stat;
 use Apache2::Const -compile => qw(OK DECLINED HTTP_INTERNAL_SERVER_ERROR);
 use Apache2::Log;
 use OpenSRF::EX qw(:try);
+use OpenILS::Utils::CStoreEditor;
 
 use constant OILS_HTTP_COOKIE_SKIN => 'oils:skin';
 use constant OILS_HTTP_COOKIE_THEME => 'oils:theme';
@@ -15,12 +16,13 @@ use constant OILS_HTTP_COOKIE_LOCALE => 'oils:locale';
 my $web_config;
 my $web_config_file;
 my $web_config_edit_time;
+my %lh_cache; # locale handlers
 
 sub import {
     my $self = shift;
     $web_config_file = shift || '';
     unless(-r $web_config_file) {
-        warn "Invalid web config $web_config_file";
+        warn "Invalid web config $web_config_file\n";
         return;
     }
     check_web_config();
@@ -32,26 +34,80 @@ sub handler {
     check_web_config($r); # option to disable this
     my $ctx = load_context($r);
     my $base = $ctx->{base_path};
+
+    $r->content_type('text/html; encoding=utf8');
+
     my($template, $page_args, $as_xml) = find_template($r, $base, $ctx);
+    $ctx->{page_args} = $page_args;
+
+    my $stat = run_context_loader($r, $ctx);
+
+    return $stat unless $stat == Apache2::Const::OK;
     return Apache2::Const::DECLINED unless $template;
 
     $template = $ctx->{skin} . "/$template";
-    $ctx->{page_args} = $page_args;
-    $r->content_type('text/html; encoding=utf8');
 
     my $tt = Template->new({
         OUTPUT => ($as_xml) ?  sub { parse_as_xml($r, $ctx, @_); } : $r,
         INCLUDE_PATH => $ctx->{template_paths},
+        DEBUG => $ctx->{debug_template},
+        PLUGINS => {
+            EGI18N => 'OpenILS::WWW::EGWeb::I18NFilter',
+            CGI_utf8 => 'OpenILS::WWW::EGWeb::CGI_utf8'
+        }
     });
 
-    unless($tt->process($template, {ctx => $ctx})) {
-        $r->log->warn('Template error: ' . $tt->error);
+    unless($tt->process($template, {ctx => $ctx, l => set_text_handler($ctx, $r)})) {
+        $r->log->warn('egweb: template error: ' . $tt->error);
         return Apache2::Const::HTTP_INTERNAL_SERVER_ERROR;
     }
 
     return Apache2::Const::OK;
 }
 
+sub set_text_handler {
+    my $ctx = shift;
+    my $r = shift;
+
+    my $locale = $ctx->{locale};
+    $locale =~ s/-/_/g;
+
+    $r->log->debug("egweb: messages locale = $locale");
+
+    unless($lh_cache{$locale}) {
+        $r->log->info("egweb: Unsupported locale: $locale");
+        $lh_cache{$locale} = $lh_cache{'en_US'};
+    }
+
+    return $OpenILS::WWW::EGWeb::I18NFilter::maketext = 
+        sub { return $lh_cache{$locale}->maketext(@_); };
+}
+
+
+
+sub run_context_loader {
+    my $r = shift;
+    my $ctx = shift;
+
+    my $stat = Apache2::Const::OK;
+
+    my $loader = $r->dir_config('OILSWebContextLoader');
+    return $stat unless $loader;
+
+    eval {
+        $loader->use;
+        $stat = $loader->new($r, $ctx)->load;
+    };
+
+    if($@) {
+        $r->log->error("egweb: Context Loader error: $@");
+        return Apache2::Const::HTTP_INTERNAL_SERVER_ERROR;
+    }
+
+    $r->log->debug("egweb: context loader resulted in status $stat");
+    return $stat;
+}
+
 sub parse_as_xml {
     my $r = shift;
     my $ctx = shift;
@@ -65,9 +121,9 @@ sub parse_as_xml {
         $data = $ctx->{final_dtd} . "\n" . $data;
         $success = 1;
     } otherwise {
-       my $e = shift;
+           my $e = shift;
         my $err = "Invalid XML: $e";
-        $r->log->error($err);
+        $r->log->error("egweb: $err");
         $r->content_type('text/plain; encoding=utf8');
         $r->print("\n$err\n\n$data");
     };
@@ -79,16 +135,23 @@ sub parse_as_xml {
 sub load_context {
     my $r = shift;
     my $cgi = CGI->new;
-    my $ctx = $web_config->{ctx};
+    my $ctx = {}; # new context for each page load
+    $ctx->{$_} = $web_config->{base_ctx}->{$_} for keys %{$web_config->{base_ctx}};
     $ctx->{hostname} = $r->hostname;
     $ctx->{base_url} = $cgi->url(-base => 1);
     $ctx->{skin} = $cgi->cookie(OILS_HTTP_COOKIE_SKIN) || 'default';
     $ctx->{theme} = $cgi->cookie(OILS_HTTP_COOKIE_THEME) || 'default';
+
     $ctx->{locale} = 
         $cgi->cookie(OILS_HTTP_COOKIE_LOCALE) || 
         parse_accept_lang($r->headers_in->get('Accept-Language')) || 'en-US';
-    $r->log->debug('skin = ' . $ctx->{skin} . ' : theme = ' . 
-        $ctx->{theme} . ' : locale = ' . $ctx->{locale});
+
+    my $mprefix = $ctx->{media_prefix};
+    if($mprefix and $mprefix !~ /^http/ and $mprefix !~ /^\//) {
+        # if a hostname is provided /w no protocol, match the protocol to the current page
+        $ctx->{media_prefix} = ($cgi->https) ? "https://$mprefix" : "http://$mprefix";
+    }
+
     return $ctx;
 }
 
@@ -146,7 +209,7 @@ sub find_template {
             last unless $localpath;
             for my $tpath (@{$ctx->{template_paths}}) {
                 my $fpath = "$tpath/$skin/$localpath.$ext";
-                $r->log->debug("looking at possible template $fpath");
+                $r->log->debug("egweb: looking at possible template $fpath");
                 if(-r $fpath) {
                     $template = "$localpath.$ext";
                     last;
@@ -161,12 +224,12 @@ sub find_template {
 
         # no template configured or found
         unless($template) {
-            $r->log->warn("No template configured for path $path");
+            $r->log->debug("egweb: No template configured for path $path");
             return ();
         }
     }
 
-    $r->log->debug("template = $template : page args = @$page_args");
+    $r->log->debug("egweb: template = $template : page args = @$page_args");
     return ($template, $page_args, $as_xml);
 }
 
@@ -176,12 +239,46 @@ sub check_web_config {
     my $r = shift;
     my $epoch = stat($web_config_file)->mtime;
     unless($web_config_edit_time and $web_config_edit_time == $epoch) {
-        $r->log->debug("Reloading web config after edit...") if $r;
+        $r->log->debug("egweb: Reloading web config after edit...") if $r;
         $web_config_edit_time = $epoch;
         $web_config = parse_config($web_config_file);
     }
 }
 
+# Create an I18N sub-module for each supported locale
+# Each module creates its own MakeText lexicon by parsing .po/.mo files
+sub load_locale_handlers {
+    my $ctx = shift;
+    my $locales = $ctx->{locales};
+
+    $locales->{en_US} = {} unless exists $locales->{en_US};
+
+    for my $lang (keys %$locales) {
+        my $messages = $locales->{$lang};
+        $messages = '' if ref $messages; # empty {}
+
+        # TODO Can we do this without eval?
+        my $eval = <<EVAL;
+            package OpenILS::WWW::EGWeb::I18N::$lang;
+            use base 'OpenILS::WWW::EGWeb::I18N';
+            if(\$messages) {
+                use Locale::Maketext::Lexicon::Gettext;
+                if(open F, '$messages') {
+                    our %Lexicon = (%Lexicon, %{ Locale::Maketext::Lexicon::Gettext->parse(<F>) });
+                    close F;
+                } else {
+                    warn "unable to open messages file: $messages"; 
+                }
+            }
+EVAL
+        eval $eval;
+        warn "$@\n" if $@; # TODO better logging
+        $lh_cache{$lang} = "OpenILS::WWW::EGWeb::I18N::$lang"->new;
+    }
+}
+
+
+
 sub parse_config {
     my $cfg_file = shift;
     my $data = XML::Simple->new->XMLin($cfg_file);
@@ -191,9 +288,12 @@ sub parse_config {
     $ctx->{media_prefix} = (ref $data->{media_prefix}) ? '' : $data->{media_prefix};
     $ctx->{base_path} = (ref $data->{base_path}) ? '' : $data->{base_path};
     $ctx->{template_paths} = [];
-    $ctx->{force_valid_xml} = ($data->{force_valid_xml} =~ /true/io) ? 1 : 0;
+    $ctx->{force_valid_xml} = ( ($data->{force_valid_xml}||'') =~ /true/io) ? 1 : 0;
+    $ctx->{debug_template} = ( ($data->{debug_template}||'')  =~ /true/io) ? 1 : 0;
     $ctx->{default_template_extension} = $data->{default_template_extension} || 'tt2';
     $ctx->{web_dir} = $data->{web_dir};
+    $ctx->{locales} = $data->{locales};
+    load_locale_handlers($ctx);
 
     my $tpaths = $data->{template_paths}->{path};
     $tpaths = [$tpaths] unless ref $tpaths;
@@ -217,7 +317,7 @@ sub parse_config {
         }
     }
 
-    return {ctx => $ctx, handlers => $handlers};
+    return {base_ctx => $ctx, handlers => $handlers};
 }
 
 package PathConfig;
@@ -226,5 +326,9 @@ sub new {
     return bless(\%args, $class);
 }
 
+# base class for all supported locales
+package OpenILS::WWW::EGWeb::I18N;
+use base 'Locale::Maketext';
+our %Lexicon = (_AUTO => 1);
 
 1;
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb/CGI_utf8.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb/CGI_utf8.pm
new file mode 100644 (file)
index 0000000..0239e1b
--- /dev/null
@@ -0,0 +1,44 @@
+package OpenILS::WWW::EGWeb::CGI_utf8;
+
+# The code in this module is copied from (except for a tiny modification)
+# Template::Plugin::CGI, which is written by:
+#
+# Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>
+#
+# Copyright (C) 1996-2007 Andy Wardley.  All Rights Reserved.
+#
+# This module is free software; you can redistribute it and/or
+# modify it under the same terms as Perl itself.
+
+use strict;
+use warnings;
+use base 'Template::Plugin';
+use CGI qw(:all -utf8);
+
+sub new {
+    my $class   = shift;
+    my $context = shift;
+    new CGI(@_);
+}
+
+# monkeypatch CGI::params() method to Do The Right Thing in TT land
+
+sub CGI::params {
+    my $self = shift;
+    local $" = ', ';
+
+    return $self->{ _TT_PARAMS } ||= do {
+        # must call Vars() in a list context to receive
+        # plain list of key/vals rather than a tied hash
+        my $params = { $self->Vars() };
+
+        # convert any null separated values into lists
+        @$params{ keys %$params } = map { 
+            /\0/ ? [ split /\0/ ] : $_ 
+        } values %$params;
+
+        $params;
+    };
+}
+
+1;
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb/I18NFilter.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb/I18NFilter.pm
new file mode 100644 (file)
index 0000000..cc931fa
--- /dev/null
@@ -0,0 +1,19 @@
+package OpenILS::WWW::EGWeb::I18NFilter;
+use Template::Plugin::Filter;
+use base qw(Template::Plugin::Filter);
+our $DYNAMIC = 1;
+our $maketext;
+
+sub filter {
+    my ($self, $text, $args) = @_;
+    return $maketext->($text, @$args);
+}
+
+sub init {
+    my $self = shift;
+    $self->install_filter('l');
+    return $self;
+}
+
+1;
+
diff --git a/Open-ILS/web/css/skin/default/opac/contentslider.css b/Open-ILS/web/css/skin/default/opac/contentslider.css
new file mode 100644 (file)
index 0000000..64a6d25
--- /dev/null
@@ -0,0 +1,39 @@
+.sliderwrapper{
+position: relative; /*leave as is*/
+overflow: hidden; /*leave as is*/
+width: 675px; /*width of featured content slider*/
+height: 213px;
+}
+
+
+
+.sliderwrapper .contentdiv{
+visibility: hidden; /*leave as is*/
+position: absolute; /*leave as is*/ 
+left: 0;  /*leave as is*/
+top: 0;  /*leave as is*/
+width: 675px; /*width of content DIVs within slider. Total width should equal slider's inner width (390+5+5=400) */
+height: 100%;
+filter:progid:DXImageTransform.Microsoft.alpha(opacity=100);
+-moz-opacity: 1;
+opacity: 1;
+}
+
+.pagination{
+width: 400px; /*Width of pagination DIV. Total width should equal slider's outer width (400+10+10=420)*/
+text-align: right;
+background-color: navy;
+padding: 5px 10px;
+}
+
+.pagination a{
+padding: 0 5px;
+text-decoration: none; 
+color: #00007D;
+background: white;
+}
+
+.pagination a:hover, .pagination a.selected{
+color: #000;
+background-color: #FEE496;
+}
\ No newline at end of file
diff --git a/Open-ILS/web/css/skin/default/opac/semiauto.css b/Open-ILS/web/css/skin/default/opac/semiauto.css
new file mode 100644 (file)
index 0000000..60fd1df
--- /dev/null
@@ -0,0 +1,181 @@
+/* once done renaming and everything, combine with style.css */
+
+/* Verfied in-use classes --------------------------- */
+.opac-auto-004 { background: #E0F0E0; }
+.opac-auto-009 { border: 3px solid #E0E0E0; }
+.opac-auto-010 { border-bottom: 1px dotted #ccc; padding-top: 10px; }
+.opac-auto-011 { border-bottom: 1px dotted #ccc; padding-top: 6px; }
+.opac-auto-012 { border-bottom: none; }
+.opac-auto-013 { border-bottom: none; *height: 0px; }
+.opac-auto-015 { border-left: 1px solid #e9ebf3; padding-right: 27px; }
+.opac-auto-017 { border: none; width: 100%; }
+.opac-auto-018 { border-top: 1px dotted #ccc; padding-top: 17px; }
+.clear-both { clear: both; }
+.common-no-pad { clear: both; height: 0px; margin: 0px; padding: 0px; }
+.common-full-pad { clear: both; height: 15px; }
+.opac-auto-029 { color: #333; font-weight: bold; font-size: 13px; }
+.opac-auto-030 { color: #545454; }
+.opac-auto-031 { color: #9999FF; padding-left: 10px; font-size: 7pt; font-weight: 300; }
+.red { color: red; }
+.bold-red { color: red; font-weight: bold }
+.pointer { cursor: pointer; }
+/* ------------------------------------------- */
+
+
+#lib_selector_span { display: none }
+.float-left { float: left; }
+.bookbag-name { float: left; font-weight: bold; padding-top: 5px; }
+.bookbag-share { float: left; padding: 5px 0px 0px 10px; }
+.left-corner { float: left; width: 163px; height: 30px; background: url('/images/utils-corner-mid.png') repeat-x top; }
+.float-right { float: right; }
+.opac-auto-045 { float: right; margin-right: 17px; }
+.opac-auto-046 { float: right; width: 214px; }
+.opac-auto-047 { float: right; width: 353px; background: #ccc; padding: 10px; margin-top: 7px; }
+.opac-auto-048 { float: right; width: 65px; }
+#they_said_dont_touch { float: right; width: 675px; height: 213px; color: green; overflow: hidden; }
+.opac-auto-050 { float: right; width: 85px; }
+.ten-px { font-size: 10px; }
+.eleven-px { font-size: 11px; }
+.eight-pt { font-size: 8pt; }
+.opac-auto-054 { font-size: 8pt; padding-left: 20px; }
+.bold { font-weight: bold; }
+.opac-auto-057 { font-weight: bold; padding: 5px; margin: 5px; width: 100%; }
+.opac-auto-058 { font-weight: bold; padding-left: 10px; }
+#anon_list_name { font-weight: bold; padding-right: 10px; }
+.opac-auto-060 { font-weight: normal; }
+.opac-auto-061 { height: 0px; border-top: 1px solid #b7b7b7; border-bottom: 1px solid #d4d4d4; margin: 15px 0px; }
+.small-height { height: 10px; }
+.normal-height { height: 15px; }
+.big-height { height: 20px; }
+.very-big-height { height: 30px; }
+#gold-links-holder { height: 24px; background: #252525; }
+.opac-auto-067 { margin: 3px; width: 100%; }
+.big-block { margin: auto; width: 974px; height: 0px; }
+.opac-auto-069 { margin-bottom: 10px; }
+.opac-auto-070 { margin-bottom: 20px; }
+.opac-auto-071 { margin-bottom: 5px; }
+.opac-auto-072 { margin-left: 20px; }
+.bookbag-list { margin-left: 5px; margin-top: 5px; width: 91%; border: 0;}
+#cn_browse_where { margin-left: 6px; }
+.opac-auto-075 { margin-right: 20px; }
+.opac-auto-076 { margin-right: 3px; }
+.opac-auto-077 { margin-right: 4px; position: relative; top: -10px; }
+.opac-auto-078 { margin-right: 7px; }
+.opac-auto-079 { margin-top: 10px; }
+.opac-auto-080 { margin-top: 10px; margin-bottom: 10px; }
+.opac-auto-081 { margin-top: 13px; }
+.opac-auto-082 { margin-top: 29px; }
+.opac-auto-083 { margin-top: 2px; }
+.opac-auto-084 { margin-top: 5px; }
+.opac-auto-085 { margin-top: 6px; margin-left: 20px; width: 250px; padding: 5px; }
+.opac-auto-086 { margin-top: 8px; }
+.opac-auto-087 { max-width: 11em; }
+.opac-auto-088 { padding: 0px; }
+.opac-auto-089 { padding: 0px 10px; }
+.opac-auto-090 { padding: 10px; }
+.opac-auto-091 { padding: 10px 0px; }
+.opac-auto-092 { padding: 4px; text-align: center; }
+.pad-bottom-five { padding: 5px; }
+.opac-auto-094 { padding: 5px 7px 0px 0px; }
+.opac-auto-095 { padding: 5px 7px 0px 0px; white-space: nowrap; }
+.opac-auto-096 { padding: 6px }
+.opac-auto-097 { padding: 8px 0px 6px 0px; width: 100%; border: 0; }
+.opac-auto-097b { padding: 8px 0px 6px 0px; border: 0; }
+.opac-auto-098 { padding-bottom: 10px; }
+.opac-auto-099 { padding-bottom: 12px; color: #666; }
+.opac-auto-100 { padding-bottom: 16px; }
+.opac-auto-101 { padding-bottom: 1px; }
+.opac-auto-102 { padding-bottom: 7px; }
+.opac-auto-103 { padding-left: 10px; }
+.opac-auto-104 { padding-left: 11px; padding-right: 11px; }
+.opac-auto-105 { padding-left: 11px; padding-right: 13px; }
+.opac-auto-106 { padding-left: 15px; }
+.opac-auto-107 { padding-left: 15px; padding-bottom: 10px; }
+.opac-auto-108 { padding-left: 5px; }
+.opac-auto-109 { padding-left: 5px; padding-bottom: 10px; }
+.opac-auto-110 { padding-left: 6px; }
+.opac-auto-111 { padding-left: 8px; }
+.opac-auto-112 { padding-left: 9px; }
+.opac-auto-113 { padding-right: 10px; }
+.opac-auto-114 { padding-right: 15px; padding-left: 15px; }
+.opac-auto-115 { padding-right: 20px; }
+.opac-auto-116 { padding-right: 5px; }
+.opac-auto-117 { padding-right: 7px; }
+.pad-top-ten { padding-top: 10px; }
+.opac-auto-119 { padding-top: 14px; }
+.opac-auto-120 { padding-top: 5px; }
+.opac-auto-121 { padding-top: 6px; }
+.opac-auto-122 { padding-top: 7px; }
+.opac-auto-123 { padding-top: 8px; }
+.pos-abs { position: absolute; }
+#new_cat_link_holder { position: absolute; z-index: 101; }
+#new_cat_link_holder a { display: block; width: 675px; height: 213px; }
+.pos-rel { position: relative; }
+#search-box table { position: relative; left: -10px; }
+.opac-auto-129 { position: relative; left: -19px; }
+.opac-auto-130 { position: relative; left: 80px; }
+.opac-auto-131 { position: relative; top: 0px; left: 55px; }
+.opac-auto-132 { position: relative; top: 13px; }
+.opac-auto-133 { position: relative; top: -13px; left: 2px; font-size: 10px; }
+.opac-auto-134 { position: relative; top: -15px; left: 172px; }
+.opac-auto-135 { position: relative; top: -15px; left: -23px; }
+.opac-auto-136 { position: relative; top: 161px; left: 172px; }
+.opac-auto-137 { position: relative; top: 161px; left: -23px; }
+#home_adv_search_link { position: relative; top: -1px; left: 10px; }
+#util_back_btn { position: relative; top: 1px; left: 10px; }
+.opac-auto-140 { position: relative; top: -2px; }
+#util_help_btn { position: relative; top: 2px; left: 40px; }
+#util_forw_btn { position: relative; top: 2px; left: 50px; }
+.opac-auto-143 { position: relative; top: -3px; }
+#util_home_btn { position: relative; top: 3px; left: 20px; }
+.opac-auto-145 { position: relative; top: -3px; left: 3px; }
+.opac-auto-146 { position: relative; top: -3px; left: -5px; }
+.opac-auto-147 { position: relative; top: -5px; }
+#learn_more { position: relative; top: 5px; }
+.opac-auto-149 { position: relative; top: 5px; left: 25px; }
+#util_print_btn { position: relative; top: 5px; left: 30px; }
+.opac-auto-151 { position: relative; top: 75px; }
+#adv_reset { position: relative; top: -9px; }
+.opac-auto-153 { position: relative; z-index: 100; }
+.text-center { text-align: center; }
+.opac-auto-156 { text-align: center; font-weight: bold; }
+#adv_quick_search_sidebar { text-align: center; margin-top: 20px; width: 400px; }
+.opac-auto-158 { text-align: center; margin-top: 6px; margin-bottom: 6px }
+.opac-auto-159 { text-align: center; padding: 20px; width: 100% }
+.opac-auto-160 { text-align: center; padding-bottom: 8px; }
+.opac-auto-161 { text-align: right; padding-right: 7px; width: 62px; }
+.opac-auto-162 { vertical-align: top; }
+.nowrap { white-space: nowrap; }
+.opac-auto-164 { white-space: nowrap; padding-left: 5px; }
+.full-width { width: 100%; }
+.opac-auto-167 { width: 100%; border: 1px solid black; padding: 6px; margin-top: 5px; }
+.opac-auto-168 { width: 100%; border: 2px solid #E0F0E0; margin-bottom: 20px; }
+.opac-auto-169 { width: 100%; height: 100%; }
+.opac-auto-170 { width: 100%; margin-top: 20px; border-top: 1px dotted #ccc; padding-top: 8px; }
+.opac-auto-171 { font-size: 120%; text-align: center; font-style: italic; }
+.opac-auto-172 { width: 100%; text-align: center; padding-bottom: 5px; }
+.opac-auto-173 { width: 10px; }
+.opac-auto-174 { width: 111px; height: 25px; }
+.opac-auto-175 { width: 125px; height: 21px; }
+.opac-auto-176 { width: 129px; }
+#search_box { width: 162px; }
+.opac-auto-178 { width: 174px; }
+.opac-auto-179 { width: 175px; margin-right: 11px; }
+.opac-auto-180 { width: 182px; color: black; padding: 5px 25px; }
+.opac-auto-181 { width: 195px; }
+.opac-auto-182 { width: 230px; text-align: left; margin-top: 3px; }
+.opac-auto-183 { width: 250px; text-align: left; }
+.opac-auto-184 { width: 26px; height: 23px; margin-top: 6px; margin-bottom: 6px; }
+.opac-auto-185 { width: 324px; }
+.opac-auto-186 { width: 400px; margin-top: 20px; }
+.opac-auto-187 { width: 662px; }
+.opac-auto-188 { width: 700px; height: 30px; border: 1px solid red; }
+.opac-auto-189 { width: 742px; float: left; }
+.opac-auto-190 { width: 88px; }
+.opac-auto-191 { width: 90px; }
+#cn_browse_div > div { width: 90%; text-align: center; margin: 10px; }
+.opac-auto-193 { width: 91px; }
+#cn_browse { width: 95%; text-align: center; padding: 15px; }
+.opac-auto-195 { width: 99%; text-align: center }
+#homesearch_thing { width: 664px; height: 117px; background: #bda964; }
+#mystery_thing { width: 664px; height: 35px; background: #ffffff; }
diff --git a/Open-ILS/web/css/skin/default/opac/style.css b/Open-ILS/web/css/skin/default/opac/style.css
new file mode 100644 (file)
index 0000000..219a338
--- /dev/null
@@ -0,0 +1,961 @@
+body {
+       margin:0;
+       font-family: Arial, Helvetica, sans-serif;
+       font-size: 12px;
+       background:#333;
+}
+
+img {
+       border: none;
+}
+
+a {
+       color: #003399;
+       text-decoration: none;
+}
+
+a:hover {
+       text-decoration: underline;
+}
+
+#search-wrapper input[type=text] {
+       border:none;
+       margin:0;
+       padding:0;
+}
+
+#search-wrapper select {
+       border:1px solid #e9ebf3;
+       margin:0;
+       padding:0;
+       width:168px;
+}
+
+/*
+#search-wrapper select {
+       border:0px solid black;
+       filter:alpha(opacity=0);
+       -moz-opacity:0;
+       -khtml-opacity:0;
+       opacity:0;
+       padding:0;
+       margin:0;
+       height:18px;
+       font-size: 12px;
+}
+*/
+h1 {
+       margin:0;
+       margin-bottom: 5px;
+       font-size: 20px;
+       font-weight:normal;
+}
+
+h2 {
+       margin:0;
+       margin-bottom: 5px;
+       font-size: 14px;
+       font-weight:bold;
+}
+
+.hide_me, .hidden {
+       display: none;
+       visibility: hidden;
+}
+
+div.select-box-wrapper {
+       position:absolute;
+       padding-top:2px;
+       padding-left:3px;
+       overflow:hidden;
+       text-align:left;
+}
+
+div.select-wrapper {
+       border:1px solid #4C8AB0;
+       display:inline-block;
+       position:relative;
+       z-index:2;
+       background:url('/images/dropdown.gif') no-repeat right center;
+}
+
+div.select-wrapper:hover {
+       background:url('/images/dropdown-hover.gif') no-repeat right center;
+}
+
+#dash_wrapper {
+       width:500px;
+       position:relative;
+       top:-26px;
+}
+
+#dashboard {
+       clear:both;
+       float:right;
+       width:384px;
+}
+
+#dashboard span {
+       font-weight:bold;
+       position:relative;
+       left:-1px;
+}
+
+#dash_user {
+       font-weight: bold;
+       text-transform: capitalize;
+    position: relative;
+    top: 10px;
+}
+
+#dash_corner_mid1a {
+    vertical-align: top;
+    background: url('/images/dash-corner-mid1.png') repeat-x;
+    padding-left: 8px;
+}
+#dash_corner_mid1b {
+    background: url('/images/dash-corner-mid1.png') repeat-x;
+    padding: 0px 8px 0px 10px;
+}
+#dash_corner_mid1b img { position: relative; top: -1px; }
+#dash_corner_mid1c {
+    background: url('/images/dash-corner-mid1.png') repeat-x;
+    vertical-align: top;
+}
+#dash_corner_mid2a {
+    vertical-align: top;
+    width: 372px;
+    background: url('/images/dash-corner-mid2.png') repeat-x;
+}
+.dash-pos-out { position: relative; left: 3px; }
+.dash-pos-holds { position: relative; left: 100px; }
+.dash-align-out { text-align: right; width: 86px; }
+.dash-align-holds { text-align: right; width: 62px; }
+.dash-pos-pickup { position: relative; left: 170px; }
+.dash-align-pickup { text-align: right; width: 111px; }
+.dash-pos-fines { position: relative; left: 284px; }
+.dash-align-fines { text-align: right; width: 76px; }
+.pos-rel-top4 { position: relative; top: 4px; }
+#dash_number_row { position: relative; top: 6px; }
+#logout_link { left: 1px; }
+
+#dash_checked { color: #ffcc33; }
+#dash_holds { color: #ffcc33; }
+#dash_pickup { color: #1dd93c; }
+#dash_fines { color: #f41d36; }
+#header {
+       color: #fff;
+       padding: 26px 0px 26px 0px;
+       width: 974px;
+       margin: auto;
+       font-size:11px;
+}
+
+#header a {
+       color: #fff;
+}
+
+#header a:hover {
+       color: white;
+       text-decoration: none;
+}
+
+#header-links {
+       color: #afafaf;
+       font-size: 11px;
+       font-weight: bold;
+       position: relative;
+       top:4px;
+       
+}
+
+#header-links a {
+       color: #afafaf;
+       display: block;
+       float:left;
+       margin-right:22px;
+}
+
+#header-links a:hover {
+       color: white;
+       text-decoration: none;
+}
+
+#header #header-links2 {
+       position:relative;
+       top:-8px;
+       color: white;
+       padding-bottom: 15px;
+}
+
+#header #header-links2 a {
+       color: white;
+}
+
+#header #header-links2 a:hover {
+       text-decoration: underline;
+}
+
+#header #your-acct-login {
+       padding-top:10px;
+}
+
+#gold-links {
+       margin:auto;
+       width:974px;
+       padding-left:0px;
+}
+
+#gold-links-home {
+       margin:auto;
+       width:694px;
+       padding-left:0px;
+}
+
+#util-bar {
+       margin:auto;
+       width:974px;
+       padding-left:0px;
+       height:0px;
+}
+
+#search-wrapper {
+       border-bottom: 1px solid #e9ebf3;
+       padding-bottom: 5px;
+       background: white;
+}
+
+#search_box_wrapper {
+       border:1px solid #e9ebf3;
+       padding: 1px;
+    padding-left: 3px;
+}
+
+#search-wrapper #breadcrumb {
+       margin-top:0px;
+       font-size: 10px;
+       float:left;
+}
+
+#search-wrapper #search-within {
+       margin-top:10px;
+       float:right;
+       position:relative;
+       left:-173px;
+}
+
+#search-wrapper #breadcrumb a {
+       color: black;
+}
+
+#search-wrapper #search_frm label {
+       font-size: 10px;
+}
+
+#search-wrapper #search-box {
+       width:974px;
+       margin:auto;
+       padding-left: 0px;
+}
+
+#utils {
+       float:right;
+       z-index:1;
+       width:150px;
+       height:30px;
+       background:url('/images/utils-corner-left.png') no-repeat left top;
+       padding-left: 3px;
+       color: white;
+       position:relative;
+}
+
+#utils a {
+       color: white;
+       font-size: 10px;
+}
+#adv_search_tabs {
+       height:33px;
+       width:974px;
+       margin:auto;
+}
+
+#adv_search_tabs a {
+       float: left;
+       display: block;
+       height:33px;
+       margin-right:7px;
+}
+
+#adv_search {
+       width:156px;
+       background:url('/images/adv_search_on.gif') no-repeat bottom;
+}
+
+#num_search {
+       width:156px;
+       background:url('/images/num_search_off.gif') no-repeat bottom;
+}
+
+#expert_search {
+       width:156px;
+       background:url('/images/expert_search_off.gif') no-repeat bottom;
+}
+
+#acct_tabs {
+       height:33px;
+       width:974px;
+       margin:auto;
+}
+
+#acct_tabs a {
+       float: left;
+       display: block;
+       height:33px;
+       margin-right:7px;
+}
+
+.acct-tab {
+    background-repeat: no-repeat;
+    background-position: bottom;
+    width:156px;
+}
+
+.acct-main-off {
+       background-image:url('/images/acct_summary_off.gif');
+}
+.acct-main-on {
+       background-image:url('/images/acct_summary_on.gif');
+}
+
+.acct-circs-off {
+       background-image:url('/images/acct_checked_out_off.gif');
+}
+.acct-circs-on {
+       background-image:url('/images/acct_checked_out_on.gif');
+}
+
+.acct-holds-off {
+       background-image:url('/images/acct_holds_off.gif');
+}
+.acct-holds-on {
+       background-image:url('/images/acct_holds_on.gif');
+}
+
+.acct-prefs-off {
+       background-image:url('/images/acct_prefs_off.gif');
+}
+.acct-prefs-on {
+       background-image:url('/images/acct_prefs_on.gif');
+}
+
+.acct-lists-off {
+       background-image:url('/images/acct_lists_off.gif');
+}
+.acct-lists-on {
+       background-image:url('/images/acct_lists_on.gif');
+}
+
+#rdetail_header {
+       font-size:14px;
+       font-weight:bold;
+       color:#074079;
+       padding: 5px 7px 6px 0px;
+       border-bottom: 1px dotted #ccc;
+}
+
+#rdetail_result_count {
+       color: black;
+       font-size: 11px;
+       font-weight: normal;
+}
+
+#rdetail_result_nav {
+       float:right;
+       font-size: 11px;
+       font-weight:normal;
+}
+
+#rdetail_details_table {
+       margin-top: 15px;
+}
+
+#rdetail_title {
+       font-size: 18px;
+}
+
+#rdetail_image { border: none; }
+#rdetail_image_cell {
+       padding-top: 3px;
+       padding-right: 10px;
+}
+
+.rdetail_aux_utils {
+       border-left:1px dotted #ccc;
+       padding-left: 17px;
+       padding-bottom: 6px;
+       padding-right: 70px;
+}
+
+.results_aux_utils {
+       border-left:1px dotted #ccc;
+       padding-left: 17px;
+       padding-bottom: 6px;
+       padding-right: 50px;
+}
+
+#rdetails_status td, #rdetails_status2 td {
+       white-space:nowrap !important;
+       padding: 7px 0px 3px 13px;
+}
+
+#rdetails_status thead td {
+       background-color: #d8d8d8;
+       padding: 13px 0px 13px 13px;
+       font-size: 10px;
+       text-transform: uppercase;
+       font-weight: bold;
+}
+
+#rdetails_status tbody td {
+       padding-left: 13px;;
+}
+
+.rdetail_extras {
+       height: 29px;
+       background: #9ad0f1;
+       padding-top:1px;
+       margin-bottom: 10px;
+       margin-top: 10px;
+       clear:both;
+}
+
+.rdetail_extras_hr {
+       height: 1px;
+       background: #b7def5;
+       margin-left: 1px;
+       margin-right: 1px;
+}
+
+.rdetail_extras_link {
+       padding-top: 4px;
+       padding-left: 12px;
+       font-size: 10px;
+       text-transform: uppercase;
+       font-weight: bold;
+}
+
+.rdetail_extras_lbl {
+       position: relative;
+       top: -4px;
+       left: 7px;
+}
+
+#paginate-homebanner a.toc {
+       display:block;
+       width:20px;
+       height:20px;
+       background:gray;
+       float:left;
+       margin-left:2px;
+       margin-right:2px;
+       margin-top:2px;
+}
+
+#rdetail_extras_expand, #rdetail_extras_collapse, #rdetail_locs_collapse {
+       margin-left: 13px;
+}
+
+#rdetail_locs_expand, #rdetail_locs_collapse {
+       padding-bottom:3px;
+       margin-top:15px;
+       margin-left:13px;
+}
+
+#rdetail_anotes_div .biography {
+       margin:0;
+}
+
+#paginate-homebanner a.selected {
+       border: 2px solid black;
+       margin-top:0px;
+       margin-left:0px;
+       margin-right:0px;
+}
+
+#hp-buttons {
+       margin: auto;
+       margin-top: 6px;
+       width: 694px; /* 974px; */
+}
+
+#hp-welcome {
+       position:absolute;
+       width:295px;
+       height:192px;
+       background: url('/images/banner-bg.png') no-repeat;
+       color: #fff;
+       padding-left: 33px;
+       padding-top: 21px;
+       z-index:9999999999;
+}
+
+#hp-welcome h1 {
+       font-size: 25px;
+       margin-bottom:15px;
+}
+
+#hp-welcome a {
+       color: #fff;
+       text-decoration: underline;
+}
+
+#hp-banner {
+       margin: auto;
+       width: 694px; /* formerly 974px */
+       height: 213px;
+}
+
+#hp-ql-table {
+       margin-left: 2px;
+       padding-top: 3px;
+}
+
+#hp-ql-table a {
+       color: #333;
+       font-weight: bold;
+       font-size: 13px;
+       text-transform: uppercase;
+       text-decoration: none;
+       display: block;
+       width: 144px;
+       height: 25px;
+       padding-top: 9px;
+       padding-left: 15px;
+       background: url('/images/button-bg.png') no-repeat;
+}
+
+#hp-ql-bottom {
+       width: 640px;
+       height: 31px;
+       padding-left: 24px;
+       padding-top: 13px;
+       background: url('/images/hp-links-mid.jpg') repeat-x;
+}
+
+#hp-ql-bottom a {
+       display: inline-block;
+       text-decoration: none;
+       color: white;
+       font-size: 15px;
+       font-weight: bold;
+}
+
+#hp-ql-bottom img {
+    position:relative;
+    top:-1px;
+    left:2px;
+}
+
+.almost-content-wrapper {
+       background: white;
+}
+
+#content-wrapper {
+       background: white;
+       min-height: 260px;
+       border-bottom: 1px solid black;
+}
+
+#main-content-home { width: 694px; margin: auto; padding-left: 17px; }
+#main-content { width: 974px; margin:auto; padding-left: 0px; }
+
+#main-content .login_boxes {
+       border: 1px solid #dedede;
+       background:url('/images/login-bg.jpg') top repeat-x;
+       color: #333;
+}
+
+#main-content .login_boxes h1 {
+       font-weight: normal;
+       font-size: 25px;
+       margin:0;
+}
+
+#main-content .left_brain {
+       padding-left:28px;
+       padding-top:25px;
+}
+
+#main-content .left_brain input[type=text], #main-content .left_brain input[type=password] {
+       width:167px;
+       height:18px;
+       margin:0;
+       padding:0;
+       border:none;
+       background: none;
+       font-size: 15px;
+       color: #666;
+}
+
+#main-content .left_brain .input_bg {
+       padding:10px 10px 0px 13px;
+       background: url('/images/login-box-bg.jpg') no-repeat;
+       width:167px;
+       height:29px;
+}
+
+#home-buttons-inner {
+       width:664px;
+       height:117px;
+       background:#bda964;
+}
+
+#holds_temp_parent td {
+       border-bottom:1px solid #dcdbdb;
+}
+
+#holds_temp_parent input, #holds_temp_parent select {
+       margin:0;
+}
+
+
+
+
+#results_header_bar {
+       background: #929292;
+       border-top:1px solid #8b8b8b;
+}
+
+#results_header_inner {
+       height:32px;
+       width:974px;
+       margin:auto;
+       padding-top:6px;
+}
+
+.results_header_btns {
+       float:left;
+       margin-right: 6px;
+}
+
+.cached_list_div { width: 111px; height: 25px; }
+
+.results_header_div {
+       float: left;
+       width: 0px;
+       height: 25px;
+       border-left: 1px solid #7c7c7c;
+       border-right: 1px solid #9c9c9c;
+       margin: 0px 13px;
+}
+
+.results_header_lbl {
+       font-weight: bold;
+       float: left;
+       font-size: 11px;
+       color: #191919;
+       position: relative;
+       top: 5px;
+       margin-right: 6px;
+}
+
+.results_header_sel {
+    /* width: 88px; */
+       float:left;
+       position: relative;
+       top: 2px;
+       margin:0;
+}
+
+.results_header_nav1 {
+       padding: 5px 7px 6px 0px;
+       border-bottom: 1px dotted #ccc;
+}
+
+.results_header_nav1 .h1 {
+       font-size:14px;
+       font-weight:bold;
+       color:#074079;
+}
+
+.start_end_links_span {
+       font-size: 11px;
+}
+
+.nav_arrow_fix {
+       font-size:8px;
+       position:relative;
+       top:-1px;
+}
+
+#result_table_div {
+       margin-top: 20px;
+}
+
+.result_numbers {
+       font-size: 11px; padding-left:15px; white-space: nowrap; width: 320px;
+}
+
+.result_table_subtable { width: 100%; border-collapse: collapse; border: 0; }
+
+
+
+
+.icon_text {
+       text-transform:capitalize;
+}
+
+.result_table_title_cell {
+       padding-left: 7px;
+}
+
+#myopac_summary_div p {
+       margin:0;
+       margin-bottom: 10px;
+}
+
+#acct_sum_checked_table td {
+       padding-bottom:5px;
+}
+
+#zero_search_hits div { float:left;width:300px;margin-top:20px; }
+
+#zero_search_hits p {
+       margin-top:0;
+}
+
+#zero_hits_term {
+       text-transform: uppercase;
+    font-weight: bold;
+}
+
+#zero_search_hits #spell_check_link {
+       text-transform: uppercase;
+}
+
+#zero_search_hits #zero_hits_suggestions {
+       text-transform: uppercase;
+}
+
+.results_info_table td {
+       padding-right: 10px;
+}
+
+#myopac_holds_main_table {
+       border-collapse: collapse;
+}
+
+#myopac_holds_main_table td {
+       border: 1px solid black;
+       
+}
+
+#myopac_prefs_div .data_grid {
+       border-collapse:collapse;
+}
+
+#myopac_prefs_div .data_grid td {
+       background:#f0f0f0;
+       border-bottom:3px solid white;
+       padding:6px 0px 7px 17px;
+}
+
+.header_middle {
+       height:22px;
+       font-size:14px;
+       font-weight:bold;
+       color:#074079;
+       padding: 0px 7px 0px 0px;
+       border-bottom: 1px dotted #ccc;
+}
+
+.header_middle a {
+       font-size: 12px;
+       font-weight: normal;
+}
+
+.acct_sum_row {
+       padding: 7px 15px;
+       width: 712px;
+       background: #f0f0f0;
+       margin-bottom: 2px;
+       font-size: 10px;
+       font-weight: bold;
+       text-transform: uppercase;
+}
+
+.acct_sum_row a {
+       text-transform: none;
+       font-size: 12px;
+       position:relative;
+       top:-1px;
+}
+
+.acct_sum_row .view_link {
+       font-weight: normal;
+       font-size:12px;
+}
+
+#myopac_sum_fines {
+       float:right;
+       padding: 15px 0px 0px 23px;
+       background: #f0f0f0;
+       width: 177px;
+       height: 166px;
+}
+
+.acct_holds_temp td {
+       text-align: left;
+}
+
+#acct_checked_tabs .align, #acct_holds_tabs .align, #acct_prefs_tabs .align {
+       float:left;
+       /*padding-left:10px;*/
+}
+
+#acct_checked_tabs .selected, #acct_holds_tabs .selected, #acct_prefs_tabs .selected {
+       /*background:url('/images/gray-arrow.png') left 3px no-repeat;*/
+}
+
+#acct_checked_main_header, #acct_holds_main_header, #acct_checked_hist_header, #acct_list_header, #acct_list_header_anon, #temp_list_holds {
+       font-weight:bold;
+       text-transform:uppercase;
+       font-size: 10px;
+}
+
+#acct_checked_main_header td, #acct_holds_main_header td, #acct_checked_hist_header td, #acct_list_header td, #acct_list_header_anon td, #temp_list_holds td {
+       background: #d8d8d8;
+       padding: 8px 0px 7px 0px;
+}
+
+#acct_list_header select, #acct_list_header_anon select {
+       font-weight:normal;
+       text-transform:none;
+}
+
+#acct_holds_activates_table label {
+       font-weight: bold;
+       font-size: 11px;
+       text-transform:uppercase;
+       padding-right: 5px;
+}
+
+.adv_search_font {
+       font-size: 10px;
+}
+
+.search_catalog_lbl {
+       font-size: 14px;
+}
+
+.lbl1 {
+       font-size:14px;
+       font-weight:bold;
+}
+
+.lbl2 {
+       font-size:10px;
+       font-weight:normal;
+       position:relative;
+       top:3px;
+}
+
+#myopac_tabs, #adv_search_parent {
+       background: #929292;
+       border-top:1px solid #8b8b8b;
+       padding-top:5px;
+       margin-bottom:20px;
+}
+
+#adv_search_parent {
+       margin-bottom:0px;
+}
+
+#myopac_loading {
+       width:100%;
+       text-align:center;
+       padding-top:20px;
+       font-size:16px;
+       font-weight:bold;
+}
+
+.chili_link {
+       width:100px !important;
+       text-align: center !important;
+}
+
+.chili_review div.chili_link div {
+       margin: auto;
+}
+
+/* some facet styling */
+.facetClassContainer { margin: 2px; border: 1px solid #CCC; }
+.facetClassLabelContainer { border: 1px solid #CCC; }
+.facetClassLabel { font-weight: bold; text-align: center; }
+.facetFieldContainer {  }
+.facetFieldLabel { padding-left: 2px; margin-top: 5px; margin-bottom: 5px; font-weight: bold; text-align: left; }
+.extraFacetFieldsWrapper { }
+.toggleExtraFacetFieldsButton { float: right; margin: 0px; padding: 0px; }
+.facetFieldLineCount { display: inline-block; border-right: 1px solid #CCC; color: gray; width: 3em; margin-right: 3px }
+.facetField { border-top: 1px solid #CCC; }
+.facetFields { padding-left: 5px; }
+.facetFieldLineValue { overflow: hidden; text-overflow: ellipsis; }
+
+#footer {
+       padding-top:5px;
+       padding-bottom: 10px;
+       color: white;
+       margin: auto;
+       width: 974px;
+       color: #afafaf;
+       font-size: 11px;
+}
+
+#footer a {
+       color: white;
+       color: #afafaf;
+}
+
+.color_4 {
+       text-transform: uppercase;
+       font-weight: bold;
+       font-size: 10px;
+}
+
+.advanced_div { padding-top: 15px; }
+#adv_global_search select { width: 13em; }
+#adv_global_input_table select { width: 7em; }
+.adv_adv_link { font-size: 8pt; color: red; }
+#acct_prefs_header { float: left; }
+#limit_to_available {
+    float: left; position: relative; top: 2px;
+    left: -2px; margin-right: 4px;
+}
+#rdetail_copy_info_table { font-size: 8pt; }
+#rdetail_copy_info_table td { padding: 3px; }
+.search_page_nav_link { cursor: pointer; }
+#opac.result.sort { width: 160px; }
+.renew-summary { font-size: 125%; font-style: italic; margin: 0.5ex 0; }
+.failure-text { margin-left: 4em; font-style: italic; color: #ff0000; }
+.refine-controls { font-size: 125%; padding: 0.5ex 0; }
+#adv_search_refine input[type=text] { border: 1px inset #ccc !important; }
+#adv_search_refine select { border: 1px inset #ccc !important; }
+#adv_search_refine {
+    padding-left: 5em; background-color: #d7d7d7; margin: 2ex 0;
+}
+.row-remover { position: relative; top: 1px; vertical-align: middle; }
+.subtle-button {
+    background-color: #ffffff;
+    color: #003399; text-decoration: none;
+    font-size: 12px;
+    padding: 0; border: 0; margin: 0;
+    vertical-align: middle;
+}
+.subtle-button:hover { text-decoration: underline; cursor: pointer; }
+.no-dec:hover { text-decoration: none; }
+.pending-addr td { background-color: #ffcccc !important; border: 0 !important; }
+
+#account-update-email table { text-align: center; padding: 20px; margin-top: 30px; border-collapse: collapse; }
+#account-update-email table td { padding: 5px 15px 5px 15px; border-bottom: 1px solid #ddd; text-align: left;}
+#account-update-email-error { font-size: 1.5em; padding: 10px; border:1px solid #e9ebf3;}
+
diff --git a/Open-ILS/web/images/KCLS_logo_horiz.gif b/Open-ILS/web/images/KCLS_logo_horiz.gif
new file mode 100644 (file)
index 0000000..8e1d56e
Binary files /dev/null and b/Open-ILS/web/images/KCLS_logo_horiz.gif differ
diff --git a/Open-ILS/web/images/acct-btn-hover.png b/Open-ILS/web/images/acct-btn-hover.png
new file mode 100644 (file)
index 0000000..1e6e20a
Binary files /dev/null and b/Open-ILS/web/images/acct-btn-hover.png differ
diff --git a/Open-ILS/web/images/acct-btn.png b/Open-ILS/web/images/acct-btn.png
new file mode 100644 (file)
index 0000000..c9b92cd
Binary files /dev/null and b/Open-ILS/web/images/acct-btn.png differ
diff --git a/Open-ILS/web/images/acct_checked_out_off.gif b/Open-ILS/web/images/acct_checked_out_off.gif
new file mode 100644 (file)
index 0000000..dcfcfcb
Binary files /dev/null and b/Open-ILS/web/images/acct_checked_out_off.gif differ
diff --git a/Open-ILS/web/images/acct_checked_out_on.gif b/Open-ILS/web/images/acct_checked_out_on.gif
new file mode 100644 (file)
index 0000000..f364d38
Binary files /dev/null and b/Open-ILS/web/images/acct_checked_out_on.gif differ
diff --git a/Open-ILS/web/images/acct_favs_off.gif b/Open-ILS/web/images/acct_favs_off.gif
new file mode 100644 (file)
index 0000000..5ffc024
Binary files /dev/null and b/Open-ILS/web/images/acct_favs_off.gif differ
diff --git a/Open-ILS/web/images/acct_favs_on.gif b/Open-ILS/web/images/acct_favs_on.gif
new file mode 100644 (file)
index 0000000..f96342a
Binary files /dev/null and b/Open-ILS/web/images/acct_favs_on.gif differ
diff --git a/Open-ILS/web/images/acct_fines_off.jpg b/Open-ILS/web/images/acct_fines_off.jpg
new file mode 100644 (file)
index 0000000..b73b61d
Binary files /dev/null and b/Open-ILS/web/images/acct_fines_off.jpg differ
diff --git a/Open-ILS/web/images/acct_fines_on.jpg b/Open-ILS/web/images/acct_fines_on.jpg
new file mode 100644 (file)
index 0000000..4ea7e89
Binary files /dev/null and b/Open-ILS/web/images/acct_fines_on.jpg differ
diff --git a/Open-ILS/web/images/acct_holds_off.gif b/Open-ILS/web/images/acct_holds_off.gif
new file mode 100644 (file)
index 0000000..6179396
Binary files /dev/null and b/Open-ILS/web/images/acct_holds_off.gif differ
diff --git a/Open-ILS/web/images/acct_holds_on.gif b/Open-ILS/web/images/acct_holds_on.gif
new file mode 100644 (file)
index 0000000..d1c75bb
Binary files /dev/null and b/Open-ILS/web/images/acct_holds_on.gif differ
diff --git a/Open-ILS/web/images/acct_lists_off.gif b/Open-ILS/web/images/acct_lists_off.gif
new file mode 100644 (file)
index 0000000..9a5b2a2
Binary files /dev/null and b/Open-ILS/web/images/acct_lists_off.gif differ
diff --git a/Open-ILS/web/images/acct_lists_on.gif b/Open-ILS/web/images/acct_lists_on.gif
new file mode 100644 (file)
index 0000000..668b0c9
Binary files /dev/null and b/Open-ILS/web/images/acct_lists_on.gif differ
diff --git a/Open-ILS/web/images/acct_payments_off.jpg b/Open-ILS/web/images/acct_payments_off.jpg
new file mode 100644 (file)
index 0000000..c8a50f5
Binary files /dev/null and b/Open-ILS/web/images/acct_payments_off.jpg differ
diff --git a/Open-ILS/web/images/acct_payments_on.jpg b/Open-ILS/web/images/acct_payments_on.jpg
new file mode 100644 (file)
index 0000000..c571398
Binary files /dev/null and b/Open-ILS/web/images/acct_payments_on.jpg differ
diff --git a/Open-ILS/web/images/acct_prefs_off.gif b/Open-ILS/web/images/acct_prefs_off.gif
new file mode 100644 (file)
index 0000000..c357add
Binary files /dev/null and b/Open-ILS/web/images/acct_prefs_off.gif differ
diff --git a/Open-ILS/web/images/acct_prefs_on.gif b/Open-ILS/web/images/acct_prefs_on.gif
new file mode 100644 (file)
index 0000000..67d1f47
Binary files /dev/null and b/Open-ILS/web/images/acct_prefs_on.gif differ
diff --git a/Open-ILS/web/images/acct_sum_fines_bl.png b/Open-ILS/web/images/acct_sum_fines_bl.png
new file mode 100644 (file)
index 0000000..d750579
Binary files /dev/null and b/Open-ILS/web/images/acct_sum_fines_bl.png differ
diff --git a/Open-ILS/web/images/acct_sum_fines_br.png b/Open-ILS/web/images/acct_sum_fines_br.png
new file mode 100644 (file)
index 0000000..8aa81f0
Binary files /dev/null and b/Open-ILS/web/images/acct_sum_fines_br.png differ
diff --git a/Open-ILS/web/images/acct_sum_fines_tl.png b/Open-ILS/web/images/acct_sum_fines_tl.png
new file mode 100644 (file)
index 0000000..17051c9
Binary files /dev/null and b/Open-ILS/web/images/acct_sum_fines_tl.png differ
diff --git a/Open-ILS/web/images/acct_sum_fines_tr.png b/Open-ILS/web/images/acct_sum_fines_tr.png
new file mode 100644 (file)
index 0000000..fb9dac3
Binary files /dev/null and b/Open-ILS/web/images/acct_sum_fines_tr.png differ
diff --git a/Open-ILS/web/images/acct_summary_off.gif b/Open-ILS/web/images/acct_summary_off.gif
new file mode 100644 (file)
index 0000000..63456c1
Binary files /dev/null and b/Open-ILS/web/images/acct_summary_off.gif differ
diff --git a/Open-ILS/web/images/acct_summary_on.gif b/Open-ILS/web/images/acct_summary_on.gif
new file mode 100644 (file)
index 0000000..99d4990
Binary files /dev/null and b/Open-ILS/web/images/acct_summary_on.gif differ
diff --git a/Open-ILS/web/images/add_mylist.gif b/Open-ILS/web/images/add_mylist.gif
new file mode 100644 (file)
index 0000000..a30b32d
Binary files /dev/null and b/Open-ILS/web/images/add_mylist.gif differ
diff --git a/Open-ILS/web/images/add_mylist_sel.gif b/Open-ILS/web/images/add_mylist_sel.gif
new file mode 100644 (file)
index 0000000..0448d21
Binary files /dev/null and b/Open-ILS/web/images/add_mylist_sel.gif differ
diff --git a/Open-ILS/web/images/add_mylist_sel.kcls.gif b/Open-ILS/web/images/add_mylist_sel.kcls.gif
new file mode 100644 (file)
index 0000000..45bd8b6
Binary files /dev/null and b/Open-ILS/web/images/add_mylist_sel.kcls.gif differ
diff --git a/Open-ILS/web/images/add_search_row_btn.gif b/Open-ILS/web/images/add_search_row_btn.gif
new file mode 100644 (file)
index 0000000..a48e68c
Binary files /dev/null and b/Open-ILS/web/images/add_search_row_btn.gif differ
diff --git a/Open-ILS/web/images/adv_row_close_btn.png b/Open-ILS/web/images/adv_row_close_btn.png
new file mode 100644 (file)
index 0000000..edccf37
Binary files /dev/null and b/Open-ILS/web/images/adv_row_close_btn.png differ
diff --git a/Open-ILS/web/images/adv_search.png b/Open-ILS/web/images/adv_search.png
new file mode 100644 (file)
index 0000000..79fb08a
Binary files /dev/null and b/Open-ILS/web/images/adv_search.png differ
diff --git a/Open-ILS/web/images/adv_search_hover.png b/Open-ILS/web/images/adv_search_hover.png
new file mode 100644 (file)
index 0000000..0cb3fe1
Binary files /dev/null and b/Open-ILS/web/images/adv_search_hover.png differ
diff --git a/Open-ILS/web/images/adv_search_off.gif b/Open-ILS/web/images/adv_search_off.gif
new file mode 100644 (file)
index 0000000..a129b93
Binary files /dev/null and b/Open-ILS/web/images/adv_search_off.gif differ
diff --git a/Open-ILS/web/images/adv_search_on.gif b/Open-ILS/web/images/adv_search_on.gif
new file mode 100644 (file)
index 0000000..d0faa4f
Binary files /dev/null and b/Open-ILS/web/images/adv_search_on.gif differ
diff --git a/Open-ILS/web/images/another_search.png b/Open-ILS/web/images/another_search.png
new file mode 100644 (file)
index 0000000..4bcd214
Binary files /dev/null and b/Open-ILS/web/images/another_search.png differ
diff --git a/Open-ILS/web/images/another_search_hover.png b/Open-ILS/web/images/another_search_hover.png
new file mode 100644 (file)
index 0000000..08efaf5
Binary files /dev/null and b/Open-ILS/web/images/another_search_hover.png differ
diff --git a/Open-ILS/web/images/arrow-down.gif b/Open-ILS/web/images/arrow-down.gif
new file mode 100644 (file)
index 0000000..ebf64c4
Binary files /dev/null and b/Open-ILS/web/images/arrow-down.gif differ
diff --git a/Open-ILS/web/images/arrow-right.gif b/Open-ILS/web/images/arrow-right.gif
new file mode 100644 (file)
index 0000000..6c82655
Binary files /dev/null and b/Open-ILS/web/images/arrow-right.gif differ
diff --git a/Open-ILS/web/images/arrow-right.png b/Open-ILS/web/images/arrow-right.png
new file mode 100644 (file)
index 0000000..232a5e4
Binary files /dev/null and b/Open-ILS/web/images/arrow-right.png differ
diff --git a/Open-ILS/web/images/asknow_available.gif b/Open-ILS/web/images/asknow_available.gif
new file mode 100644 (file)
index 0000000..326c8d1
Binary files /dev/null and b/Open-ILS/web/images/asknow_available.gif differ
diff --git a/Open-ILS/web/images/banner-bg.png b/Open-ILS/web/images/banner-bg.png
new file mode 100644 (file)
index 0000000..6d990c5
Binary files /dev/null and b/Open-ILS/web/images/banner-bg.png differ
diff --git a/Open-ILS/web/images/banner1.jpg b/Open-ILS/web/images/banner1.jpg
new file mode 100644 (file)
index 0000000..28eaafc
Binary files /dev/null and b/Open-ILS/web/images/banner1.jpg differ
diff --git a/Open-ILS/web/images/btnCancel.png b/Open-ILS/web/images/btnCancel.png
new file mode 100644 (file)
index 0000000..4cfacaf
Binary files /dev/null and b/Open-ILS/web/images/btnCancel.png differ
diff --git a/Open-ILS/web/images/btnSubmit.png b/Open-ILS/web/images/btnSubmit.png
new file mode 100644 (file)
index 0000000..7a67408
Binary files /dev/null and b/Open-ILS/web/images/btnSubmit.png differ
diff --git a/Open-ILS/web/images/button-bg.png b/Open-ILS/web/images/button-bg.png
new file mode 100644 (file)
index 0000000..38390aa
Binary files /dev/null and b/Open-ILS/web/images/button-bg.png differ
diff --git a/Open-ILS/web/images/cancel_btn.gif b/Open-ILS/web/images/cancel_btn.gif
new file mode 100644 (file)
index 0000000..1cebf59
Binary files /dev/null and b/Open-ILS/web/images/cancel_btn.gif differ
diff --git a/Open-ILS/web/images/cd-small.png b/Open-ILS/web/images/cd-small.png
new file mode 100644 (file)
index 0000000..d2f8fb4
Binary files /dev/null and b/Open-ILS/web/images/cd-small.png differ
diff --git a/Open-ILS/web/images/clipboard.png b/Open-ILS/web/images/clipboard.png
new file mode 100644 (file)
index 0000000..b4bf071
Binary files /dev/null and b/Open-ILS/web/images/clipboard.png differ
diff --git a/Open-ILS/web/images/dash-corner-left1.png b/Open-ILS/web/images/dash-corner-left1.png
new file mode 100644 (file)
index 0000000..9559e8b
Binary files /dev/null and b/Open-ILS/web/images/dash-corner-left1.png differ
diff --git a/Open-ILS/web/images/dash-corner-left2.png b/Open-ILS/web/images/dash-corner-left2.png
new file mode 100644 (file)
index 0000000..5bc8112
Binary files /dev/null and b/Open-ILS/web/images/dash-corner-left2.png differ
diff --git a/Open-ILS/web/images/dash-corner-mid1.png b/Open-ILS/web/images/dash-corner-mid1.png
new file mode 100644 (file)
index 0000000..546b8a8
Binary files /dev/null and b/Open-ILS/web/images/dash-corner-mid1.png differ
diff --git a/Open-ILS/web/images/dash-corner-mid2.png b/Open-ILS/web/images/dash-corner-mid2.png
new file mode 100644 (file)
index 0000000..15af112
Binary files /dev/null and b/Open-ILS/web/images/dash-corner-mid2.png differ
diff --git a/Open-ILS/web/images/dash-corner-right1.png b/Open-ILS/web/images/dash-corner-right1.png
new file mode 100644 (file)
index 0000000..061afc9
Binary files /dev/null and b/Open-ILS/web/images/dash-corner-right1.png differ
diff --git a/Open-ILS/web/images/dash-corner-right2.png b/Open-ILS/web/images/dash-corner-right2.png
new file mode 100644 (file)
index 0000000..8663e0c
Binary files /dev/null and b/Open-ILS/web/images/dash-corner-right2.png differ
diff --git a/Open-ILS/web/images/dash-divider.jpg b/Open-ILS/web/images/dash-divider.jpg
new file mode 100644 (file)
index 0000000..19dda7d
Binary files /dev/null and b/Open-ILS/web/images/dash-divider.jpg differ
diff --git a/Open-ILS/web/images/dropdown-hover.gif b/Open-ILS/web/images/dropdown-hover.gif
new file mode 100644 (file)
index 0000000..1ac62ae
Binary files /dev/null and b/Open-ILS/web/images/dropdown-hover.gif differ
diff --git a/Open-ILS/web/images/dropdown.gif b/Open-ILS/web/images/dropdown.gif
new file mode 100644 (file)
index 0000000..3aab6fe
Binary files /dev/null and b/Open-ILS/web/images/dropdown.gif differ
diff --git a/Open-ILS/web/images/expert_search_off.gif b/Open-ILS/web/images/expert_search_off.gif
new file mode 100644 (file)
index 0000000..96b4f51
Binary files /dev/null and b/Open-ILS/web/images/expert_search_off.gif differ
diff --git a/Open-ILS/web/images/expert_search_on.gif b/Open-ILS/web/images/expert_search_on.gif
new file mode 100644 (file)
index 0000000..6a41861
Binary files /dev/null and b/Open-ILS/web/images/expert_search_on.gif differ
diff --git a/Open-ILS/web/images/faqs-btn.png b/Open-ILS/web/images/faqs-btn.png
new file mode 100644 (file)
index 0000000..38134ec
Binary files /dev/null and b/Open-ILS/web/images/faqs-btn.png differ
diff --git a/Open-ILS/web/images/go-btn-hover.png b/Open-ILS/web/images/go-btn-hover.png
new file mode 100644 (file)
index 0000000..9b878b2
Binary files /dev/null and b/Open-ILS/web/images/go-btn-hover.png differ
diff --git a/Open-ILS/web/images/go-btn.png b/Open-ILS/web/images/go-btn.png
new file mode 100644 (file)
index 0000000..24091c9
Binary files /dev/null and b/Open-ILS/web/images/go-btn.png differ
diff --git a/Open-ILS/web/images/go_but_long.gif b/Open-ILS/web/images/go_but_long.gif
new file mode 100644 (file)
index 0000000..79d2f9a
Binary files /dev/null and b/Open-ILS/web/images/go_but_long.gif differ
diff --git a/Open-ILS/web/images/golive.jpg b/Open-ILS/web/images/golive.jpg
new file mode 100644 (file)
index 0000000..8b34912
Binary files /dev/null and b/Open-ILS/web/images/golive.jpg differ
diff --git a/Open-ILS/web/images/gray-arrow.png b/Open-ILS/web/images/gray-arrow.png
new file mode 100644 (file)
index 0000000..bf56b6e
Binary files /dev/null and b/Open-ILS/web/images/gray-arrow.png differ
diff --git a/Open-ILS/web/images/green_check.png b/Open-ILS/web/images/green_check.png
new file mode 100644 (file)
index 0000000..9738bd8
Binary files /dev/null and b/Open-ILS/web/images/green_check.png differ
diff --git a/Open-ILS/web/images/header_left.gif b/Open-ILS/web/images/header_left.gif
new file mode 100644 (file)
index 0000000..9543795
Binary files /dev/null and b/Open-ILS/web/images/header_left.gif differ
diff --git a/Open-ILS/web/images/header_right.gif b/Open-ILS/web/images/header_right.gif
new file mode 100644 (file)
index 0000000..f00ff76
Binary files /dev/null and b/Open-ILS/web/images/header_right.gif differ
diff --git a/Open-ILS/web/images/hp-links-left.jpg b/Open-ILS/web/images/hp-links-left.jpg
new file mode 100644 (file)
index 0000000..0b8c9cf
Binary files /dev/null and b/Open-ILS/web/images/hp-links-left.jpg differ
diff --git a/Open-ILS/web/images/hp-links-mid.jpg b/Open-ILS/web/images/hp-links-mid.jpg
new file mode 100644 (file)
index 0000000..c9cdabf
Binary files /dev/null and b/Open-ILS/web/images/hp-links-mid.jpg differ
diff --git a/Open-ILS/web/images/hp-links-right.jpg b/Open-ILS/web/images/hp-links-right.jpg
new file mode 100644 (file)
index 0000000..63812f9
Binary files /dev/null and b/Open-ILS/web/images/hp-links-right.jpg differ
diff --git a/Open-ILS/web/images/locations.jpg b/Open-ILS/web/images/locations.jpg
new file mode 100644 (file)
index 0000000..56e7785
Binary files /dev/null and b/Open-ILS/web/images/locations.jpg differ
diff --git a/Open-ILS/web/images/login-bg.jpg b/Open-ILS/web/images/login-bg.jpg
new file mode 100644 (file)
index 0000000..46fc85f
Binary files /dev/null and b/Open-ILS/web/images/login-bg.jpg differ
diff --git a/Open-ILS/web/images/login-bg2.jpg b/Open-ILS/web/images/login-bg2.jpg
new file mode 100644 (file)
index 0000000..2c38853
Binary files /dev/null and b/Open-ILS/web/images/login-bg2.jpg differ
diff --git a/Open-ILS/web/images/login-box-bg.jpg b/Open-ILS/web/images/login-box-bg.jpg
new file mode 100644 (file)
index 0000000..caf036d
Binary files /dev/null and b/Open-ILS/web/images/login-box-bg.jpg differ
diff --git a/Open-ILS/web/images/login-btn-hover.png b/Open-ILS/web/images/login-btn-hover.png
new file mode 100644 (file)
index 0000000..442f33f
Binary files /dev/null and b/Open-ILS/web/images/login-btn-hover.png differ
diff --git a/Open-ILS/web/images/login-btn.gif b/Open-ILS/web/images/login-btn.gif
new file mode 100644 (file)
index 0000000..69d6a56
Binary files /dev/null and b/Open-ILS/web/images/login-btn.gif differ
diff --git a/Open-ILS/web/images/login-btn.png b/Open-ILS/web/images/login-btn.png
new file mode 100644 (file)
index 0000000..5548b99
Binary files /dev/null and b/Open-ILS/web/images/login-btn.png differ
diff --git a/Open-ILS/web/images/login-btn2.png b/Open-ILS/web/images/login-btn2.png
new file mode 100644 (file)
index 0000000..ff4af14
Binary files /dev/null and b/Open-ILS/web/images/login-btn2.png differ
diff --git a/Open-ILS/web/images/logout-btn-hover.png b/Open-ILS/web/images/logout-btn-hover.png
new file mode 100644 (file)
index 0000000..411fc01
Binary files /dev/null and b/Open-ILS/web/images/logout-btn-hover.png differ
diff --git a/Open-ILS/web/images/logout-btn.png b/Open-ILS/web/images/logout-btn.png
new file mode 100644 (file)
index 0000000..bd31a47
Binary files /dev/null and b/Open-ILS/web/images/logout-btn.png differ
diff --git a/Open-ILS/web/images/media_3dobject.jpg b/Open-ILS/web/images/media_3dobject.jpg
new file mode 100644 (file)
index 0000000..21ee11d
Binary files /dev/null and b/Open-ILS/web/images/media_3dobject.jpg differ
diff --git a/Open-ILS/web/images/media_book.jpg b/Open-ILS/web/images/media_book.jpg
new file mode 100644 (file)
index 0000000..d928e6e
Binary files /dev/null and b/Open-ILS/web/images/media_book.jpg differ
diff --git a/Open-ILS/web/images/media_bookoncassette.jpg b/Open-ILS/web/images/media_bookoncassette.jpg
new file mode 100644 (file)
index 0000000..acc469e
Binary files /dev/null and b/Open-ILS/web/images/media_bookoncassette.jpg differ
diff --git a/Open-ILS/web/images/media_bookoncassettecd.jpg b/Open-ILS/web/images/media_bookoncassettecd.jpg
new file mode 100644 (file)
index 0000000..e288689
Binary files /dev/null and b/Open-ILS/web/images/media_bookoncassettecd.jpg differ
diff --git a/Open-ILS/web/images/media_bookoncd.jpg b/Open-ILS/web/images/media_bookoncd.jpg
new file mode 100644 (file)
index 0000000..9e49aed
Binary files /dev/null and b/Open-ILS/web/images/media_bookoncd.jpg differ
diff --git a/Open-ILS/web/images/media_cassettewithbook.jpg b/Open-ILS/web/images/media_cassettewithbook.jpg
new file mode 100644 (file)
index 0000000..c434af6
Binary files /dev/null and b/Open-ILS/web/images/media_cassettewithbook.jpg differ
diff --git a/Open-ILS/web/images/media_cdrom.jpg b/Open-ILS/web/images/media_cdrom.jpg
new file mode 100644 (file)
index 0000000..59f9702
Binary files /dev/null and b/Open-ILS/web/images/media_cdrom.jpg differ
diff --git a/Open-ILS/web/images/media_cdwithbook.jpg b/Open-ILS/web/images/media_cdwithbook.jpg
new file mode 100644 (file)
index 0000000..b1828d8
Binary files /dev/null and b/Open-ILS/web/images/media_cdwithbook.jpg differ
diff --git a/Open-ILS/web/images/media_downloadebook.jpg b/Open-ILS/web/images/media_downloadebook.jpg
new file mode 100644 (file)
index 0000000..ce97463
Binary files /dev/null and b/Open-ILS/web/images/media_downloadebook.jpg differ
diff --git a/Open-ILS/web/images/media_downloadmusic.jpg b/Open-ILS/web/images/media_downloadmusic.jpg
new file mode 100644 (file)
index 0000000..953b7e7
Binary files /dev/null and b/Open-ILS/web/images/media_downloadmusic.jpg differ
diff --git a/Open-ILS/web/images/media_downloadvideo.jpg b/Open-ILS/web/images/media_downloadvideo.jpg
new file mode 100644 (file)
index 0000000..e3abfc3
Binary files /dev/null and b/Open-ILS/web/images/media_downloadvideo.jpg differ
diff --git a/Open-ILS/web/images/media_dvd.jpg b/Open-ILS/web/images/media_dvd.jpg
new file mode 100644 (file)
index 0000000..905f623
Binary files /dev/null and b/Open-ILS/web/images/media_dvd.jpg differ
diff --git a/Open-ILS/web/images/media_eaudio.jpg b/Open-ILS/web/images/media_eaudio.jpg
new file mode 100644 (file)
index 0000000..0d810ba
Binary files /dev/null and b/Open-ILS/web/images/media_eaudio.jpg differ
diff --git a/Open-ILS/web/images/media_ebooktext.jpg b/Open-ILS/web/images/media_ebooktext.jpg
new file mode 100644 (file)
index 0000000..c45f944
Binary files /dev/null and b/Open-ILS/web/images/media_ebooktext.jpg differ
diff --git a/Open-ILS/web/images/media_equipment.jpg b/Open-ILS/web/images/media_equipment.jpg
new file mode 100644 (file)
index 0000000..47b8377
Binary files /dev/null and b/Open-ILS/web/images/media_equipment.jpg differ
diff --git a/Open-ILS/web/images/media_films.jpg b/Open-ILS/web/images/media_films.jpg
new file mode 100644 (file)
index 0000000..99b74a0
Binary files /dev/null and b/Open-ILS/web/images/media_films.jpg differ
diff --git a/Open-ILS/web/images/media_games.jpg b/Open-ILS/web/images/media_games.jpg
new file mode 100644 (file)
index 0000000..24d50ae
Binary files /dev/null and b/Open-ILS/web/images/media_games.jpg differ
diff --git a/Open-ILS/web/images/media_kit.jpg b/Open-ILS/web/images/media_kit.jpg
new file mode 100644 (file)
index 0000000..ea50e56
Binary files /dev/null and b/Open-ILS/web/images/media_kit.jpg differ
diff --git a/Open-ILS/web/images/media_language.jpg b/Open-ILS/web/images/media_language.jpg
new file mode 100644 (file)
index 0000000..0d86b5b
Binary files /dev/null and b/Open-ILS/web/images/media_language.jpg differ
diff --git a/Open-ILS/web/images/media_largeprint.jpg b/Open-ILS/web/images/media_largeprint.jpg
new file mode 100644 (file)
index 0000000..bd8b0a4
Binary files /dev/null and b/Open-ILS/web/images/media_largeprint.jpg differ
diff --git a/Open-ILS/web/images/media_magazines.jpg b/Open-ILS/web/images/media_magazines.jpg
new file mode 100644 (file)
index 0000000..e8bb737
Binary files /dev/null and b/Open-ILS/web/images/media_magazines.jpg differ
diff --git a/Open-ILS/web/images/media_map.jpg b/Open-ILS/web/images/media_map.jpg
new file mode 100644 (file)
index 0000000..9236724
Binary files /dev/null and b/Open-ILS/web/images/media_map.jpg differ
diff --git a/Open-ILS/web/images/media_microform.jpg b/Open-ILS/web/images/media_microform.jpg
new file mode 100644 (file)
index 0000000..7e7e0dc
Binary files /dev/null and b/Open-ILS/web/images/media_microform.jpg differ
diff --git a/Open-ILS/web/images/media_musiccassete.jpg b/Open-ILS/web/images/media_musiccassete.jpg
new file mode 100644 (file)
index 0000000..7d9a779
Binary files /dev/null and b/Open-ILS/web/images/media_musiccassete.jpg differ
diff --git a/Open-ILS/web/images/media_musiccassette.jpg b/Open-ILS/web/images/media_musiccassette.jpg
new file mode 100644 (file)
index 0000000..c4a673f
Binary files /dev/null and b/Open-ILS/web/images/media_musiccassette.jpg differ
diff --git a/Open-ILS/web/images/media_musiccd.jpg b/Open-ILS/web/images/media_musiccd.jpg
new file mode 100644 (file)
index 0000000..f82eaed
Binary files /dev/null and b/Open-ILS/web/images/media_musiccd.jpg differ
diff --git a/Open-ILS/web/images/media_musicrecord.jpg b/Open-ILS/web/images/media_musicrecord.jpg
new file mode 100644 (file)
index 0000000..4731692
Binary files /dev/null and b/Open-ILS/web/images/media_musicrecord.jpg differ
diff --git a/Open-ILS/web/images/media_newspaper.jpg b/Open-ILS/web/images/media_newspaper.jpg
new file mode 100644 (file)
index 0000000..8a7b769
Binary files /dev/null and b/Open-ILS/web/images/media_newspaper.jpg differ
diff --git a/Open-ILS/web/images/media_online.jpg b/Open-ILS/web/images/media_online.jpg
new file mode 100644 (file)
index 0000000..2f9cfcc
Binary files /dev/null and b/Open-ILS/web/images/media_online.jpg differ
diff --git a/Open-ILS/web/images/media_onlinejournal.jpg b/Open-ILS/web/images/media_onlinejournal.jpg
new file mode 100644 (file)
index 0000000..3528f1c
Binary files /dev/null and b/Open-ILS/web/images/media_onlinejournal.jpg differ
diff --git a/Open-ILS/web/images/media_podcasts.jpg b/Open-ILS/web/images/media_podcasts.jpg
new file mode 100644 (file)
index 0000000..c65727c
Binary files /dev/null and b/Open-ILS/web/images/media_podcasts.jpg differ
diff --git a/Open-ILS/web/images/media_printedmusic.jpg b/Open-ILS/web/images/media_printedmusic.jpg
new file mode 100644 (file)
index 0000000..2379dbd
Binary files /dev/null and b/Open-ILS/web/images/media_printedmusic.jpg differ
diff --git a/Open-ILS/web/images/media_projectedmedia.jpg b/Open-ILS/web/images/media_projectedmedia.jpg
new file mode 100644 (file)
index 0000000..99b74a0
Binary files /dev/null and b/Open-ILS/web/images/media_projectedmedia.jpg differ
diff --git a/Open-ILS/web/images/media_sheetmusic.jpg b/Open-ILS/web/images/media_sheetmusic.jpg
new file mode 100644 (file)
index 0000000..9207268
Binary files /dev/null and b/Open-ILS/web/images/media_sheetmusic.jpg differ
diff --git a/Open-ILS/web/images/media_slide.jpg b/Open-ILS/web/images/media_slide.jpg
new file mode 100644 (file)
index 0000000..62aca57
Binary files /dev/null and b/Open-ILS/web/images/media_slide.jpg differ
diff --git a/Open-ILS/web/images/media_software.jpg b/Open-ILS/web/images/media_software.jpg
new file mode 100644 (file)
index 0000000..090cee2
Binary files /dev/null and b/Open-ILS/web/images/media_software.jpg differ
diff --git a/Open-ILS/web/images/media_streamingaudio.jpg b/Open-ILS/web/images/media_streamingaudio.jpg
new file mode 100644 (file)
index 0000000..3efafe8
Binary files /dev/null and b/Open-ILS/web/images/media_streamingaudio.jpg differ
diff --git a/Open-ILS/web/images/media_streamingvideo.jpg b/Open-ILS/web/images/media_streamingvideo.jpg
new file mode 100644 (file)
index 0000000..ab9bf9c
Binary files /dev/null and b/Open-ILS/web/images/media_streamingvideo.jpg differ
diff --git a/Open-ILS/web/images/media_vhs.jpg b/Open-ILS/web/images/media_vhs.jpg
new file mode 100644 (file)
index 0000000..228d156
Binary files /dev/null and b/Open-ILS/web/images/media_vhs.jpg differ
diff --git a/Open-ILS/web/images/num_search_off.gif b/Open-ILS/web/images/num_search_off.gif
new file mode 100644 (file)
index 0000000..1062802
Binary files /dev/null and b/Open-ILS/web/images/num_search_off.gif differ
diff --git a/Open-ILS/web/images/num_search_on.gif b/Open-ILS/web/images/num_search_on.gif
new file mode 100644 (file)
index 0000000..f7d7829
Binary files /dev/null and b/Open-ILS/web/images/num_search_on.gif differ
diff --git a/Open-ILS/web/images/one_land.gif b/Open-ILS/web/images/one_land.gif
new file mode 100644 (file)
index 0000000..082b996
Binary files /dev/null and b/Open-ILS/web/images/one_land.gif differ
diff --git a/Open-ILS/web/images/pay-fines-btn-hover.png b/Open-ILS/web/images/pay-fines-btn-hover.png
new file mode 100644 (file)
index 0000000..b7708da
Binary files /dev/null and b/Open-ILS/web/images/pay-fines-btn-hover.png differ
diff --git a/Open-ILS/web/images/pay-fines-btn.png b/Open-ILS/web/images/pay-fines-btn.png
new file mode 100644 (file)
index 0000000..356433b
Binary files /dev/null and b/Open-ILS/web/images/pay-fines-btn.png differ
diff --git a/Open-ILS/web/images/pay_fines_btn.gif b/Open-ILS/web/images/pay_fines_btn.gif
new file mode 100644 (file)
index 0000000..eb4816f
Binary files /dev/null and b/Open-ILS/web/images/pay_fines_btn.gif differ
diff --git a/Open-ILS/web/images/place_hold.gif b/Open-ILS/web/images/place_hold.gif
new file mode 100644 (file)
index 0000000..3f72215
Binary files /dev/null and b/Open-ILS/web/images/place_hold.gif differ
diff --git a/Open-ILS/web/images/plus_sign.png b/Open-ILS/web/images/plus_sign.png
new file mode 100644 (file)
index 0000000..a17d58a
Binary files /dev/null and b/Open-ILS/web/images/plus_sign.png differ
diff --git a/Open-ILS/web/images/projectedmedia.jpg b/Open-ILS/web/images/projectedmedia.jpg
new file mode 100644 (file)
index 0000000..ba0e6d2
Binary files /dev/null and b/Open-ILS/web/images/projectedmedia.jpg differ
diff --git a/Open-ILS/web/images/question-mark.png b/Open-ILS/web/images/question-mark.png
new file mode 100644 (file)
index 0000000..b5f0f87
Binary files /dev/null and b/Open-ILS/web/images/question-mark.png differ
diff --git a/Open-ILS/web/images/questions.png b/Open-ILS/web/images/questions.png
new file mode 100644 (file)
index 0000000..9be69b2
Binary files /dev/null and b/Open-ILS/web/images/questions.png differ
diff --git a/Open-ILS/web/images/rdetail_arrow.png b/Open-ILS/web/images/rdetail_arrow.png
new file mode 100644 (file)
index 0000000..e464bf2
Binary files /dev/null and b/Open-ILS/web/images/rdetail_arrow.png differ
diff --git a/Open-ILS/web/images/reset_form_btn.gif b/Open-ILS/web/images/reset_form_btn.gif
new file mode 100644 (file)
index 0000000..6b70964
Binary files /dev/null and b/Open-ILS/web/images/reset_form_btn.gif differ
diff --git a/Open-ILS/web/images/reviews.gif b/Open-ILS/web/images/reviews.gif
new file mode 100644 (file)
index 0000000..b78fa25
Binary files /dev/null and b/Open-ILS/web/images/reviews.gif differ
diff --git a/Open-ILS/web/images/save-btn.png b/Open-ILS/web/images/save-btn.png
new file mode 100644 (file)
index 0000000..4565850
Binary files /dev/null and b/Open-ILS/web/images/save-btn.png differ
diff --git a/Open-ILS/web/images/save_btn.gif b/Open-ILS/web/images/save_btn.gif
new file mode 100644 (file)
index 0000000..f87282a
Binary files /dev/null and b/Open-ILS/web/images/save_btn.gif differ
diff --git a/Open-ILS/web/images/search_btn.gif b/Open-ILS/web/images/search_btn.gif
new file mode 100644 (file)
index 0000000..f2fdc9b
Binary files /dev/null and b/Open-ILS/web/images/search_btn.gif differ
diff --git a/Open-ILS/web/images/starz.png b/Open-ILS/web/images/starz.png
new file mode 100644 (file)
index 0000000..4a79dd4
Binary files /dev/null and b/Open-ILS/web/images/starz.png differ
diff --git a/Open-ILS/web/images/sub_checked_hist_off.jpg b/Open-ILS/web/images/sub_checked_hist_off.jpg
new file mode 100644 (file)
index 0000000..7fda1c3
Binary files /dev/null and b/Open-ILS/web/images/sub_checked_hist_off.jpg differ
diff --git a/Open-ILS/web/images/sub_checked_hist_on.jpg b/Open-ILS/web/images/sub_checked_hist_on.jpg
new file mode 100644 (file)
index 0000000..703aac1
Binary files /dev/null and b/Open-ILS/web/images/sub_checked_hist_on.jpg differ
diff --git a/Open-ILS/web/images/sub_checked_out_off.jpg b/Open-ILS/web/images/sub_checked_out_off.jpg
new file mode 100644 (file)
index 0000000..0573fbd
Binary files /dev/null and b/Open-ILS/web/images/sub_checked_out_off.jpg differ
diff --git a/Open-ILS/web/images/sub_checked_out_on.jpg b/Open-ILS/web/images/sub_checked_out_on.jpg
new file mode 100644 (file)
index 0000000..97bb178
Binary files /dev/null and b/Open-ILS/web/images/sub_checked_out_on.jpg differ
diff --git a/Open-ILS/web/images/sub_holds_hist_off.jpg b/Open-ILS/web/images/sub_holds_hist_off.jpg
new file mode 100644 (file)
index 0000000..020abe9
Binary files /dev/null and b/Open-ILS/web/images/sub_holds_hist_off.jpg differ
diff --git a/Open-ILS/web/images/sub_holds_hist_on.jpg b/Open-ILS/web/images/sub_holds_hist_on.jpg
new file mode 100644 (file)
index 0000000..020abe9
Binary files /dev/null and b/Open-ILS/web/images/sub_holds_hist_on.jpg differ
diff --git a/Open-ILS/web/images/sub_holds_off.jpg b/Open-ILS/web/images/sub_holds_off.jpg
new file mode 100644 (file)
index 0000000..b888359
Binary files /dev/null and b/Open-ILS/web/images/sub_holds_off.jpg differ
diff --git a/Open-ILS/web/images/sub_holds_on.jpg b/Open-ILS/web/images/sub_holds_on.jpg
new file mode 100644 (file)
index 0000000..9505638
Binary files /dev/null and b/Open-ILS/web/images/sub_holds_on.jpg differ
diff --git a/Open-ILS/web/images/sub_prefs_info_off.jpg b/Open-ILS/web/images/sub_prefs_info_off.jpg
new file mode 100644 (file)
index 0000000..896e227
Binary files /dev/null and b/Open-ILS/web/images/sub_prefs_info_off.jpg differ
diff --git a/Open-ILS/web/images/sub_prefs_info_on.jpg b/Open-ILS/web/images/sub_prefs_info_on.jpg
new file mode 100644 (file)
index 0000000..0895969
Binary files /dev/null and b/Open-ILS/web/images/sub_prefs_info_on.jpg differ
diff --git a/Open-ILS/web/images/sub_prefs_notify_off.jpg b/Open-ILS/web/images/sub_prefs_notify_off.jpg
new file mode 100644 (file)
index 0000000..55df9da
Binary files /dev/null and b/Open-ILS/web/images/sub_prefs_notify_off.jpg differ
diff --git a/Open-ILS/web/images/sub_prefs_notify_on.jpg b/Open-ILS/web/images/sub_prefs_notify_on.jpg
new file mode 100644 (file)
index 0000000..fd536a8
Binary files /dev/null and b/Open-ILS/web/images/sub_prefs_notify_on.jpg differ
diff --git a/Open-ILS/web/images/sub_prefs_search_off.jpg b/Open-ILS/web/images/sub_prefs_search_off.jpg
new file mode 100644 (file)
index 0000000..89115f6
Binary files /dev/null and b/Open-ILS/web/images/sub_prefs_search_off.jpg differ
diff --git a/Open-ILS/web/images/sub_prefs_search_on.jpg b/Open-ILS/web/images/sub_prefs_search_on.jpg
new file mode 100644 (file)
index 0000000..3eab9fa
Binary files /dev/null and b/Open-ILS/web/images/sub_prefs_search_on.jpg differ
diff --git a/Open-ILS/web/images/submit_btn.gif b/Open-ILS/web/images/submit_btn.gif
new file mode 100644 (file)
index 0000000..5286943
Binary files /dev/null and b/Open-ILS/web/images/submit_btn.gif differ
diff --git a/Open-ILS/web/images/tool_back.gif b/Open-ILS/web/images/tool_back.gif
new file mode 100644 (file)
index 0000000..37d1278
Binary files /dev/null and b/Open-ILS/web/images/tool_back.gif differ
diff --git a/Open-ILS/web/images/tool_back.png b/Open-ILS/web/images/tool_back.png
new file mode 100644 (file)
index 0000000..41a13e2
Binary files /dev/null and b/Open-ILS/web/images/tool_back.png differ
diff --git a/Open-ILS/web/images/tool_font.gif b/Open-ILS/web/images/tool_font.gif
new file mode 100644 (file)
index 0000000..9dc10a9
Binary files /dev/null and b/Open-ILS/web/images/tool_font.gif differ
diff --git a/Open-ILS/web/images/tool_forward.gif b/Open-ILS/web/images/tool_forward.gif
new file mode 100644 (file)
index 0000000..db0d800
Binary files /dev/null and b/Open-ILS/web/images/tool_forward.gif differ
diff --git a/Open-ILS/web/images/tool_forward.png b/Open-ILS/web/images/tool_forward.png
new file mode 100644 (file)
index 0000000..582a6b9
Binary files /dev/null and b/Open-ILS/web/images/tool_forward.png differ
diff --git a/Open-ILS/web/images/tool_help.gif b/Open-ILS/web/images/tool_help.gif
new file mode 100644 (file)
index 0000000..2a3de86
Binary files /dev/null and b/Open-ILS/web/images/tool_help.gif differ
diff --git a/Open-ILS/web/images/tool_help.png b/Open-ILS/web/images/tool_help.png
new file mode 100644 (file)
index 0000000..3007c20
Binary files /dev/null and b/Open-ILS/web/images/tool_help.png differ
diff --git a/Open-ILS/web/images/tool_home.gif b/Open-ILS/web/images/tool_home.gif
new file mode 100644 (file)
index 0000000..9b83ccf
Binary files /dev/null and b/Open-ILS/web/images/tool_home.gif differ
diff --git a/Open-ILS/web/images/tool_home.png b/Open-ILS/web/images/tool_home.png
new file mode 100644 (file)
index 0000000..0620200
Binary files /dev/null and b/Open-ILS/web/images/tool_home.png differ
diff --git a/Open-ILS/web/images/tool_mail.gif b/Open-ILS/web/images/tool_mail.gif
new file mode 100644 (file)
index 0000000..83c3573
Binary files /dev/null and b/Open-ILS/web/images/tool_mail.gif differ
diff --git a/Open-ILS/web/images/tool_print.gif b/Open-ILS/web/images/tool_print.gif
new file mode 100644 (file)
index 0000000..d3d7ee3
Binary files /dev/null and b/Open-ILS/web/images/tool_print.gif differ
diff --git a/Open-ILS/web/images/tool_print.png b/Open-ILS/web/images/tool_print.png
new file mode 100644 (file)
index 0000000..2c0dc0b
Binary files /dev/null and b/Open-ILS/web/images/tool_print.png differ
diff --git a/Open-ILS/web/images/utils-corner-left.png b/Open-ILS/web/images/utils-corner-left.png
new file mode 100644 (file)
index 0000000..db70a75
Binary files /dev/null and b/Open-ILS/web/images/utils-corner-left.png differ
diff --git a/Open-ILS/web/images/utils-corner-mid.png b/Open-ILS/web/images/utils-corner-mid.png
new file mode 100644 (file)
index 0000000..80d4857
Binary files /dev/null and b/Open-ILS/web/images/utils-corner-mid.png differ
diff --git a/Open-ILS/web/images/utils-corner-right.jpg b/Open-ILS/web/images/utils-corner-right.jpg
new file mode 100644 (file)
index 0000000..1559897
Binary files /dev/null and b/Open-ILS/web/images/utils-corner-right.jpg differ
diff --git a/Open-ILS/web/images/utils-corner-right.png b/Open-ILS/web/images/utils-corner-right.png
new file mode 100644 (file)
index 0000000..303ab75
Binary files /dev/null and b/Open-ILS/web/images/utils-corner-right.png differ
diff --git a/Open-ILS/web/images/utils-corner.jpg b/Open-ILS/web/images/utils-corner.jpg
new file mode 100644 (file)
index 0000000..4932a28
Binary files /dev/null and b/Open-ILS/web/images/utils-corner.jpg differ
diff --git a/Open-ILS/web/images/view_my_list.png b/Open-ILS/web/images/view_my_list.png
new file mode 100644 (file)
index 0000000..d5f1b83
Binary files /dev/null and b/Open-ILS/web/images/view_my_list.png differ
diff --git a/Open-ILS/web/images/view_my_list_hover.png b/Open-ILS/web/images/view_my_list_hover.png
new file mode 100644 (file)
index 0000000..369cb1a
Binary files /dev/null and b/Open-ILS/web/images/view_my_list_hover.png differ
diff --git a/Open-ILS/web/js/ui/default/opac/simple.js b/Open-ILS/web/js/ui/default/opac/simple.js
new file mode 100644 (file)
index 0000000..7124d03
--- /dev/null
@@ -0,0 +1,29 @@
+/* Keep this dead simple. No dojo. Call nothing via onload. */
+function $(s) { return document.getElementById(s); }
+function removeClass(node, cls) {
+    if (!node || !node.className) return;
+    node.className =
+        node.className.replace(new RegExp("\\b" + cls + "\\b", "g"), "");
+}
+function addClass(node, cls) {
+    if (!node) return;
+    removeClass(node, cls);
+    if (!node.className) node.className = cls;
+    else node.className += ' ' + cls;
+}
+function unHideMe(node) { removeClass(node, "hide_me"); }
+function hideMe(node) { addClass(node, "hide_me"); }
+
+var _search_row_template;
+function addSearchRow() {
+    if (!_search_row_template) {
+        t = $("adv_global_row").cloneNode(true);
+        t.id = null;
+        _search_row_template = t;
+    }
+
+    $("adv_global_tbody").insertBefore(
+        _search_row_template.cloneNode(true),
+        $("adv_global_addrow")
+    );
+}
diff --git a/Open-ILS/web/templates/default/opac-poc/base.tt2 b/Open-ILS/web/templates/default/opac-poc/base.tt2
new file mode 100644 (file)
index 0000000..6d54607
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns='http://www.w3.org/1999/xhtml' lang='[% ctx.locale %]' xml:lang='[% ctx.locale %]'>
+    <head>
+        <title>[% ctx.page_title %]</title>
+        <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+        [% BLOCK html_head; END; # provide a default that can be overridden %]
+        [% PROCESS html_head %]
+    </head>
+    <body>
+        [% content %] 
+    </body>
+</html>
diff --git a/Open-ILS/web/templates/default/opac-poc/common.tt2 b/Open-ILS/web/templates/default/opac-poc/common.tt2
new file mode 100644 (file)
index 0000000..c4caa0e
--- /dev/null
@@ -0,0 +1,58 @@
+[% 
+    # Org Unit Selector Widget : 
+    #   PROCESS build_org_selector id='selector-id' name='selector-name'
+    BLOCK build_org_selector;
+        first_run = 0;
+        IF !org_unit;
+            org_unit = ctx.aou_tree;
+            first_run = 1;
+%]
+    <select id='[% id %]' name='[% name %]'>
+    [% END %]
+        <option value='[% org_unit.id %]' [% IF org_unit.id == value %] selected='selected' [% END %]>
+            [% 
+                pad = org_unit.ou_type.depth * 2;
+                FOR idx IN [0..pad]; '&nbsp;'; END;
+                org_unit.name;
+            %]
+        </option>
+        [% FOR child IN org_unit.children; PROCESS build_org_selector org_unit = child; END %]
+    [% IF first_run %]
+    </select>
+    [% END %]
+[% END %]
+
+[% PROCESS 'default/opac/marc_attrs.tt2' %]
+[%  USE date;
+    USE money = format('$%.2f');
+    icon_by_mattype = {     # XXX KCLS-specific
+        "a" => "media_book.jpg",
+        "b" => "media_magazines.jpg",
+        "c" => "media_printedmusic.jpg",
+        "d" => "media_microform.jpg",
+        "e" => "media_equipment.jpg",
+        "f" => "media_films.jpg",
+        "g" => "",
+        "h" => "media_dvd.jpg",
+        "i" => "media_bookoncassette.jpg",
+        "j" => "media_musiccd.jpg",
+        "k" => "media_musiccassette.jpg",
+        "l" => "media_musicrecord.jpg",
+        "m" => "media_software.jpg",
+        "n" => "media_bookoncd.jpg",
+        "o" => "media_kit.jpg",
+        "p" => "media_newspaper.jpg",
+        "q" => "media_largeprint.jpg",
+        "r" => "media_3dobject.jpg",
+        "s" => "media_slide.jpg",
+        "t" => "media_online.jpg",
+        "u" => "media_eaudio.jpg",
+        "v" => "media_ebooktext.jpg",
+        "w" => "media_eaudio.jpg",
+        "x" => "media_downloadmusic.jpg",
+        "y" => "media_downloadvideo.jpg",
+        "z" => "media_map.jpg",
+        "2" => "media_cassettewithbook.jpg",
+        "5" => "media_cdwithbook.jpg"
+    };
+%]
diff --git a/Open-ILS/web/templates/default/opac-poc/home.tt2 b/Open-ILS/web/templates/default/opac-poc/home.tt2
new file mode 100644 (file)
index 0000000..03b2ad1
--- /dev/null
@@ -0,0 +1,24 @@
+[% ctx.page_title = "Home" %]
+
+[% BLOCK html_head %]
+<style>
+    #home_div { text-align: center; width: 100%; margin-top: 30px;}
+</style>
+[% END %]
+
+[% WRAPPER "default/opac/base.tt2" %]
+[% PROCESS "default/opac/common.tt2" %]
+
+<div id='home_div'>
+    <img src='/images/eg_logo.jpg'/>
+    <br/><br/>
+    <form action='./results' method='GET'>
+        <input type='text' name='query' size='50' value='[% query %]'/>
+        [% PROCESS build_org_selector name='loc' %]
+        <input type='submit' value='[% l('Go!') %]'/>
+        <input type='hidden' name='page' value='0'/>
+    </form>
+</div>
+
+
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac-poc/login.tt2 b/Open-ILS/web/templates/default/opac-poc/login.tt2
new file mode 100644 (file)
index 0000000..1bae958
--- /dev/null
@@ -0,0 +1,32 @@
+[% BLOCK html_head %]
+<style>
+</style>
+[% END %]
+
+[% 
+    USE CGI;
+    WRAPPER "default/opac/base.tt2"; 
+    ctx.page_title = "Login";
+%]
+
+<div style='width:400px; text-align:center; border: 1px solid #888'>
+    <form method='POST'>
+        <table>
+            <tr>
+                <td>Username or Barcode</td>
+                <td><input name='username' type='text'/></td>
+            </tr>
+            <tr>
+                <td>Password</td>
+                <td><input name='password' type='password'/></td>
+            </tr>
+            <tr>
+                <td colspan='2' style='text-align:center'>
+                    <input type='submit'/>
+                </td>
+            </tr>
+        </table>
+        <input type='hidden' name='redirect_to' value='[% CGI.param('redirect_to') || ctx.referer | replace('^http:', 'https:') %]'/>
+    </form>
+</div>
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac-poc/marc_attrs.tt2 b/Open-ILS/web/templates/default/opac-poc/marc_attrs.tt2
new file mode 100644 (file)
index 0000000..73f12c3
--- /dev/null
@@ -0,0 +1,18 @@
+[% 
+    # Extract MARC fields from XML
+    #   get_marc_attrs( { marc_xml => doc } )
+    BLOCK get_marc_attrs;
+        xml = args.marc_xml;
+        args.isbn = xml.findnodes('//*[@tag="020"]/*[@code="a"]').textContent;
+        args.upc = xml.findnodes('//*[@tag="024"]/*[@code="a"]').textContent;
+        args.issn = xml.findnodes('//*[@tag="022"]/*[@code="a"]').textContent;
+        args.title = xml.findnodes('//*[@tag="245"]/*[@code="a"]').textContent;
+        args.author = xml.findnodes('//*[@tag="100"]/*[@code="a"]').textContent;
+        args.publisher = xml.findnodes('//*[@tag="260"]/*[@code="b"]').textContent;
+        args.pubdate = xml.findnodes('//*[@tag="260"]/*[@code="c"]').textContent;
+        args.mattype = xml.findnodes('//*[@tag="998"]/*[@code="d"]').textContent; # XXX this is KCLS-specific and will need to change
+
+        # clean up the ISBN
+        args.isbn_clean = args.isbn.replace('\ .*', '');
+    END;
+%]
diff --git a/Open-ILS/web/templates/default/opac-poc/myopac/_links.tt2 b/Open-ILS/web/templates/default/opac-poc/myopac/_links.tt2
new file mode 100644 (file)
index 0000000..b034198
--- /dev/null
@@ -0,0 +1,20 @@
+<div>[%
+pages = [
+    {url => "main", name => "My Account"},
+    {url => "circs", name => "Items Out"},
+    {url => "holds", name => "Items on Hold"},
+    {url => "fines", name => "Fines"},
+    {url => "prefs", name => "Account Preferences"},
+    {url => "bookbags", name => "My Bookbags"}
+];
+FOREACH page IN pages %]
+    <span style="margin: 0 0.5em;">
+    [% IF page.url != myopac_page %]<a href="[% page.url %]">[% END;
+        page.name;
+        IF page.url != myopac_page %]</a>
+    [% ELSE; ctx.page_title = page.name; END %]</span>
+[% END %]</div>
+<ul>
+    <li><a href="../home">Home</a></li>
+    <li><a href="../logout">Logout</a></li>
+</ul>
diff --git a/Open-ILS/web/templates/default/opac-poc/myopac/bookbags.tt2 b/Open-ILS/web/templates/default/opac-poc/myopac/bookbags.tt2
new file mode 100644 (file)
index 0000000..0ac2dc0
--- /dev/null
@@ -0,0 +1,52 @@
+[% BLOCK html_head %]
+<style>
+    table { width: 100%; text-align: center; padding: 20px; margin-top: 30px; }
+    table { border-collapse: collapse; }
+    table { padding: 3px; border-bottom: 1px solid #ddd; text-align: left;}
+    table tr:nth-child(odd) { background-color:#ded; }
+    #action_div { width: 95%; }
+    #action-buttons { float:right; }
+</style>
+[% END %]
+
+[% WRAPPER "default/opac/base.tt2" %]
+[% INCLUDE "default/opac/myopac/_links.tt2" myopac_page = "bookbags" %]
+
+[% IF ctx.bookbags.size == 0 %]
+<b>No Bookbags</b>
+[% STOP; END %]
+
+<form method='POST' id='bbag-form'>
+    <div id='action_div'>
+        <div id='action-buttons'>
+            <select name='action'>
+                <option value='delete'>Delete Selected</option>
+                <option value='delete_all'>Delete All</option>
+            </select>
+            <input type='submit' value='Go'/>
+        </div>
+    </div>
+    <table>
+        <thead>
+            <tr>
+                <th>Name</th>
+                <th>Public</th>
+                <th>Created On</th>
+                <th>Items</th>
+            </tr>
+        </thead>
+        <tbody>
+            [% FOR bbag IN ctx.bookbags %]
+                <tr [% IF loop.count % 2 == 1 %] class='bbag-table-odd' [% END %]>
+                    <td>[% bbag.name %]</td>
+                    <td>[% bbag.pub == 't' ? 'Yes' : 'No' %]</td>
+                    <td>[% date.format(ctx.parse_datetime(bbag.create_time),'%Y-%m-%d') %]</td>
+                    <td>XXX</td>
+                </tr>
+            [% END %]
+        </tbody>
+    </table>
+</form>
+
+
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac-poc/myopac/circs.tt2 b/Open-ILS/web/templates/default/opac-poc/myopac/circs.tt2
new file mode 100644 (file)
index 0000000..5f08d2e
--- /dev/null
@@ -0,0 +1,77 @@
+[% BLOCK html_head %]
+<style>
+    table { width: 100%; text-align: center; padding: 20px; margin-top: 30px; }
+    table { border-collapse: collapse; }
+    table { padding: 3px; border-bottom: 1px solid #ddd; text-align: left;}
+    #action_div { width: 95%; }
+    .renew-summary { float:left; padding-right: 10px;}
+    #action-buttons { float:right; }
+    .circ-table-odd { background-color:#ded; }
+    .failure-text { font-weight: bold; color: red; }
+    #circ-form { margin-top: 20px; }
+</style>
+[% END %]
+
+[% PROCESS "default/opac/common.tt2" %]
+[% WRAPPER "default/opac/base.tt2" %]
+[% INCLUDE "default/opac/myopac/_links.tt2" myopac_page = "circs" %]
+
+[% IF ctx.circs.size == 0 %]
+<b>No Items Checked Out</b>
+[% STOP; END %]
+
+<form method='POST' id='circ-form'>
+    <div id='action_div'>
+        [% IF ctx.success_renewals > 0 %]
+            <div class='renew-summary'><b>Successfully renewed [% ctx.success_renewals %] items.</b></div>
+        [% END %]
+        [% IF ctx.failed_renewals > 0 %]
+            <div class='renew-summary'><b>Failed to renew [% ctx.failed_renewals %] items.</b></div>
+        [% END %]
+        <div id='action-buttons'>
+            <button type='submit' value='renew' name='action'>Renew Selected</button>
+            <button type='submit' value='renew_all' name='action'>Renew All</button>
+        </div>
+    </div>
+    <table>
+        <thead>
+            <tr>
+                <th>Title</th>
+                <th>Author</th>
+                <th>Due Date</th>
+                <th>Renewals Remaining</th>
+                <th>Select</th>
+            </tr>
+        </thead>
+        <tbody>
+            [% FOR circ IN ctx.circs %]
+                [% attrs = {marc_xml => circ.marc_xml}; %]
+                [% PROCESS get_marc_attrs args=attrs; %]
+
+                <tr [% IF loop.count % 2 == 1 %] class='circ-table-odd' [% END %]>
+                    <td><a href='../record/[% circ.circ.target_copy.call_number.record.id %]'>[% attrs.title %]</a></td>
+                    <td><a href='../results?query=au:[% attrs.author | url %]'>[% attrs.author %]</a></td>
+                    <td>[% date.format(ctx.parse_datetime(circ.circ.due_date),'%Y-%m-%d') %]</td>
+                    <td><em>[% circ.circ.renewal_remaining %]</em></td>
+                    <td><input name='circ' value='[% circ.circ.id %]' type='checkbox' 
+                        [% IF circ.circ.renewal_remaining < 1 %] disabled='disabled' [% END %]/></td>
+                </tr>
+
+                [% IF circ.renewal_response and circ.renewal_response.textcode != 'SUCCESS' %]
+                <tr [% IF loop.count % 2 == 1 %] class='circ-table-odd' [% END %]>
+                    <td colspan='0'>
+                        <div class='failure-text'>
+                            [% circ.renewal_response.textcode %] 
+                            [% IF circ.renewal_response.payload.fail_part and circ.renewal_response.payload.fail_part != circ.renewal_response.textcode %]
+                                [% circ.renewal_response.payload.fail_part %]
+                            [% END %]
+                        </div>
+                    </td>
+                </tr>
+                [% END %]
+            [% END %]
+        </tbody>
+    </table>
+</form>
+
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac-poc/myopac/fines.tt2 b/Open-ILS/web/templates/default/opac-poc/myopac/fines.tt2
new file mode 100644 (file)
index 0000000..727322f
--- /dev/null
@@ -0,0 +1,107 @@
+[% BLOCK html_head %]
+<style>
+    table { width: 100%; text-align: center; padding: 20px; margin-top: 30px; }
+    table { border-collapse: collapse; }
+    table { padding: 3px; border-bottom: 1px solid #ddd; text-align: left;}
+    table tr:nth-child(odd) { background-color:#ded; }
+    h2 { margin-bottom: 0; }
+</style>
+[% END %]
+
+[% PROCESS "default/opac/common.tt2" %]
+[% WRAPPER "default/opac/base.tt2" %]
+[% INCLUDE "default/opac/myopac/_links.tt2" myopac_page = "fines" %]
+<h2>Summary</h2>
+<table>
+    <thead>
+        <tr>
+            <th>Total Owed</th>
+            <th>Total Paid</th>
+            <th>Balance Owed</th>
+        </tr>
+    </thead>
+    <tbody>
+        <tr>
+            <td>[% money(ctx.fines.total_owed) %]</td>
+            <td>[% money(ctx.fines.total_paid) %]</td>
+            <td>[% money(ctx.fines.balance_owed) %]</td>
+        </tr>
+    </tbody>
+</table>
+
+[% IF ctx.fines.circulation.size > 0 %]
+<h2>Overdue materials</h2>
+<table>
+    <thead>
+        <tr>
+            <th>Title</th>
+            <th>Author</th>
+            <th>Checkout Date</th>
+            <th>Due Date</th>
+            <th>Date Returned</th>
+            <th>Balance Owed</th>
+        </tr>
+    </thead>
+    <tbody>
+    [% FOR f IN ctx.fines.circulation %]
+        [% attrs = {marc_xml => f.marc_xml}; %]
+        [% PROCESS get_marc_attrs args=attrs; %]
+        <tr>
+            <td>[% attrs.title %]</td>
+            <td>[% attrs.author %]</td>
+            <td>[% date.format(
+                ctx.parse_datetime(f.xact.circulation.xact_start), "%Y-%m-%d"
+            ) %]</td>
+            <td>[% date.format(
+                ctx.parse_datetime(f.xact.circulation.due_date), "%Y-%m-%d"
+            ) %]</td>
+            <td>[%
+                IF f.xact.circulation.checkin_time;
+                    date.format(
+                        ctx.parse_datetime(f.xact.circulation.checkin_time),
+                        "%Y-%m-%d"
+                    );
+                END %]</td><!-- XXX TODO display stop_fines_time if set? Display something instead of blank like "fines accruing" ? -->
+            <td>[% money(f.xact.balance_owed) %]</td>
+        </tr>
+    [% END %]
+    </tbody>
+</table>
+[% END %]
+
+[% IF ctx.fines.grocery.size > 0 %]
+<h2>Other Fees</h2>
+<table>
+    <thead>
+        <tr>
+            <th>Transaction Start Time</th>
+            <th>Last Payment Time</th>
+            <th>Initial Amount Owed</th>
+            <th>Total Amount Paid</th>
+            <th>Balance Owed</th>
+            <th>Billing Type</th>
+        </tr>
+    </thead>
+    <tbody>
+    [% FOR f IN ctx.fines.grocery %]
+        <tr>
+            <td>[%
+                date.format(
+                    ctx.parse_datetime(f.xact.xact_start), "%Y-%m-%d"
+                ) %]</td>
+            <td>[% IF f.xact.last_payment_ts;
+                    date.format(
+                        ctx.parse_datetime(f.xact.last_payment_ts), "%Y-%m-%d"
+                        );
+                    END %]</td>
+            <td>[% money(f.xact.total_owed) %]</td>
+            <td>[% money(f.xact.total_paid) %]</td>
+            <td>[% money(f.xact.balance_owed) %]</td>
+            <td>[% f.xact.last_billing_type %]</td>
+        </tr>
+    [% END %]
+    </tbody>
+</table>
+[% END %]
+
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac-poc/myopac/holds.tt2 b/Open-ILS/web/templates/default/opac-poc/myopac/holds.tt2
new file mode 100644 (file)
index 0000000..ce09725
--- /dev/null
@@ -0,0 +1,94 @@
+[% BLOCK html_head %]
+<style>
+    table { width: 100%; text-align: center; padding: 20px; margin-top: 30px; }
+    table { border-collapse: collapse; }
+    table { padding: 3px; border-bottom: 1px solid #ddd; text-align: left;}
+    table tr:nth-child(odd) { background-color:#ded; }
+    #action_div { width: 95%; }
+    #action-buttons { float:right; }
+</style>
+[% END %]
+
+[%  PROCESS "default/opac/common.tt2";
+    WRAPPER "default/opac/base.tt2";
+    INCLUDE "default/opac/myopac/_links.tt2" myopac_page = "holds" %]
+
+[% IF ctx.holds.size == 0 %]
+<b>No Items On Hold</b>
+[% STOP; END %]
+
+<form method='POST'>
+
+    <div id='action_div'>
+        <div id='action-buttons'>
+            <select name='action'>
+                <option value='cancel'>Cancel Selected</option>
+                <option value='cancel_all'>Cancel All</option>
+                <option value='suspend'>Suspend Selected</option>
+                <option value='suspend_all'>Suspend All</option>
+                <option value='activate'>Activate Selected</option>
+                <option value='activate_all'>Activate All</option>
+            </select>
+            <input type='Submit' value='Go'/>
+        </div>
+    </div>
+    <table>
+        <thead>
+            <tr>
+                <th>Title</th>
+                <th>Author</th>
+                <th>Formats</th>
+                <th>Pickup Location</th>
+                <th>Status</th>
+                <th>Active</th>
+                <th>Activate on...</th>
+                <th>Expiration Date</th>
+                <th>Select</th>
+            </tr>
+        </thead>
+        <tbody>
+            [% FOR hold IN ctx.holds %]
+                [% attrs = {marc_xml => hold.marc_xml}; %]
+                [% PROCESS get_marc_attrs args=attrs; %]
+            <tr>
+                <td><a href='../record/[% hold.hold.bre.id %]'>[% attrs.title %]</a></td>
+                <td><a href='../results?query=au:[% attrs.author | url %]'>[% attrs.author %]</a></td>
+                <td>
+                    [%
+                        key = attrs.mattype;
+                        format_desc = ctx.find_citm(key).value;
+                        icon_filename = icon_by_mattype.$key;
+                        IF icon_filename;
+                    %]<!-- XXX in situations where we might show M-type holds, this won't be good enough -->
+                    <img alt="[% format_desc %]" title="[% format_desc %]"
+                        src="/images/mattype/[% icon_filename %]" />
+                    [%  END %]
+                </td>
+                <td>[% ctx.find_aou(hold.hold.hold.pickup_lib).name %]</td>
+                <td>[%
+                    IF hold.hold.status == 4;
+                        "Available";
+                    ELSIF hold.hold.estimated_wait;
+                        "Estimated wait (days): "; hold.hold.estimated_wait;
+                    ELSIF hold.hold.status == 3;
+                        "In Transit";
+                    ELSIF hold.hold.status < 3;
+                        "Waiting for copy";
+                    END;
+                %]</td>
+                <td>[% IF hold.hold.hold.frozen == 't' %] No [% ELSE %] Yes [% END %]</td>
+                <td>[% 
+                    IF hold.hold.hold.frozen == 't' AND hold.hold.hold.thaw_date;
+                        date.format(ctx.parse_datetime(hold.hold.hold.thaw_date),'%Y-%m-%d'); 
+                    ELSE;
+                        '-';
+                    END 
+                %]</td>
+                <td>[% hold.hold.hold.expire_time ? hold.hold.hold.expire_time : '-' %]</td>
+                <td><input type='checkbox' name='hold_id' value='[% hold.hold.hold.id %]'/></td>
+            </tr>
+            [% END %]
+        </tbody>
+    </table>
+</form> 
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac-poc/myopac/main.tt2 b/Open-ILS/web/templates/default/opac-poc/myopac/main.tt2
new file mode 100644 (file)
index 0000000..33a533e
--- /dev/null
@@ -0,0 +1,39 @@
+[% BLOCK html_head %]
+<style>
+    table { text-align: center; padding: 20px; margin-top: 30px; border-collapse: collapse; }
+    table td { padding: 5px 15px 5px 15px; border-bottom: 1px solid #ddd; text-align: left;}
+    table tr:nth-child(odd) { background-color:#ded; }
+</style>
+[% END %]
+
+[% WRAPPER "default/opac/base.tt2" %]
+[% INCLUDE "default/opac/myopac/_links.tt2" myopac_page = "main" %]
+<table>
+    <tr>
+        <td>First Name</td>
+        <td>[% ctx.user.first_given_name %]</td>
+    </tr>
+    <tr>
+        <td>Middle Name</td>
+        <td>[% ctx.user.second_given_name %]</td>
+    </tr>
+    <tr>
+        <td>Last Name</td>
+        <td>[% ctx.user.family_name %]</td>
+    </tr>
+    <tr>
+        <td>Library Card</td>
+        <td>[% ctx.user.card.barcode %]</td>
+    </tr>
+    <tr>
+        <td>Email Address</td>
+        <td>[% ctx.user.email %]</td>
+        <td><a href='update_email'>Change</a></td>
+    </tr>
+    <tr>
+        <td>Phone</td>
+        <td>[% ctx.user.day_phone %]</td>
+    </tr>
+</table>
+
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac-poc/myopac/prefs.tt2 b/Open-ILS/web/templates/default/opac-poc/myopac/prefs.tt2
new file mode 100644 (file)
index 0000000..d9a60ba
--- /dev/null
@@ -0,0 +1,15 @@
+[% BLOCK html_head %]
+<style>
+    table { width: 100%; text-align: center; padding: 20px; margin-top: 30px; }
+    table { border-collapse: collapse; }
+    table { padding: 3px; border-bottom: 1px solid #ddd; text-align: left;}
+    table tr:nth-child(odd) { background-color:#ded; }
+</style>
+[% END %]
+
+[% WRAPPER "default/opac/base.tt2" %]
+[% INCLUDE "default/opac/myopac/_links.tt2" myopac_page = "prefs" %]
+<p><em>XXX TODO Need to find out whether the list of pref fields can/should be generated
+    from db entries or something.</em></p>
+
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac-poc/myopac/update_email.tt2 b/Open-ILS/web/templates/default/opac-poc/myopac/update_email.tt2
new file mode 100644 (file)
index 0000000..7666c8f
--- /dev/null
@@ -0,0 +1,20 @@
+[% BLOCK html_head %]
+<style>
+    table { text-align: center; padding: 20px; margin-top: 30px; border-collapse: collapse; }
+    table td { padding: 5px 15px 5px 15px; border-bottom: 1px solid #ddd; text-align: left;}
+    table tr:nth-child(odd) { background-color:#ded; }
+</style>
+[% END %]
+
+[% WRAPPER "default/opac/base.tt2" %]
+[% INCLUDE "default/opac/myopac/_links.tt2" %]
+
+<form method='POST'>
+    <table> 
+        <tr><td>Current Email</td><td>[% ctx.user.email %]</td></tr>
+        <tr><td>New Email</td><td><input type='text' name='email'/></td></tr>
+    </table>
+    <input type='submit'/>
+</form>
+
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac-poc/place_hold.tt2 b/Open-ILS/web/templates/default/opac-poc/place_hold.tt2
new file mode 100644 (file)
index 0000000..bfbee07
--- /dev/null
@@ -0,0 +1,33 @@
+[% BLOCK html_head %]
+<style>
+</style>
+[% END %]
+
+[% 
+    USE CGI;
+    PROCESS "default/opac/common.tt2";
+    WRAPPER "default/opac/base.tt2"; 
+    ctx.page_title = "Place Hold";
+    attrs = {marc_xml => ctx.marc_xml};
+    PROCESS get_marc_attrs args=attrs;
+%]
+
+
+<div>
+    <div>Placing hold on [% attrs.title %], by [% attrs.author %]</div>
+    [% IF ctx.hold_success %] 
+        <div>Succeeded</div>
+    [% ELSIF ctx.hold_failed %]
+        <div>Failed...</div>
+    [% ELSE %]
+    <form action='place_hold' method='POST'>
+        Choose a pickup Library [% PROCESS build_org_selector name='pickup_lib' value=ctx.default_pickup_lib %]
+        <input type='Submit'/>
+        <input type='hidden' name='hold_target' value='[% CGI.param('hold_target') | html %]'/>
+        <input type='hidden' name='hold_type' value='[% CGI.param('hold_type') | html %]'/>
+        <input type='hidden' name='redirect_to' value='[% ctx.referer | html %]'/>
+    </form>
+    [% END %]
+</div>
+
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac-poc/record.tt2 b/Open-ILS/web/templates/default/opac-poc/record.tt2
new file mode 100644 (file)
index 0000000..24f1203
--- /dev/null
@@ -0,0 +1,82 @@
+[% BLOCK html_head %]
+<style>
+    table { width: 100%; padding: 20px; margin-top: 30px; }
+    table { border-collapse: collapse; }
+    table td { padding: 3px; border-bottom: 1px solid #ddd; text-align: left;}
+    table th { padding: 3px; border-bottom: 1px solid #ddd; text-align: left;}
+    table tr:nth-child(even) { background-color:#ded; }
+    #record_table td { padding-left: 15px; padding-right: 15px; }
+</style>
+[% END %]
+
+[% 
+    WRAPPER "default/opac/base.tt2"; 
+    PROCESS "default/opac/common.tt2";
+    ctx.page_title = "Details";
+    record = ctx.record;
+    attrs = {marc_xml => ctx.marc_xml};
+    PROCESS get_marc_attrs args=attrs;
+%]
+
+<div id='detail_div'>
+    <table id='record_table' style='width:auto'>
+        <tr>
+            <td rowspan='10' style='width:55px; vertical-align:top; padding-right:4px;'>
+                [% IF attrs.isbn_clean || attrs.upc %]
+                <img width='50' height='70' src='[% ctx.media_prefix %]/opac/extras/ac/jacket/small/[% attrs.isbn_clean || attrs.upc %]'/>
+                [% END %]
+            </td>
+        </tr>
+        [% IF attrs.title %]<tr><td>Title</td><td>[% attrs.title %]</td></tr>[% END %]
+        [% IF attrs.author %]<tr><td>Author</td><td><a href='../results?query=au:[% attrs.author | uri %]'>[% attrs.author %]</a></td></tr>[% END %]
+        [% IF attrs.isbn %]<tr><td>ISBN</td><td>[% attrs.isbn %]</td></tr>[% END %]
+        [% IF attrs.issn %]<tr><td>ISSN</td><td>[% attrs.issn %]</td></tr>[% END %]
+        [% IF attrs.upc %]<tr><td>UPC</td><td>[% attrs.upc %]</td></tr>[% END %]
+        [% IF attrs.pubdate %]<tr><td>Publication Date</td><td>[% attrs.pubdate %]</td></tr>[% END %]
+        [% IF attrs.publisher %]<tr><td>Publishere</td><td>[% attrs.publisher %]</td></tr>[% END %]
+        <tr>
+            <td>Subjects</td>
+            <td>
+            [% FOR node IN ctx.marc_xml.findnodes('//*[@tag="650"]') %]
+                [% 
+                    s0 = node.childNodes.0.textContent;
+                    s1 = node.childNodes.1.textContent;
+                %]
+                [% IF s0 %]
+                    <a href='../results?query=su:[% s0 | url %]'>[% s0 %]</a>
+                    [% IF s1 %]
+                    <span>--</span>
+                    <a href='../results?query=su:[% s1 | url %]'>[% s1 %]</a>
+                    [% END %]
+                    <br/>
+                [% END %]
+            [% END %]
+            </td>
+        </tr>
+    </table>
+    <table id='copy_table'>
+        <thead>
+            <tr>
+                <th>Owning Lib</th>
+                <th>Call Number</th>
+                <th>Barcode</th>
+                <th>Status</th>
+            </tr>
+        </thead>
+        <tbody>
+        [% FOR acn IN record.call_numbers %]
+            [% FOR acp IN acn.copies %]
+                <tr>
+                    <td>[% ctx.find_aou(acn.owning_lib).shortname %]</td>
+                    <td>[% acn.label %]</td>
+                    <td>[% acp.barcode %]</td>
+                    <td>[% ctx.find_ccs(acp.status).name %]</td>
+                </tr>
+            [% END %]
+        [% END %]
+        </tbody>
+    </table>
+</div>
+
+
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac-poc/results.tt2 b/Open-ILS/web/templates/default/opac-poc/results.tt2
new file mode 100644 (file)
index 0000000..9ecead4
--- /dev/null
@@ -0,0 +1,117 @@
+[% BLOCK html_head %]
+<style>
+    #body_table { width: 100%; margin-top: 20px; }
+    #left_block { width: 15%; vertical-align: top; }
+    #right_block { width: auto; vertical-align: top;}
+    #record_table { border-collapse: collapse; width:100%; }
+    #record_table td { padding: 3px; border-bottom: 1px solid #ddd; }
+    #record_table tr:nth-child(odd) { background-color:#ded; }
+    .record-table-odd { background-color:#ded; }
+    #form_div { text-align: center; width: 100%; margin-top: 10px;}
+    #links_div { margin-bottom: 10px; padding: 5px;}
+</style>
+[% END %]
+
+[% 
+    USE CGI;
+    USE POSIX;
+    WRAPPER "default/opac/base.tt2"; 
+    PROCESS "default/opac/common.tt2";
+    ctx.page_title = "Results";
+    page = CGI.param('page') || 0; 
+    query = CGI.param('query');
+    page_count = POSIX.ceil(ctx.hit_count / ctx.page_size);
+    loc = CGI.param('loc');
+%]
+
+<div id='form_div'>
+    <form action='./results' method='GET'>
+        <input type='text' name='query' size='50' value='[% query %]'/>
+        [% PROCESS build_org_selector name='loc' value=loc %]
+        <input type='submit'/>
+        <input type='hidden' name='page' value='0'/>
+    </form>
+</div>
+
+<table id='body_table'>
+    <tr>
+        <td id='left_block'>
+                [% IF ctx.user; %]
+                    <div id='links_div'>
+                        <div><a href='home'>Home</a></div>
+                        <div><a href='myopac/main'>Account</a></div>
+                        <div><a href='logout'>Logout</a></div>
+                    </div>
+                    <hr/>
+                    <table>
+                        <tr><td colspan='2' style='border-bottom:1px solid #9A9'>Signed in as [% ctx.user.usrname %]</td></tr>
+                        <tr><td>Total Holds</td><td>[% ctx.user_stats.holds.total %]</td></tr>
+                        <tr><td>Ready Holds</td><td>[% ctx.user_stats.holds.ready %]</td></tr>
+                        <tr><td>Items Out</td><td>[% ctx.user_stats.checkouts.out %]</td></tr>
+                        <tr><td>Fines</td><td>$[% ctx.user_stats.fines.balance_owed %]</td></tr>
+                    </table>
+                [% ELSE %]
+                    [% 
+                        login = CGI.url("-path" => 1).replace('^http:', 'https:').replace('/results','/login');
+                    %]
+                    <a href='[% login %]'>Login</a>
+                [% END %]
+            </div>
+            <div>
+                [% FOR facet_type IN ctx.search_facets.keys %]
+                    [% cmf = ctx.search_facets.$facet_type.cmf %]
+                    <b>[% cmf.label %]</b>
+                    <ul>
+                        [% FOR facet IN ctx.search_facets.$facet_type.data.keys %]
+                            [% facet_count = ctx.search_facets.$facet_type.data.$facet %]
+                            <li><a href='results?query=[% query | url %]&facet=[% cmf.field_class %]|[% cmf.name %][[% facet | url %]]'>[% facet_count %] / [% facet %]</a></li>
+                        [% END %]
+                    </ul>
+                [% END %]
+            </div>
+        </td>
+        <td id='right_block'>
+            <div>
+                <span>[% l('Hits: [_1] / Page [_2] of [_3]', ctx.hit_count, page + 1, page_count) %]</span>
+                [% 
+                    q = query | url;
+                    np_link = '?query=' _ q;
+                    IF loc; np_link = np_link _ "&loc=" _ loc; END;
+                    IF depth or depth == 0; np_link = np_link _ "&depth=" _ depth; END;
+                %]
+                <a [% IF page > 0 %] href='[% np_link %]&page=[% page - 1 %]' [% END %]>Prev</a>  
+                <a [% IF (page + 1) < page_count %] href='[% np_link %]&page=[% page + 1 %]' [% END %]>Next</a>
+            </div>
+            <table id='record_table'>
+                [%
+                FOR rec IN ctx.records;
+                    attrs = {marc_xml => rec.marc_xml};
+                    PROCESS get_marc_attrs args=attrs;
+                %]
+                <tr [% IF loop.count % 2 == 1 %] class='record-table-odd' [% END %]>
+                    <td style='width:52px;height:72px'>
+                        [% IF attrs.isbn %]
+                        <img width='50' height='70' src='[% ctx.media_prefix %]/opac/extras/ac/jacket/small/[% attrs.isbn_clean || attrs.upc %]'/>
+                        [% END %]
+                    </td>
+                    <td width='auto'>
+                        <div width='99%'>
+                            <div style='float:left'>
+                                <a href='record/[% rec.bre.id %]'>[% attrs.title %]</a>
+                            </div>
+                            <div style='float:right'>
+                                <span>[% rec.copy_counts.available %] / [% rec.copy_counts.visible %]</span>
+                                <span style='padding-left:10px;'><a href='place_hold?hold_target=[% rec.bre.id %]&hold_type=T'>Hold</a></span>
+                            </div>
+                        </div><br/>
+                        <div>[% attrs.author %]</div>
+                        <div>[% attrs.isbn || attrs.issn || attrs.upc %] [% attrs.publisher %] [% attrs.pubdate %]</div>
+                    </td>
+                </tr>
+                [% END %]
+            </table>
+        </td>
+    </tr>
+
+</table>
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac/advanced.tt2 b/Open-ILS/web/templates/default/opac/advanced.tt2
new file mode 100644 (file)
index 0000000..adb1807
--- /dev/null
@@ -0,0 +1,23 @@
+[%  PROCESS "default/opac/parts/header.tt2";
+    WRAPPER "default/opac/parts/base.tt2";
+    INCLUDE "default/opac/parts/topnav.tt2";
+    ctx.page_title = l("Advanced Search") %]
+    <div id="search-wrapper">
+        [% INCLUDE "default/opac/parts/utils.tt2" %]
+        <div id="adv_search_parent">
+            <div id="adv_search_tabs">
+                <a href="#" alt="[% l('Advanced Search') %]" id="adv_search"></a>
+                <a href="#" alt="[% l('Numeric Search') %]" id="num_search"></a>
+                <a href="#" alt="[% l('Expert Search') %]" id="expert_search"></a>
+            </div>
+        </div>
+    </div>
+    <div id="content-wrapper">
+        <div id="main-content">
+            <div class="advanced_div">
+            [% INCLUDE "default/opac/parts/advanced/search.tt2" %]
+            </div>
+            <div class="common-full-pad"></div>        
+        </div>
+    </div>
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac/home.tt2 b/Open-ILS/web/templates/default/opac/home.tt2
new file mode 100644 (file)
index 0000000..3436a46
--- /dev/null
@@ -0,0 +1,16 @@
+[%  PROCESS "default/opac/parts/header.tt2";
+    WRAPPER "default/opac/parts/base.tt2";
+    INCLUDE "default/opac/parts/topnav.tt2";
+    ctx.page_title = l("Home") %]
+    <div id="search-wrapper">
+        [% INCLUDE "default/opac/parts/utils.tt2" %]
+        [% INCLUDE "default/opac/parts/searchbar.tt2" %]
+    </div>
+    <div id="content-wrapper">
+        <div id="main-content-home">
+            <div class="common-full-pad"></div>
+            [% INCLUDE "default/opac/parts/homesearch.tt2" %]
+            <div class="common-full-pad"></div>        
+        </div>
+    </div>
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac/login.tt2 b/Open-ILS/web/templates/default/opac/login.tt2
new file mode 100644 (file)
index 0000000..675a40d
--- /dev/null
@@ -0,0 +1,27 @@
+[%  PROCESS "default/opac/parts/header.tt2";
+    WRAPPER "default/opac/parts/base.tt2";
+    INCLUDE "default/opac/parts/topnav.tt2";
+    ctx.page_title = l("Account Login") %]
+    <div id="search-wrapper">
+        [% INCLUDE "default/opac/parts/utils.tt2" %]
+        [% INCLUDE "default/opac/parts/searchbar.tt2" %]
+    </div>
+    <div id="content-wrapper">
+        <div id="main-content">
+            [% INCLUDE "default/opac/parts/login/form.tt2" %]
+            <div class="clear-both very-big-height"></div>     
+            <script type="text/javascript">
+                /* Note: when common browsers suppor HTML5 "autofocus", we can remove this */
+                var _onload = window.onload;
+                window.onload = function() {
+                    try {
+                        document.getElementById("username_field").focus();
+                        if (_onload) _onload();
+                    } catch (E) {
+                        void(0);
+                    }
+                };
+            </script>
+        </div>
+    </div>
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac/mylist.tt2 b/Open-ILS/web/templates/default/opac/mylist.tt2
new file mode 100644 (file)
index 0000000..daccdb7
--- /dev/null
@@ -0,0 +1,20 @@
+[%  PROCESS "default/opac/parts/header.tt2";
+    PROCESS "default/opac/parts/marc_misc.tt2";
+    WRAPPER "default/opac/parts/base.tt2";
+    INCLUDE "default/opac/parts/topnav.tt2";
+    ctx.page_title = l("Record Detail") %]
+    <div id="search-wrapper">
+        [% INCLUDE "default/opac/parts/utils.tt2" %]
+        [% INCLUDE "default/opac/parts/searchbar.tt2" %]
+    </div>
+    <div id="content-wrapper">
+        <div id="main-content">
+            [%  IF ctx.mylist.size;
+                    INCLUDE "default/opac/parts/anon_list.tt2";
+                ELSE %]
+                <div class="opac-auto-171 opac-auto-097">[% l("You have not created a list yet."); %]</div>
+                [% END %]
+            <div class="common-full-pad"></div>        
+        </div>
+    </div>
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac/myopac/circs.tt2 b/Open-ILS/web/templates/default/opac/myopac/circs.tt2
new file mode 100644 (file)
index 0000000..8846bdf
--- /dev/null
@@ -0,0 +1,217 @@
+[%  PROCESS "default/opac/parts/header.tt2";
+    PROCESS "default/opac/parts/marc_misc.tt2";
+    WRAPPER "default/opac/parts/base.tt2" +
+        "default/opac/parts/myopac/base.tt2";
+    myopac_page = "circs"  %]
+<div id='myopac_checked_div' style="padding:0px;">
+    <div id="acct_checked_tabs" style="padding-bottom: 12px;color:#666;" class="hide_me">
+        <div class="align selected" id="checked_label">
+            <img src="[% ctx.media_prefix %]/images/sub_checked_out_on.jpg" />
+        </div>
+        <div class="align" id="checked_hist_link">
+            <a class="" href="#"><img
+                src="[% ctx.media_prefix %]/images/sub_checked_hist_off.jpg" /></a>
+        </div>
+        <div class="align hide_me" id="checked_link">
+            <a href="#">
+                <img src="[% ctx.media_prefix %]/images/sub_checked_out_off.jpg" />
+            </a>
+        </div>
+        <div class="align selected hide_me" id="checked_hist_label">
+            <img src="[% ctx.media_prefix %]/images/sub_checked_hist_on.jpg" />
+        </div>    
+        <div class="clear-both"></div>
+    </div>
+    
+    <div class="header_middle">
+        <span class="float-left">[% l('Current Items Checked Out') %]</span>
+        <span class="float-right">
+            <a class="hide_me" href="#">[% l('Export List') %]</a>
+        </span>
+    </div>
+    <div class="clear-both"></div>
+    [% IF ctx.circs.size < 1 %]
+    <div class="opac-auto-079">
+        <big><strong>[% l('You have no items checked out.') %]</strong></big>
+    </div>
+    [% ELSE %]
+    [% IF ctx.success_renewals %]
+    <div class="renew-summary">
+        [% l("Successfully renewed [_1] item(s)", ctx.success_renewals) %]
+    </div>
+    [% END %]
+    [% IF ctx.failed_renewals %]
+    <div class="renew-summary red">
+        [% l("Failed to renew [_1] item(s)", ctx.failed_renewals) %]
+    </div>
+    [% END %]
+    <div id='checked_main'>
+        <form method="POST" id="circ-form"
+            onsubmit="return confirm('[% l("Are you sure you wish to renew the selected item(s)?") %]');">
+        <table cellpadding='0' cellspacing='0' class="opac-auto-097b">
+            <tr>
+                <td>
+                    <select name="action">
+                        <option value="renew">[% l('Renew Selected Titles') %]</option>
+                    </select>
+                </td>
+                <td style="padding-left:9px;">
+                    <input type="image"
+                        alt="[% l('Go') %]" title="[% l('Go') %]"
+                        src="[% ctx.media_prefix %]/images/go-btn.png" /></a>
+                </td>
+                <td style="padding-left:5px;">
+                    <a href="#"><img alt="Renewing Help"
+                        src="[% ctx.media_prefix %]/images/question-mark.png" /></a>
+                </td>
+            </tr>
+        </table>
+        <table id="acct_checked_main_header" cellpadding='0' cellspacing='0'
+            border='0'>
+            <tr>
+                <td width="1%" style="padding-left:10px;">
+                    <input type="checkbox" id="check_all_checked"
+                        onclick="var inputs=document.getElementsByTagName('input'); for (i = 0; i < inputs.length; i++) { if (inputs[i].name == 'circ' && !inputs[i].disabled) inputs[i].checked = this.checked;}"
+                    />
+                </td>
+                <td width="40%" style="padding-left:5px;">
+                    <span title="Click to sort" class='pointer'>
+                        Title
+                    </span> /
+                    <span title="Click to sort" class='pointer'>
+                        Author
+                    </span>
+                </td>
+                <td width="8%" style="padding-right:5px;" align="center">
+                    <span title="Click to sort" class='pointer'>Renews<br />Left
+                    </span>
+                </td>
+                <td width="13%" style="padding-left:5px;">
+                    <span title="Click to sort" class='pointer'>Due Date</span>
+                </td>
+                <td width="16%">
+                    <span title="Click to sort" class='pointer'>barcode</span>
+                </td>
+                <td width="22%">
+                    <span title="Click to sort" class='pointer'>call number</span>
+                </td>
+            </tr>
+        </table>
+   
+        <div id="checked_temp_parent">
+            <div id="acct_checked_temp">
+                <table cellpadding='0' cellspacing='0' border='0'
+                    style="margin-top:5px;">
+                    [% FOR circ IN ctx.circs;
+                        attrs = {marc_xml => circ.marc_xml};
+                        PROCESS get_marc_attrs args=attrs; %]
+                    <tr>
+                        <td width="1%" style="padding-left:10px;" valign="top">
+                            <input type="checkbox" name="circ"
+                                [% IF circ.circ.renewal_remaining < 1; l('disabled="disabled"'); END %]
+                                value="[% circ.circ.id %]" />
+                        </td>
+                        <td width="40%"
+                            style="padding-left:5px;padding-bottom:10px;"
+                            name="author">
+                            <a href="[% ctx.opac_root %]/record/[% circ.circ.target_copy.call_number.record.id %]" name="[% l('Catalog record') %]">[% attrs.title %]</a>
+                            [% IF attrs.author %] /
+                            <a href="[% ctx.opac_root %]/results?qtype=author&query=[% attrs.author | replace('[,\.:;]', '') | url %]">[% attrs.author %]</a>
+                            [% END %]
+                        </td>
+                        <td width="8%" name="renewals" align="center">
+                            [% circ.circ.renewal_remaining %]
+                        </td>
+                        <td width="13%" style="padding-left:5px;"
+                            name="due_date">
+                            [% date.format(ctx.parse_datetime(circ.circ.due_date),DATE_FORMAT) %]
+                        </td>
+                        <td width="16%" name="barcode">
+                            [% circ.circ.target_copy.barcode %]
+                        </td>
+                        <td width="22%" name="call_number">
+                            [% circ.circ.target_copy.call_number.label %]
+                        </td>
+                    </tr>
+                    [%  IF circ.renewal_response AND
+                            circ.renewal_response.textcode != 'SUCCESS' %]
+                    <tr>
+                        <td colspan="6">[%# XXX colspan="0" does not work in IE %]
+                            <span class="failure-text" title="[% circ.renewal_response.textcode %] / [% circ.renewal_response.payload.fail_part %]">
+                                [% circ.renewal_response.desc || circ.renewal_response.payload.fail_part || circ.renewal_response.textcode %]
+                            </span>
+                        </td>
+                    </tr>
+                    [%  END;
+                    END %]
+                </table>
+            </div>
+        </div>
+        </form>
+    </div>
+    [% END %]
+    <div id='checked_hist' class="hide_me" style="padding-top:8px;">
+        <table id="acct_checked_hist_header" cellpadding='0' cellspacing='0'
+            border='0' width='100%'>
+            <tr>
+                <td width="45%" style="padding-left:15px;">
+                    <span title="Click to sort" class='pointer'>Title</span> /
+                    <span title="Click to sort" class='pointer'>Author</span>
+                </td>
+                <td width="22%"
+                    style="white-space:nowrap;padding-left:5px;">
+                    <span title="Click to sort" class='pointer'>Call Number</span>
+                </td>
+                <td width="11%">
+                    <span title="Click to sort" class='pointer'>Checkout</span>
+                </td>
+                <td width="11%">
+                    <span title="Click to sort" class='pointer'>Due Date</span>
+                </td>
+                <td width="11%">
+                    <span title="Click to sort" class='pointer'>Returned</span>
+                </td>
+            </tr>
+        </table>
+        <table cellpadding='0' cellspacing='0' border='0'
+            style="margin-top:5px;" width="100%">
+            <tbody id="acct_checked_hist_parent">
+                <tr id="acct_checked_hist_temp">
+                    <td width="45%"
+                        style="padding-left:15px;padding-bottom:10px;">
+                        <a href="#" name="title"></a> /
+                        <span name="author"></span>
+                    </td>
+                    <td width="22%" style="padding-left:5px;"
+                        name="call_number"></td>
+                    <td width="11%" name="checkout"></td>
+                    <td width="11%" name="due_date"></td>
+                    <td width="11%" name="returned"
+                        nowrap="nowrap" style="white-space:nowrap;"></td>
+                </tr>
+            </tbody>
+        </table>
+    </div>
+    <div id='non_cat_circs_div' class='hide_me'>
+        <br/>
+        <div style='text-align: center'><b>[% l("Other Circulations") %]</b></div>
+        <table class='data_grid' width='100%'>
+            <thead>
+                <tr>
+                    <td>[% l("Circulating Library") %]</td>
+                    <td>[% l("Circulation Type") %]</td>
+                    <td>[% l("Please return by ...") %]</td>
+                </tr>
+            </thead>
+            <tbody id='non_cat_circs_tbody'>
+                <tr id='non_cat_circs_row'>
+                    <td name='circ_lib'/>
+                    <td name='item_type'/>
+                    <td name='circ_time'/>
+                </tr>
+            </tbody>
+        </table>
+    <span class='hide_me' id='myopac_renew_fail'>[% l("The system is unable to renew the selected item at this time.  This usually means the item is needed to fulfill a hold.  Please see a librarian for further help.") %]</span>
+   <span class='hide_me' id='myopac_renew_fail2'>[% l("Library policy prevents the renewal of this item at this time.  Please see a librarian for further details.") %]</span>
+</div>
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac/myopac/holds.tt2 b/Open-ILS/web/templates/default/opac/myopac/holds.tt2
new file mode 100644 (file)
index 0000000..d0dd325
--- /dev/null
@@ -0,0 +1,250 @@
+[%  PROCESS "default/opac/parts/header.tt2";
+    PROCESS "default/opac/parts/marc_misc.tt2";
+    WRAPPER "default/opac/parts/base.tt2" +
+        "default/opac/parts/myopac/base.tt2";
+    myopac_page = "holds"  %]
+<div id='myopac_holds_div'>
+    <div id="acct_holds_tabs" style="padding-bottom: 12px;color:#666;" class="hide_me">
+        <div class="align selected" id="holds_label">
+            <img src="[% ctx.media_prefix %]/images/sub_holds_on.jpg" />
+        </div>
+        <div class="align hide_me" id="holds_hist_link">
+            <a href="#"><img
+                src="[% ctx.media_prefix %]/images/sub_holds_hist_off.jpg" /></a>
+        </div>
+        <div class="align hide_me" id="holds_link">
+            <a href="#"><img
+                src="[% ctx.media_prefix %]/images/sub_holds_off.jpg" /></a>
+        </div>
+        <div class="align selected hide_me" id="holds_hist_label">
+            <img src="[% ctx.media_prefix %]/images/sub_holds_hist_on.jpg" />
+        </div> 
+        <div class="clear-both"></div>
+    </div>
+    <div class="header_middle">
+        <span id="acct_holds_header" style="float:left;">
+            [%  IF CGI.param("available");
+                    l("Items Ready for Pickup");
+                ELSE;
+                    l("Current Items on Hold");
+                END
+            %]
+        </span>
+        <span style="float:right;">
+            <a class="hide_me" href="#">Export List</a>
+        </span>
+    </div>
+    <div class="clear-both"></div>
+    <div id='holds_main'>
+        <form method="POST">
+        <table cellpadding='0' cellspacing='0' class="opac-auto-097">
+            <tr>
+                <td width="1">
+                    <select name="action" id="acct_holds_actions">
+                        <option id='myopac_holds_actions_none' value=''>
+                        -- [% l("Actions for selected holds") %] --
+                        </option>
+                        <option value='suspend'>
+                            [% l("Suspend") %]
+                        </option>
+                        <option value='activate'>
+                            [% l("Activate") %]
+                        </option>
+                        <!-- XXX maybe later <option value='thaw_date'>
+                            [% l("Set Active Date") %]
+                        </option> -->
+                        <option value='cancel'>
+                            [% l("Cancel") %]
+                        </option>
+                    </select>
+                </td>
+                <td width="1" style="padding-left:9px;">
+                    <input type="image"
+                        alt="[% l('Go') %]" title="[% l('Go') %]"
+                        src="[% ctx.media_prefix %]/images/go-btn.png" />
+                </td>
+                <td width="1" style="padding-left:5px;">
+                    <a href="#"><img
+                        alt="Holds Help"
+                        src="[% ctx.media_prefix %]/images/question-mark.png" /></a>
+                </td>
+                <td align="right">
+                    [% l("Show") %] &nbsp; &nbsp;
+                    [% IF CGI.param("available") %]
+                    <a href="holds">[% l('all') %]</a> |
+                    <strong>[% l("only available") %]</strong>
+                    [% ELSE %]
+                    <strong>[% l("all") %]</strong> |
+                    <a href="holds?available=1">[% l("only available") %]</a>
+                    [% END %] &nbsp; &nbsp;
+                    [% l("holds") %]
+                    <select class="hide_me" id="holds_sort">
+                        <option value="">-- Sort By --</option>
+                        <option value="title">Title</option>
+                        <option value="pickup">PickUp Location</option>
+                        <option value="status">Status</option>
+                    </select>
+                </td>
+            </tr>
+        </table>
+        [% IF ctx.holds.size < 1 %]
+        <div class="opac-auto-079">
+            <big><strong>[% l('No holds found.') %]</strong></big>
+        </div>
+        [% ELSE %]
+        <table id="acct_holds_main_header" cellpadding='0' cellspacing='0'
+            border='0' width="100%">
+            <tr>
+                <td width="36" align="center">
+                    <input type="checkbox" id="check_all_holds" />
+                </td>
+                <td width="138">
+                    <span title="Click to sort"
+                        style="cursor:pointer;">
+                        Title
+                    </span>
+                </td>
+                <td width="123">
+                    <span title="Click to sort" style="cursor:pointer;">Author</span>
+                </td>
+                <td width="64">
+                    <span title="Click to sort"
+                        style="cursor:pointer;">Format</span>
+                </td>
+                <td width="136">
+                    <span title="Click to sort"
+                        style="cursor:pointer;">Pickup Location</span>
+                </td>
+                <td width="104">Activate</td>
+                <td width="106">Cancel if not<br />filled by</td>
+                <td width="95">Active</td>
+                <td width="172">
+                    <span title="Click to sort"
+                        style="cursor:pointer;">Status</span>
+                </td>
+            </tr>
+        </table>
+        <div class="hide_me">
+            <select id="hold_pickup_lib_temp" name="hold_pickup_lib_sel"
+                class="hide_me" style="width:125px;height:21px;"></select>
+        </div>
+
+        <table cellpadding='0' cellspacing='0' border='0' width="100%">
+            <tbody id="holds_temp_parent">
+                [% FOR hold IN ctx.holds;
+                    attrs = {marc_xml => hold.marc_xml};
+                    PROCESS get_marc_attrs args=attrs %]
+                <tr id="acct_holds_temp" name="acct_holds_temp"
+                    class="acct_holds_temp">
+                    <td width="36" align="center" style="text-align:center;">
+                        <input type="checkbox" name="hold_id" value="[% hold.hold.hold.id %]" />
+                    </td>
+                    <td width="138">
+                        <div style="margin-top:10px;margin-bottom:10px;">
+                            <a href="[% ctx.opac_root %]/record/[% hold.hold.bre.id %]">[% attrs.title | html %]</a>
+                        </div>
+                    </td>
+                    <td width="123">
+                        <div style="margin-top:10px;margin-bottom:10px;">
+                            <a href="[% ctx.opac_root %]/results?qtype=author&query=[% attrs.author | replace('[,\.:;]', '') | url %]">[% attrs.author | html %]</a>
+                        </div>
+                    </td>
+                    <td width="64">
+                        <div style="width:26px;height:23px;margin-top:6px;margin-bottom:6px;">
+                            [% IF attrs.format_icon %]
+                            <img src="[% ctx.media_prefix %]/images/[% attrs.form_icon %]"
+                                title="[% attrs.format %]" alt="[% attrs.format %]" />
+                            [% ELSE;
+                                attrs.format;
+                               END %]
+                        </div>
+                    </td>
+                    <td width="136">
+                        [% ctx.find_aou(hold.hold.hold.pickup_lib).name %]
+                    </td>
+                    <td width="104">
+                        <!-- <input
+                            title="Enter a date (e.g. 10/21/2010)"
+                            class="hide_me" style="width:91px;"
+                            name="activate_box" type="text" /> -->
+                        [% IF hold.hold.hold.frozen == 't' AND
+                                hold.hold.hold.thaw_date;
+                            date.format(ctx.parse_datetime(hold.hold.hold.thaw_date), DATE_FORMAT);
+                        END %]
+                    </td>
+                    <td width="106">
+                        <!-- <input title="[% l('Enter a date (e.g. 10/21/2010)') %]"
+                            class="hide_me" style="width:91px;"
+                            name="hold_expires_box" type="text" />-->
+                        [% IF hold.hold.hold.expire_time;
+                            date.format(ctx.parse_datetime(hold.hold.hold.expire_time), DATE_FORMAT);
+                        END %]
+                    </td>
+                    <td width="95">
+                        <!-- <select name="hold_active_sel"
+                            style="width:90px;" class="hide_me">
+                            <option value="f">Active</option>
+                            <option value="t">Suspended</option>
+                        </select> -->
+                        [% l(hold.hold.hold.frozen == 'f' ? 'Active' : 'Suspended') %]
+                    </td>
+                    <td width="110">
+                        <div name="acct_holds_status"
+                            style="margin-top:10px;margin-bottom:10px;">
+                            [%
+                                IF hold.hold.status == 4;
+                                    l("Available");
+                                ELSIF hold.hold.estimated_wait AND hold.hold.estimated_wait > 0;
+                                    # estimated wait is delivered as seconds.
+                                    SET hwait = POSIX.ceil(hold.hold.estimated_wait / 86400);
+                                    l("Estimated wait: [quant,_1,day,days]", hwait);
+                                ELSIF hold.hold.status == 3;
+                                    l("In Transit");
+                                ELSIF hold.hold.status < 3;
+                                    l("Waiting for copy");
+                                END;
+                            %]
+                        </div>
+                    </td>
+                    <td class="opac-auto-161">
+                        <!-- XXX TODO <a name="hold_edit_link" href="#">Edit</a>
+                        <a href="#" name="hold_save_link"
+                            class="hide_me">Save</a>
+                        <a href="#" name="hold_cancel_link"
+                            class="hide_me">Back</a> -->
+                    </td>
+                </tr>
+                [% END %]
+            </tbody>
+        </table>
+        [% END %]
+        </form>
+    </div>
+
+    <span id='myopac.holds.cancel.confirm' class='hide_me'>[% l("Are you sure you wish to cancel the selected holds?") %]</span>
+    <span id='myopac.holds.freeze.confirm' class='hide_me'>[% l("Are you sure you wish to suspend the selected holds?  If an item has already been selected to fulfill the hold, it will not be suspended") %]</span>
+    <span id='myopac.holds.thaw.confirm' class='hide_me'>[% l("Are you sure you wish to activate the selected holds?") %]</span>
+    <span id='myopac.holds.thaw_date.confirm' class='hide_me'>[% l("Are you sure you wish to change the activate date for the selected holds?") %]</span>
+    <span id='myopac.holds.freeze.select_thaw' class='hide_me'>[% l("Select an automatic activation date.  If no date is chosen, the holds will remain suspended until they are manually activated.") %]</span>
+
+    <table width='100%' id='myopac_holds_processing' class='hide_me'>
+        <tr><td>[% l("Processing holds... This may take a moment.") %]</td></tr>
+    </table>
+   
+    <span class='hide_me' id='myopac_holds_cancel_verify'>
+       [% l("If you wish to cancel the selected hold, click OK, otherwise click Cancel.") %]
+    </span>
+</div>
+<div id='myopac_holds_thaw_date_form' class='hide_me'>
+    <div id='myopac_holds_freeze_select_thaw'>
+        [% l("Select an automatic activation date.  If no date is chosen, the holds will remain suspended until they are manually activated.") %]
+    </div>
+    <p>
+        <input size='10' maxlength='10'
+            type='text' id='myopac_holds_thaw_date_input' />
+    </p>
+    <p>
+        <button>[% l("Submit") %]</button>
+    </p>
+</div>
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac/myopac/lists.tt2 b/Open-ILS/web/templates/default/opac/myopac/lists.tt2
new file mode 100644 (file)
index 0000000..85cf1c0
--- /dev/null
@@ -0,0 +1,166 @@
+[%  PROCESS "default/opac/parts/header.tt2";
+    PROCESS "default/opac/parts/marc_misc.tt2";
+    WRAPPER "default/opac/parts/base.tt2" +
+        "default/opac/parts/myopac/base.tt2";
+    myopac_page = "lists"  %]
+<div id='myopac_bookbag_div' style="padding:5px;">
+    <!-- <div class="header_middle">
+        <span id="acct_holds_header" style="float:left;">[% l('My Lists') %]</span>
+        <span style="float:right;"><a class="hide_me" href="#">[% l('Export List') %]</a></span>
+    </div>
+    <div style="float:right;width:85px;">
+        <div style="position:absolute">
+            <div style="position:relative;top:13px;">
+                <a href="#" style="position:relative;top:-3px;left:-5px;"><img alt="[% l('Saving Help') %]" 
+                    src="[% ctx.media_prefix %]/images/question-mark.png" /></a>
+                <a href="#"><img alt="[% l('Save') %]" src="[% ctx.media_prefix %]/images/save-btn.png"/></a>
+            </div>
+        </div>
+    </div> -->
+    <div id="temp_wrapper">
+        [% INCLUDE "default/opac/parts/anon_list.tt2" %]
+        [% IF ctx.bookbags.size %]
+        <div id='acct_lists_prime'>
+            [% FOR bbag IN ctx.bookbags %]
+            <div id='acct_list_template'>
+                <div style="width:100%">
+                    <div class="bookbag-name">[% bbag.name %]</div>
+                    <div class="bookbag-share">
+                        [% IF bbag.pub == 't'; # XXX TODO %]
+                        <!-- <a target='_blank' name='share_list_rss'><img
+                            alt="[% l('RSS Feed') %]" border="0"
+                            src="[% ctx.media_prefix %]/images/small-rss.png"
+                            title="[% l('You are sharing this list') %]" /></a> -->
+                        [% END %]
+                    </div>
+                    <form action="[% ctx.opac_root %]/myopac/list/update"
+                        method="POST">
+                        <div class="bookbag-share">
+                            <input type="hidden" name="list" value="[% bbag.id %]" />
+                            [% IF bbag.pub != 't' %]
+                            <input type="hidden" name="action" value="show" />
+                            <input type="submit" value="[% l('Share') %]" />
+                            [% ELSE %]
+                            <input type="hidden" name="action" value="hide" />
+                            <input type="submit" value="[% l('Hide') %]" />
+                            [% END %]
+                        </div>
+                    </form>
+                    <form action="[% ctx.opac_root %]/myopac/list/update"
+                        method="POST">
+                        <div class="bookbag-share">
+                            <input type="hidden" name="list" value="[% bbag.id %]" />
+                            <input type="hidden" name="action" value="delete" />
+                            <input type="submit" value="[% l('Delete List') %]" />
+                        </div>
+                    </form>
+                    <div class="clear-both pad-bottom-five"></div>
+                </div>
+                <form action="[% ctx.opac_root %]/myopac/list/update"
+                    method="POST">
+                <input type="hidden" name="list" value="[% bbag.id %]" />
+                <table cellpadding='0' cellspacing='0' border='0'>
+                    <thead id="acct_list_header">
+                        <tr>
+                            <td width="1%" style="padding-left: 10px;">
+                                <input type="checkbox" />
+                            </td>
+                            <td width="49%" style="padding-left: 5px;">[% l('Title') %]</td>
+                            <td width="49%">[% l('Author(s)') %]</td>
+                            <td width="1%" class="nowrap">
+                                <select class="opac-auto-179" name="action">
+                                    <option>[% l('-- Actions for this list --') %]</option>
+                                    <!-- XXX not ready yet<option value="hold">[% l('Place Hold') %]</option> -->
+                                    <option value="del_item">[% l('Remove Items') %]</option>
+                                </select>
+                                <input type="submit" value="[% l('Go') %]" />
+                            </td>
+                        </tr>
+                    </thead>
+                    <tbody>
+                        [% UNLESS bbag.items.size %]
+                        <tr><td colspan="4" class="opac-auto-171 opac-auto-097">
+                            [% l("This list contains no items.") %]
+                        </td></tr>
+                        [% END %]
+                        [% FOR item IN bbag.items;
+                            item_id = item.id;
+                            attrs = {marc_xml => ctx.bookbags_marc_xml.$item_id};
+                            PROCESS get_marc_attrs args=attrs %]
+                        <tr>
+                            <td class="opac-auto-097b" style="padding-left: 10px;"><input type="checkbox" name="del_item" value="[% item_id %]" /></td>
+                            <td class="opac-auto-097b" style="padding-left: 5px;">[% attrs.title %]</td>
+                            <td class="opac-auto-097b">[% attrs.author %]</td>
+                        </tr>
+                        [% END %]
+                    </tbody>
+                </table>
+                </form>
+                <br /><br />
+            </div>
+            [% END %]
+        </div>
+        [% END %]
+    </div>
+    <div id='myopac_delete_bookbag_warn' class='hide_me'>
+        [% l("This will remove the selected bookbag and all items contained within the bookbag.  Are you sure you wish to continue?") %]
+    </div>
+    <div style='text-align: center; font-weight: bold;' 
+        class='hide_me' id='myopac_bookbags_none'>[% l("You have not created any bookbags") %]</div>
+    <div style='width: 99%; text-align: center'>
+        <b id='myopac_bookbag_items_name'> </b>
+    </div>
+    <span id='bb_publish_text' class='hide_me'>[% l("Sharing a Bookbag means that the contents of the Bookbag will be visible to others.  To see the public view of a shared Bookbag, click the \"View\" link in the \"Shared\" column of the Bookbag list at the top of this page.") %]</span>
+    <span id='myopac_remove_bb_item_confirm' class='hide_me'>
+        [% l("Are you sure you wish to remove this bookbag item?") %]
+    </span>
+    <span id='myopac_make_published_confirm' class='hide_me'>
+        [% l("Sharing this bookbag will allow the contents of the bookbag to be seen by others.  Are you sure you wish to share this bookbag?") %]
+    </span>
+    <span id='myopac_make_unpublished_confirm' class='hide_me'>
+        [% l("Are you sure you wish to hide this bookbag?") %]
+    </span>
+    <span id='myopac_bb_update_success' class='hide_me'>
+        [% l("The Bookbag was successfully updated.") %]
+    </span>
+    <span id='bb_create_warning' class='hide_me'>
+        [% l("Warning: Adding items to a bookbag creates a link between you and the items in the database.  The contents of the bookbag are NOT publicly viewable unless the bookbag is shared. However, if you prefer not to have any link between your patron record and a particular item or items, we suggest that you do not place said items in a bookbag or that you avoid using bookbags all together.  Thank you.") %]
+    </span>
+    <span id='myopac_bb_what_are' class='hide_me'>
+        [% l("Bookbags are...") %]
+    </span>
+    <span class='hide_me' id='bb_update_success'>
+        [% l("Bookbag successfully updated") %]
+    </span>
+</div>
+<!-- new list creation -->
+<form action="[% ctx.opac_root %]/myopac/list/update" method="POST" id="create_form">
+<div style="padding-bottom: 7px;">
+    <h2>[% l('Create new list') %]</h2><a name="createnewlist"></a>
+    [% l('Enter the name of the new list:') %]<br/>
+    <input type="hidden" name="action" value="create" />
+    <input type="text" name="name" />
+</div>
+
+<table cellpadding="0" cellspacing="10" border="0">
+    <tr>
+        <td>
+            [% l('Share this list?') %]
+            <a href="#"><img alt="[% l('Sharing Help') %]"
+                src="[% ctx.media_prefix %]/images/question-mark.png" /></a>
+        </td>
+        <td>
+            <input type="radio" value="0" name="shared" id="shared_0" checked="checked" /><label for="shared_0">[% l('No') %]</label>
+            <br/>
+            <input type="radio" value="1" name="shared" id="shared_1"/><label for="shared_1">[% l('Yes') %]</label>
+        </td>
+    </tr>
+</table>
+<input type="image" alt="[% l('Submit') %]" src="[% ctx.media_prefix %]/images/btnSubmit.png"/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+<a href="javascript:void(0);"
+    onclick="document.getElementById('create_form').reset(); return false"><img
+    alt="[% l('Cancel') %]"
+    src="[% ctx.media_prefix %]/images/btnCancel.png" /></a>
+</form>
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac/myopac/main.tt2 b/Open-ILS/web/templates/default/opac/myopac/main.tt2
new file mode 100644 (file)
index 0000000..b2e4a2f
--- /dev/null
@@ -0,0 +1,468 @@
+[%  PROCESS "default/opac/parts/header.tt2";
+    PROCESS "default/opac/parts/marc_misc.tt2";
+    WRAPPER "default/opac/parts/base.tt2" +
+        "default/opac/parts/myopac/base.tt2";
+    myopac_page = "main"  %]
+<div id='myopac_summary_div' style="padding:0px;">
+    <div id="acct_sum">
+        <div style="width:742px;float:left;">
+            <div class="header_middle">Account Summary</div>
+        </div>
+        <div id="myopac_sum_fines">
+            <div style="position:absolute;">
+                <div style="position:relative;top:-15px;left:-23px;">
+                    <img src="[% ctx.media_prefix %]/images/acct_sum_fines_tl.png" />
+                </div>
+            </div>
+            <div style="position:absolute;">
+                <div style="position:relative;top:-15px;left:172px;">
+                    <img src="[% ctx.media_prefix %]/images/acct_sum_fines_tr.png" />
+                </div>
+            </div>
+            <div style="position:absolute;">
+                <div style="position:relative;top:161px;left:-23px;">
+                    <img src="[% ctx.media_prefix %]/images/acct_sum_fines_bl.png" />
+                </div>
+            </div>
+            <div style="position:absolute;">
+                <div style="position:relative;top:161px;left:172px;">
+                    <img src="[% ctx.media_prefix %]/images/acct_sum_fines_br.png" />
+                </div>
+            </div>
+            [% l('Fines:') %]
+            <span id="myopac_sum_fines_bal" class='[% ctx.fines.balance_owed ? "red" : ""%]'>
+                [% money(ctx.fines.balance_owed) %]
+            </span><br />
+            <a class="hide_me" href="#" id="pay_fines_btn1"><img
+                alt="[% l('Pay Fines') %]"
+                onmouseover="this.src='[% ctx.media_prefix %]/images/pay-fines-btn-hover.png';"
+                onmouseout="this.src='[% ctx.media_prefix %]/images/pay-fines-btn.png';"
+                src="[% ctx.media_prefix %]/images/pay-fines-btn.png"
+                style="position:relative;top:5px;" /></a>
+        </div>
+        <div style="width:662px;">
+            <div style="float:left;">
+                <div style="padding:10px 0px;" id="myopac_sum_name"></div>
+                <div class="acct_sum_row">
+                    <table width="100%" cellspacing="0" cellpadding="0">
+                        <tr>
+                            <td>
+                                [% l("Items Currently Checked out") %]
+                                <span id="myopac_sum_checked" class="view_link">
+                                    ([% ctx.user_stats.checkouts.total_out %])
+                                </span>
+                            </td>
+                            <td align="right" class="view_link">
+                                <a href="[% ctx.opac_root %]/myopac/circs">[% l("View All") %]</a>
+                            </td>
+                        </tr>
+                    </table>
+                </div>
+                <div class="acct_sum_row">
+                    <table width="100%" cellspacing="0" cellpadding="0">
+                        <tr>
+                            <td>
+                                Items Currently on Hold
+                                <span id="myopac_sum_holds" class="view_link">
+                                    ([% ctx.user_stats.holds.total %])
+                                </span>
+                            </td>
+                            <td align="right" class="view_link">
+                                <a href="[% ctx.opac_root %]/myopac/holds">View All</a>
+                            </td>
+                        </tr>
+                    </table>
+                </div>
+                <div class="acct_sum_row">
+                    <table width="100%" cellspacing="0" cellpadding="0">
+                        <tr>
+                            <td>
+                                Items ready for pickup
+                                <span id="myopac_sum_pickup" class="view_link">
+                                    ([% ctx.user_stats.holds.ready %])
+                                </span>
+                            </td>
+                            <td align="right" class="view_link">
+                                <a href="[% ctx.opac_root %]/myopac/holds?available=1">View All</a>
+                            </td>
+                        </tr>
+                    </table>
+                </div>
+                <div class="acct_sum_row" id="myopac_sum_fines_slim">
+                    <table width="100%" cellspacing="0" cellpadding="0">
+                        <tr>
+                            <td>Fees &amp; Fines</td>
+                            <td align="right" class="view_link">
+                                <a class="hide_me"
+                                    id="show_fines_link"
+                                    href="#">Show Overdue Materials</a>
+                            </td>
+                        </tr>
+                    </table>
+                </div>
+            </div>
+        </div>
+        <div class="clear-both"></div>
+        <div id='myopac_fines_div'>
+            <table width='100%' class='data_grid data_grid_center'>
+                <thead class='color_3'>
+                    <tr>
+                        <td colspan='3' style='padding: 6px'>
+                            <b>[% l("Summary") %]</b>
+                        </td>
+                    </tr>
+                    <tr>
+                        <td width='33%'>[% l("Total Owed") %]</td>
+                        <td width='33%'>[% l("Total Paid") %]</td>
+                        <td width='33%'>[% l("Balance Owed") %]</td>
+                    </tr>
+                </thead>
+                <tbody id='myopac_fines_summary_tbody'>
+                    <tr id='myopac_fines_summary_row'>
+                        <td id='myopac_fines_summary_total'>[% money(ctx.fines.total_owed) %]</td>
+                        <td id='myopac_fines_summary_paid'>[% money(ctx.fines.total_paid) %]</td>
+                        <td id='myopac_fines_summary_balance' class='bold-red'>[% money(ctx.fines.balance_owed) %]</td>
+                    </tr>
+                </tbody>
+            </table>
+        <!--
+        <div id='accrue_explanation' class='hide_me'>
+            <span>Transactions whose balances are marked with a</span>
+            <span class='bold-red'>*</span>
+            <span>will continue to accrue fines until the checked out item is returned.</span>
+        </div>
+        -->
+        [% IF ctx.fines.circulation.size > 0 %]
+            <div id='myopac_circ_trans_div'>
+                <br/><hr/><br/>
+                <table width='100%' class='data_grid data_grid_center'
+                    id='myopac_circ_trans_table'>
+                    <thead>
+                        <tr>
+                            <td colspan='10' style='padding: 6px'>
+                                <strong>[% l("Fines") %]</strong>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td>[% l("Title") %]</td>
+                            <td>[% l("Author") %]</td>
+                            <td>[% l("Checkout Date") %]</td>
+                            <td>[% l("Due Date") %]</td>
+                            <td>[% l("Date Returned") %]</td>
+                            <td>[% l("Balance Owed") %]</td>
+                            <!-- TODO: hidden until pay-fines is implemented
+                            <td nowrap="nowrap" style="white-space:nowrap;">
+                                <input id="pay_fines_box1" checked="checked"
+                                    type="checkbox" title="[% l('Click to (un)select all fines') %]" />
+                                <label for="pay_fines_box1">[% l('Pay Fines') %]</label>
+                            </td>
+                            -->
+                        </tr>
+                    </thead>
+                    <tbody id='myopac_circ_trans_tbody'>
+                        [% FOR f IN ctx.fines.circulation;
+                            attrs = {marc_xml => f.marc_xml};
+                            PROCESS get_marc_attrs args=attrs %]
+                        <tr id='myopac_circ_trans_row'>
+                            <td>
+                                <a class='classic_link'
+                                    href="[% ctx.opac_root %]/record/[% f.xact.circulation.target_copy.call_number.record.id %]">[% attrs.title %]</a>
+                            </td>
+                            <td>
+                                <a class="classic_link"
+                                    href="[% ctx.opac_root %]/results?qtype=author&query=[% attrs.author | replace('[,\.:;]', '') | url %]">[% attrs.author %]</a>
+                            </td>
+                            <td name='myopac_circ_trans_start'>
+                                [% date.format(
+                                    ctx.parse_datetime(
+                                        f.xact.circulation.xact_start
+                                    ), DATE_FORMAT
+                                ) %]
+                            </td>
+                            <td name='myopac_circ_trans_due'>
+                                [% date.format(
+                                    ctx.parse_datetime(
+                                        f.xact.circulation.due_date
+                                    ), DATE_FORMAT
+                                ) %]
+                            </td>
+                            <td name='myopac_circ_trans_finished'>
+                                [%  IF f.xact.circulation.checkin_time;
+                                        date.format(
+                                            ctx.parse_datetime(
+                                                f.xact.circulation.checkin_time
+                                            ), DATE_FORMAT
+                                        );
+                                    ELSE %]
+                                    <!-- XXX TODO fines aren't really accruing
+                                        if circ has hit maxfines. more clarity
+                                        here? -->
+                                    <span class="red">[% l('(fines accruing)') %]</span>
+                                [%  END %]
+                            </td>
+                            <td>
+                                <strong class="red">
+                                    [% money(f.xact.balance_owed) %]
+                                </strong>
+                            </td>
+                            <!-- TODO: hidden until pay-fines is implemented
+                            <td>
+                                <input type="checkbox" name="selector" title="[% l('Pay this fine') %]" />
+                            </td>
+                            -->
+                        </tr>
+                        [% END %]
+                    </tbody>
+                </table>
+            </div>
+        [% END %]
+
+        [% IF ctx.fines.grocery.size > 0 %]
+            <!-- Table for all non-circulation transactions -->
+            <div id='myopac_trans_div'>
+                <br/>
+                <hr class='opac-auto-013'  color="#dcdbdb" />
+                <br/>
+                <table width='100%' class='data_grid data_grid_center'
+                    id='myopac_trans_table'>
+                    <thead>
+                        <tr>
+                            <td colspan='8' style='padding: 6px'>
+                                <b>[% l("Other Fees") %]</b>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td width='16%'>[% l("Transaction Start Time") %]</td>
+                            <td width='16%'>[% l("Last Payment Time") %]</td>
+                            <td width='16%'>[% l("Initial Amount Owed") %]</td>
+                            <td width='16%'>[% l("Total Amount Paid") %]</td>
+                            <td width='16%'>[% l("Balance Owed") %]</td>
+                            <td width='16%'>[% l("Billing Type") %]</td>
+                            <!-- TODO: hidden until pay-fines is implemented
+                            <td width='4%' align="center" nowrap="nowrap"
+                                style="white-space:nowrap;">
+                                <input id="pay_fines_box2" checked="checked"
+                                    type="checkbox"
+                                    title="[% l('Click to (un)select all fines') %]" />
+                                <label for="pay_fines_box2">[% l("Pay Fines") %]</label>
+                            </td>
+                            -->
+                        </tr>
+                    </thead>
+                    <tbody id='myopac_trans_tbody'>
+                        [% FOR f IN ctx.fines.grocery %]
+                        <tr id='myopac_trans_row'>
+                            <td>[% date.format(
+                                    ctx.parse_datetime(f.xact.xact_start),
+                                    DATE_FORMAT
+                            ) %]</td>
+                            <td>
+                                [%  IF f.xact.last_payment_ts;
+                                        date.format(
+                                            ctx.parse_datetime(
+                                                f.xact.last_payment_ts
+                                            ), DATE_FORMAT
+                                        );
+                                    END %]
+                            </td>
+                            <td>[% money(f.xact.total_owed) %]</td>
+                            <td>[% money(f.xact.total_paid) %]</td>
+                            <td class="red">
+                                <strong>
+                                    [% money(f.xact.balance_owed) %]
+                                </strong>
+                            </td>
+                            <td>[% f.xact.last_billing_type %]</td>
+                            <!-- TODO: hidden until pay-fines is implemented
+                            <td>
+                                <input type="checkbox" name='selector' title='[% l("Pay this fine") %]'/>
+                            </td>
+                            -->
+                        </tr>
+                        [% END %]
+                    </tbody>
+                </table>
+            </div>
+            [% END %]
+            <!-- TODO: hidden until pay-fines is implemented
+            <a href="#"><img alt="[% l('Pay Fines') %]"
+                onmouseover="this.src='[% ctx.media_prefix %]/images/pay-fines-btn-hover.png';"
+                src="[% ctx.media_prefix %]/images/pay-fines-btn.png"
+                style="position:relative;top:5px;" /></a>
+            <br/>
+            -->
+        </div>
+    </div>
+    <div id="pay_fines_now" class="hide_me">
+        <table id='oils-selfck-cc-payment-table'>
+            <tbody>
+                <tr>
+                    <td><div style="width:129px;"></div></td>
+                    <td><div style="width:195px;"></div></td>
+                    <td><div style="width:324px;"></div></td>
+                </tr>
+                <tr>
+                    <td colspan='2'><strong>Billing Information</strong></td>
+                    <td rowspan='13' valign='top'>
+                        Selected fines you are paying for:
+                        <table cellpadding="0" cellspacing="5" border="0">
+                            <thead>
+                                <tr>
+                                    <td>
+                                        <strong>Name</strong>
+                                    </td>
+                                    <td>
+                                        <strong>Amount</strong>
+                                    </td>
+                                </tr>
+                            </thead>
+                            <tbody id="selectedFines">
+                            </tbody>
+                        </table>
+                        <br />
+                        <div id='oils-selfck-cc-payment-summary'>
+                            Total amount to pay:
+                            <strong>$<span></span></strong>
+                        </div>
+                        <br />
+                        Click <strong>Cancel</strong> to go back and (un)select
+                        other fines.
+                    </td>
+                </tr>
+                <tr>
+                    <td>First Name</td>
+                    <td><input jsId='oilsSelfckCCFName' /></td>
+                </tr>
+                <tr>
+                    <td>Last Name</td>
+                    <td><input jsId='oilsSelfckCCLName' /></td>
+                </tr>
+                <tr>
+                    <td>Street Address</td>
+                    <td><input jsId='oilsSelfckCCStreet' /></td>
+                </tr>
+                <tr>
+                    <td>City</td>
+                    <td><input jsId='oilsSelfckCCCity' /></td>
+                </tr>
+                <tr>
+                    <td>State or Province</td>
+                    <td><input jsId='oilsSelfckCCState' /></td>
+                </tr>
+                <tr>
+                    <td>ZIP or Postal Code</td>
+                    <td><input jsId='oilsSelfckCCZip' /></td>
+                </tr>
+                <tr>
+                  <td colspan='2'><strong>Credit Card Information</strong></td>
+                </tr>
+                <!-- Technically not needed since card type is derived from the CC number
+                <tr>
+                    <td>Type of Card</td>
+                    <td>
+                        <select jsId='oilsSelfckCCType' required='true'>
+                            <option value='VISA'>VISA</option>
+                            <option value='MasterCard'>MasterCard</option>
+                            <option value='American Express'>American Express</option>
+                        </select>
+                    </td>
+                </tr>
+                -->
+                <tr>
+                    <td>Credit Card #</td>
+                    <td><input jsId='oilsSelfckCCNumber' /></td>
+                </tr>
+                <tr>
+                    <td>
+                        <div style="position:absolute;">
+                            <div style="position:relative;left:80px;">
+                                <a href="#"><img
+                                    src="[% ctx.media_prefix %]/images/question-mark.png" /></a>
+                            </div>
+                        </div>
+                        Security Code
+                    </td>
+                    <td>
+                        <input jsId='oilsSelfckCCCVV' />
+                    </td>
+                </tr>
+                <tr>
+                    <td>Exipration Month</td>
+                    <td>
+                        <select jsId='oilsSelfckCCMonth'>
+                            <option value='01' selected='selected'>January</option>
+                            <option value='02'>February</option>
+                            <option value='03'>March</option>
+                            <option value='04'>April</option>
+                            <option value='05'>May</option>
+                            <option value='06'>June</option>
+                            <option value='07'>July</option>
+                            <option value='08'>August</option>
+                            <option value='09'>September</option>
+                            <option value='10'>October</option>
+                            <option value='11'>November</option>
+                            <option value='12'>December</option>
+                        </select>
+                    </td>
+                </tr>
+                <tr>
+                    <td>Expiration Year</td>
+                    <td>
+                      <select jsId='oilsSelfckCCYear'>
+                        <option value='2011'>2011</option>
+                        <option value='2012'>2012</option>
+                        <option value='2013'>2013</option>
+                        <option value='2014'>2014</option>
+                        <option value='2015'>2015</option>
+                        <option value='2016'>2016</option>
+                        <option value='2017'>2017</option>
+                        <option value='2018'>2018</option>
+                        <option value='2019'>2019</option>
+                      </select>
+                    </td>
+                </tr>
+                <tr class="hide_me">
+                    <td>Edit Billing Address</td>
+                    <td>
+                        <input jsId='oilsSelfckEditDetails'/>
+                    </td>
+                </tr>
+                <tr>
+                    <td colspan='2' align="center">
+                        <button jsId='oilsSelfckCCSubmit'>
+                            Submit Payment
+                        </button>
+                        <button>
+                            Cancel
+                        </button>
+                    </td>
+                </tr>
+                <tr>
+                    <td colspan="3">
+                        <br />
+                        Important! You must have a printed receipt to be
+                        eligible for a refund on lost items (regulations allow
+                        for no exceptions).
+                        <br />
+                        <strong>
+                            To ensure your necessary receipt information is
+                            not lost, enter your email address above and a
+                            receipt will be emailed to you. Otherwise, make
+                            certain you have a printed receipt in hand before
+                            closing the payment receipt screen.
+                        </strong>
+                        <br />
+                        Refunds are not available for parts and pieces, overdue
+                        fines, or items that do not display a specific title in
+                        My Account. For a full list of refundable and
+                        non-refundable items, visit
+                        <a href="http://www.kcls.org/usingthelibrary/borrowing/refundable.cfm">http://www.kcls.org/usingthelibrary/borrowing/refundable.cfm</a><br /><br />
+                        This site uses VeriSign SSL encryption to ensure your
+                        privacy.
+                    </td>
+                </tr>
+            </tbody>
+        </table>
+    </div>
+</div>
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac/myopac/prefs.tt2 b/Open-ILS/web/templates/default/opac/myopac/prefs.tt2
new file mode 100644 (file)
index 0000000..bb62854
--- /dev/null
@@ -0,0 +1,683 @@
+[%  PROCESS "default/opac/parts/header.tt2";
+    WRAPPER "default/opac/parts/base.tt2" +
+        "default/opac/parts/myopac/base.tt2";
+    myopac_page = "prefs"  %]
+    <div id='myopac_prefs_div'>
+        <!-- XXX TODO <div id="acct_prefs_tabs"
+             style="padding-bottom: 12px;color:#666;">
+            <div style="float:left;">
+                <div class="align selected"
+                     id="prefs_info_lbl"><img src=
+                     "[% ctx.media_prefix %]/images/sub_prefs_info_on.jpg" /></div>
+
+                <div class="align hide_me"
+                     id="prefs_info_link">
+                    <a href="#"><img src=
+                         "[% ctx.media_prefix %]/images/sub_prefs_info_off.jpg" /></a>
+                </div>
+
+                <div class="align"
+                     id="prefs_notify_link">
+                    <a href="#"><img src=
+                         "[% ctx.media_prefix %]/images/sub_prefs_notify_off.jpg" /></a>
+                </div>
+
+                <div class="align selected hide_me"
+                     id="prefs_notify_lbl"><img src=
+                     "[% ctx.media_prefix %]/images/sub_prefs_notify_on.jpg" /></div>
+
+                <div class="align"
+                     id="prefs_search_link">
+                    <a href="#"><img src=
+                         "[% ctx.media_prefix %]/images/sub_prefs_search_off.jpg" /></a>
+                </div>
+
+                <div class="align selected hide_me"
+                     id="prefs_search_lbl"><img src=
+                     "[% ctx.media_prefix %]/images/sub_prefs_search_on.jpg" /></div>
+            </div>
+
+            <div style="float:right;width:65px;">
+                <div style="position:absolute">
+                    <div style="position:relative;top:75px;">
+                        <a id='acct_prefs_save'
+                             class='hide_me'
+                             href="#"><img alt="Save"
+                             src="[% ctx.media_prefix %]/images/save-btn.png" /></a>
+                    </div>
+                </div>
+            </div>
+
+            <div class="clear-both"></div>
+        </div> -->
+
+        <div class="header_middle">
+            <span id="acct_prefs_header">
+                Account Information and Preferences
+            </span>
+            <span class="float-right">
+                <a class="hide_me"
+                    href="#">Export List</a>
+            </span>
+        </div>
+
+        <div class="clear-both normal-height"></div>
+
+        <table class="hide_me full-width" id="acct_search_main">
+            <tbody id='myopac_prefs_tbody'>
+                <tr id='myopac_prefs_loading'>
+                    <td colspan='3'><b>[% l("Loading...") %]</b></td>
+                </tr>
+
+                <tr id='myopac_prefs_row'>
+                    <td width='20%'>[% l("Search hits per page") %]</td>
+
+                    <td>
+                        <div style="position:absolute">
+                            <div style="position:relative;top:0px;left:55px;">
+                                <a href="#">
+                                <img alt="Search Hits Help"
+                                     src=
+                                     "[% ctx.media_prefix %]/images/question-mark.png" /></a>
+                            </div>
+                        </div><select id='prefs_hits_per'
+                            style="position:relative;z-index:100;">
+                            <option value='5'>
+                                5
+                            </option>
+
+                            <option value='8'>
+                                8
+                            </option>
+
+                            <option value='10'>
+                                10
+                            </option>
+
+                            <option value='15'>
+                                15
+                            </option>
+
+                            <option value='20'>
+                                20
+                            </option>
+
+                            <option value='25'>
+                                25
+                            </option>
+
+                            <option value='50'>
+                                50
+                            </option>
+                        </select>
+                    </td>
+                </tr>
+
+                <tr>
+                    <td colspan="2"><label for="circHistStart">Keep history of
+                    checked out items?</label> <input type="checkbox"
+                           id="circHistStart" /></td>
+                </tr><!-- FONT size preference -->
+
+                <tr class="hide_me">
+                    <td>[% l("Default Font Size") %]</td>
+
+                    <td><select id='prefs_def_font'>
+                        <option value='regular'>
+                            [% l("Regular Font") %]
+                        </option>
+
+                        <option value='large'>
+                            [% l("Large Font") %]
+                        </option>
+                    </select></td>
+                </tr>
+
+                <tr class="hide_me">
+                    <td>[% l("Default Search Location") %]</td>
+                    <td>
+                        <div style='margin-bottom: 5px;'>
+                            <input type='checkbox' id='myopac_pref_home_lib' />
+                                 [% l("Always search my home library by default.") %]
+                        </div>
+                        <select id='prefs_def_location'></select>
+                    </td>
+                </tr>
+
+                <tr class="hide_me">
+                    <td>[% l("Default Search Range") %]</td>
+
+                    <td><select id='prefs_def_range'>
+                        </select></td>
+                </tr>
+            </tbody>
+        </table><a href=
+        "http://www.kcls.org/usingthelibrary/catalog_help/library_elf.cfm"><u>Try
+        Library Elf-to manage library materials!</u></a>
+
+        <table class="hide_me"
+               id="acct_notify_main">
+            <tbody>
+                <tr class="hide_me">
+                    <td><span>[% l("Default Hold Notification Method") %]</span> <a class=
+                    'classic_link'
+                       href='#'>[% l("(Help)") %]</a></td>
+
+                    <td style="padding-left:15px;"><select id=
+                    'prefs_hold_notify'>
+                        <option value='phone:email'
+                                selected='selected'>
+                            [% l("Use Phone and Email") %]
+                        </option>
+
+                        <option value='phone'>
+                            [% l("Use Phone Only") %]
+                        </option>
+
+                        <option value='email'>
+                            [% l("Use Email Only") %]
+                        </option>
+                    </select></td>
+                </tr>
+
+                <tr>
+                    <td style="padding-top:10px;"><strong>Pick Up Notice for
+                    Holds</strong><br />
+                    <input type="checkbox"
+                           id="opac.hold_notify.email"
+                           name="opac.hold_notify.email" /> <label for=
+                           "opac.hold_notify.email">Email</label><br />
+                    <input type="checkbox"
+                           id="opac.hold_notify.phone"
+                           name="opac.hold_notify.phone" /> <label for=
+                           "opac.hold_notify.phone">Phone</label>
+                           <b>(Temporarily phone notification will generate a
+                           mailed paper notice.)</b></td>
+                </tr>
+
+                <tr>
+                    <td style="padding-top:10px;"><strong>Expire Notice for
+                    Holds</strong><br />
+                    <input type="checkbox"
+                           id="notification.hold.expire.email"
+                           name="notification.hold.expire.email" /> <label for=
+                           "notification.hold.expire.email">Email</label></td>
+                </tr>
+
+                <tr>
+                    <td style="padding-top:10px;"><strong>Cancel Notice for
+                    Holds</strong><br />
+                    <input type="checkbox"
+                           id="notification.hold.cancel.email"
+                           name="notification.hold.cancel.email" /> <label for=
+                           "notification.hold.cancel.email">Email</label></td>
+                </tr>
+
+                <tr>
+                    <td style="padding-top:10px;"><strong>Overdue First
+                    Notice</strong><br />
+                    <input type="checkbox"
+                           id="notification.overdue.first.email"
+                           name="notification.overdue.first.email" />
+                           <label for=
+                           "notification.overdue.first.email">Email</label><br />
+                    <input type="checkbox"
+                           id="notification.overdue.first.phone"
+                           name="notification.overdue.first.phone" />
+                           <label for=
+                           "notification.overdue.first.phone">Phone</label>
+                           <b>(Temporarily phone notification will generate a
+                           mailed paper notice.)</b></td>
+                </tr>
+
+                <tr>
+                    <td style="padding-top:10px;"><strong>Courtesy
+                    Notice</strong><br />
+                    <input type="checkbox"
+                           id="notification.predue.email"
+                           name="notification.predue.email" /> <label for=
+                           "notification.predue.email">Email</label><br /></td>
+                </tr>
+            </tbody>
+        </table>
+
+        <div id="acct_info_main">
+            <div id='myopac.expired.alert'
+                 class='hide_me'
+                 style='margin-bottom: 20px;'>
+                <table class='data_grid'
+                       width='100%'>
+                    <tbody>
+                        <tr>
+                            <td width='100%' class='red'>
+                                [% l("Your account expired on") %]
+                                <span id='myopac.expired.date'></span>!
+                                [% l("Please see a librarian to renew your account.") %]</td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+
+            <div id='myopac.notes.div'
+                 class='hide_me'>
+                <table class='data_grid'
+                       width='100%'>
+                    <thead>
+                        <tr>
+                            <td colspan='2'>
+                            <b>[% l("* Staff Notes *") %]</b></td>
+                        </tr>
+                    </thead>
+
+                    <tbody id='myopac.notes.tbody'>
+                        <tr id='myopac.notes.tr'>
+                            <td><b name='title'></b> : <span name=
+                            'value'></span></td>
+                        </tr>
+                    </tbody>
+                </table><br />
+            </div>
+
+            <table width='70%'
+                   class='light_border data_grid'>
+                <tbody id='myopac_summary_tbody'>
+                    <tr>
+                        <td width='30%'
+                            class='color_4 light_border'>[% l("Name") %]</td>
+
+                        <td class='light_border'>[% l(
+                            HUMAN_NAME_FORMAT,
+                            ctx.user.prefix, ctx.user.first_given_name,
+                            ctx.user.second_given_name, ctx.user.family_name,
+                            ctx.user.suffix
+                        ) | html %]</td>
+
+                        <td></td>
+                    </tr>
+
+                    <tr>
+                        <td class='color_4 light_border'>
+                        [% l("Day Phone") %]</td>
+
+                        <td class='light_border'
+                            id='myopac_summary_dayphone'>[% ctx.user.day_phone | html %]</td>
+
+                        <td class='light_border'><a href='#'
+                           class="hide_me"
+                           id='myopac_summary_phone1_change'
+                           style=
+                           'text-decoration: underline;'>[% l("Change") %]</a></td>
+                    </tr>
+
+                    <tr id='myopac_update_phone1_row'
+                        class='hide_me'>
+                        <td class='myopac_update_cell'
+                            colspan='3'>
+                            <span class='myopac_update_span'>
+                                Enter New [% l("Day Phone") %]:
+                            </span>
+
+                            <input type='text' size='24' id='myopac_new_phone1' />
+                            <span class='myopac_update_span'>
+                                <button>
+                                    <span class='myopac_update_span'>
+                                        [% l("Submit") %]</span>
+                                </button>
+                            </span>
+                            <span class='myopac_update_span'>
+                                <button>
+                                    <span class='myopac_update_span'>
+                                        [% l("Cancel") %]</span>
+                                </button>
+                            </span>
+                        </td>
+                    </tr>
+
+                    <tr>
+                        <td class='color_4 light_border'>
+                        [% l("Evening Phone") %]</td>
+
+                        <td class='light_border'
+                            id='myopac_summary_eveningphone'>[% ctx.user.evening_phone | html %]</td>
+
+                        <td class='light_border'><a href='#'
+                           class="hide_me"
+                           id='myopac_summary_phone2_change'
+                           style=
+                           'text-decoration: underline;'>[% l("Change") %]</a></td>
+                    </tr>
+
+                    <tr id='myopac_update_phone2_row'
+                        class='hide_me'>
+                        <td class='myopac_update_cell'
+                            colspan='3'><span class='myopac_update_span'>New
+                            [% l("Evening Phone") %]:</span>
+                            <input type='text' size='24' id='myopac_new_phone2' />
+                            <span class='myopac_update_span'><button><span class=
+                                'myopac_update_span'>[% l("Submit") %]</span></button></span>
+                            <span class='myopac_update_span'><button><span class=
+                                'myopac_update_span'>[% l("Cancel") %]</span></button></span>
+                        </td>
+                    </tr>
+
+                    <tr>
+                        <td class='color_4 light_border'>
+                        [% l("Other Phone") %]</td>
+
+                        <td class='light_border'
+                            id='myopac_summary_otherphone'>[% ctx.user.other_phone | html %]</td>
+
+                        <td class='light_border'><a href='#'
+                           class="hide_me"
+                           id='myopac_summary_phone3_change'
+                           style=
+                           'text-decoration: underline;'>[% l("Change") %]</a></td>
+                    </tr>
+
+                    <tr id='myopac_update_phone3_row'
+                        class='hide_me'>
+                        <td class='myopac_update_cell'
+                            colspan='3'><span class='myopac_update_span'>Enter
+                            New [% l("Other Phone") %]:</span>
+                            <input type='text' size='24' id='myopac_new_phone3' />
+                            <span class='myopac_update_span'><button><span class=
+                                'myopac_update_span'>[% l("Submit") %]</span></button></span>
+                            <span class='myopac_update_span'><button><span class=
+                                'myopac_update_span'>[% l("Cancel") %]</span></button></span>
+                        </td>
+                    </tr>
+
+                    <tr>
+                        <td class='color_4 light_border'>
+                            <div style="position:absolute">
+                                <div class="hide_me" style=
+                                "position:relative;left:70px;top:-3px;">
+                                    <a href="#">
+                                    <img alt="Username Help"
+                                         src=
+                                         "[% ctx.media_prefix %]/images/question-mark.png" /></a>
+                                </div>
+                            </div>[% l("Username") %]
+                        </td>
+
+                        <td class='light_border'
+                            id='myopac_summary_username'>[% ctx.user.usrname | html %]</td>
+
+                        <td class='light_border'><a href='#'
+                           class="hide_me"
+                           id='myopac_summary_username_change'
+                           style=
+                           'text-decoration: underline;'>[% l("Change") %]</a></td>
+                    </tr>
+
+                    <tr id='myopac_update_username_row'
+                        class='hide_me'>
+                        <td class='myopac_update_cell'
+                            colspan='3'><span class=
+                            'myopac_update_span'>[% l("Enter new username:") %]</span>
+                            <input type='text' size='24' id='myopac_new_username' />
+                            <span class='myopac_update_span'><button><span class=
+                                'myopac_update_span'>[% l("Submit") %]</span></button></span>
+                            <span class='myopac_update_span'><button><span class=
+                                'myopac_update_span'>[% l("Cancel") %]</span></button></span>
+                        </td>
+                    </tr>
+                    <tr>
+                        <td class='color_4 light_border'>
+                        [% l("Password") %]</td>
+                        <td class='light_border'
+                            id='myopac_summary_password'>
+                            [% l("(not shown)") %]</td>
+                        <td class='light_border'><a href='#'
+                           class="hide_me"
+                           style='text-decoration: underline;'>[% l("Change") %]</a></td>
+                    </tr>
+                    <tr class='hide_me'>
+                        <td class='myopac_update_cell'
+                            colspan='3'>
+                            <table>
+                                <tbody>
+                                    <tr>
+                                        <td>
+                                            <span class= 'myopac_update_span'>
+                                                [% l("Enter current password:") %]
+                                            </span>
+                                        </td>
+
+                                        <td>
+                                            <input type='password'
+                                               size='24' />
+                                           </td>
+                                    </tr>
+                                    <tr>
+                                        <td><span class=
+                                        'myopac_update_span'>[% l("Enter new password:") %]</span></td>
+
+                                        <td><input type='password' size='24' />
+                                           </td>
+                                    </tr>
+
+                                    <tr>
+                                        <td><span class=
+                                        'myopac_update_span'>[% l("Re-enter new password:") %]</span></td>
+
+                                        <td>
+                                            <input type='password' size='24' />
+                                        </td>
+                                    </tr>
+                                </tbody>
+                            </table><span class=
+                            'myopac_update_span'><button><span class=
+                            'myopac_update_span'>[% l("Submit") %]</span></button></span>
+                            <span class='myopac_update_span'><button><span class='myopac_update_span'>
+                            [% l("Cancel") %]</span></button></span>
+                        </td>
+                    </tr>
+
+                    <tr>
+                        <td class='color_4 light_border'>[% l("Email Address") %]</td>
+                        <td class='light_border'>[% ctx.user.email | html %]</td>
+                        <td class='light_border'><a href='update_email'>[% l('Change') %]</a></td>
+                    </tr>
+
+                    <tr class='hide_me'>
+                        <td class='myopac_update_cell' colspan='3'>
+                            <span class= 'myopac_update_span'>
+                                [% l("Enter new email address:") %]
+                            </span>
+                            <input type='text' size='24' />
+                            <span class='myopac_update_span'>
+                                <button>
+                                    <span class= 'myopac_update_span'>
+                                        [% l("Submit") %]</span>
+                                </button>
+                            </span>
+                            <span class='myopac_update_span'>
+                                <button>
+                                    <span class='myopac_update_span'>
+                                        [% l("Cancel") %]</span>
+                                </button>
+                            </span>
+                        </td>
+                    </tr>
+                    [% IF ctx.user.ident_value %]<tr class="hide_me">
+                        <td class='color_4 light_border'>
+                        [% l("Primary Identification") %]</td>
+
+                        <td class='light_border'>
+                            [%
+                            # l('[_1] ([_2])', ctx.user.ident_value, ctx.user.ident_type.name) | html
+                            # XXX uncomment the above line to show primary
+                            # identification. With a minor tweak it could
+                            # alternatively be shown but partially obscured. %]
+                        </td>
+                        <td></td>
+                    </tr>[% END %]
+
+                    <tr>
+                        <td class='color_4 light_border'>
+                        [% l("Active Barcode") %]</td>
+
+                        <td class='light_border'>[% ctx.user.card.barcode %]</td>
+
+                        <td></td>
+                    </tr>
+
+                    <tr>
+                        <td class='color_4 light_border'>
+                        [% l("Home Library") %]</td>
+                        <td class='light_border'>[% ctx.user.home_ou.name %]</td>
+                        <td><a href='#'
+                           class="hide_me"
+                           style='text-decoration: underline;'>[% l("Change") %]</a></td>
+                    </tr>
+                    <tr class='hide_me'>
+                        <td class='myopac_update_cell'
+                            colspan='3'>
+                            <span class='myopac_update_span'>
+                                New home library:</span>
+                            <select>
+                            </select>
+                            <span class='myopac_update_span'>
+                                <button>
+                                    <span class= 'myopac_update_span'>
+                                        [% l("Submit") %]</span>
+                                </button>
+                            </span>
+                            <span class='myopac_update_span'>
+                                <button>
+                                    <span class= 'myopac_update_span'>
+                                        [% l("Cancel") %]</span>
+                                </button>
+                            </span>
+                        </td>
+                    </tr>
+                    <tr class="hide_me">
+                        <td class='color_4 light_border'>
+                            [% l("Account Creation Date") %]
+                        </td>
+                        <td class='light_border'
+                            id='myopac_summary_create_date'></td>
+                        <td></td>
+                    </tr>
+                </tbody>
+            </table><br />
+            <hr class='opac-auto-013' color="#DCDBDB" />
+            <br />
+
+            <table width='100%' class='light_border data_grid'>
+                <thead>
+                    <tr>
+                        <td><strong>[% l("Addresses") %]</strong></td>
+
+                    </tr>
+                </thead>
+                <tbody id='myopac_addr_tbody'>
+                    [% FOR addr IN ctx.user.addresses %]
+                    <tr class='[% addr.pending == "t" ? "pending-addr" : "light_border" %]'>
+                        <td>
+                            <table>
+                                <tr>
+                                    <td>[% l("Address Type") %]</td>
+                                    <td name='myopac_addr_type'>[%
+                                        IF addr.pending == "t";
+                                            "<strong>" _ l("*** PENDING ***") _ "</strong> ";
+                                        END;
+                                        addr.address_type | lower | ucfirst;
+                                    %]</td>
+                                </tr>
+                                <tr>
+                                    <td>[% l("Street") %]</td>
+                                    <td name='myopac_addr_street'>[% addr.street1 | html %]</td>
+                                </tr>
+                                [% IF addr.street2 %]<tr>
+                                    <td>[% l("Street") %]</td>
+                                    <td name='myopac_addr_street2'>[% addr.street2 | html %]</td>
+                                </tr>[% END %]
+
+                                <tr>
+                                    <td>[% l("City") %]</td>
+                                    <td name='myopac_addr_city'>[% addr.city | html %]</td>
+                                </tr>
+
+                                <tr>
+                                    <td>[% l("County") %]</td>
+                                    <td name='myopac_addr_county'>[% addr.county| html  %]</td>
+                                </tr>
+
+                                <tr>
+                                    <td>[% l("State") %]</td>
+                                    <td name='myopac_addr_state'>[% addr.state | html %]</td>
+                                </tr>
+
+                                <tr>
+                                    <td>[% l("Country") %]</td>
+                                    <td name='myopac_addr_country'>[% addr.country | html %]</td>
+                                </tr>
+
+                                <tr>
+                                    <td>[% l("Zip") %]</td>
+                                    <td name='myopac_addr_zip'>[% addr.post_code | html %]</td>
+                                </tr>
+                                <tr>
+                                    <td name='myopac_addr_edit_td'
+                                        colspan='2' class='hide_me'>
+                                        <a class='classic_link'
+                                            name='myopac_addr_edit_link'
+                                            href='#'>Edit Address</a>
+                                    </td>
+                                </tr>
+                            </table>
+                        </td>
+                    </tr>
+                    [% END %]
+                </tbody>
+            </table>
+        </div>
+        <div class='hide_me' id='myopac_username_error'>
+            [% l("Please enter a username") %]
+        </div>
+        <div class='hide_me' id='myopac_username_dup'>
+            [% l("The requested username is not available.  Please choose a different username.") %]
+        </div>
+        <div class='hide_me' id='myopac_username_success'>
+            [% l("Username successfully updated") %]
+        </div>
+        <div class='hide_me' id='myopac_username_failure'>
+            [% l("Username update failed") %]
+        </div>
+        <div class='hide_me' id='myopac_email_error'>
+            [% l("Please enter a valid email address") %]
+        </div>
+        <div class='hide_me' id='myopac_email_success'>
+            [% l("Email address successfully updated") %]
+        </div>
+        <div class='hide_me' id='myopac_email_failure'>
+            [% l("Email address update failed") %]
+        </div>
+        <div class='hide_me' id='myopac_password_error'>
+            [% l("Passwords are empty or do not match") %]
+        </div>
+        <div class='hide_me' id='myopac_password_success'>
+            [% l("Password successfully updated") %]
+        </div>
+        <div class='hide_me' id='myopac_password_failure'>
+            [% l("Password update failed") %]
+        </div>
+        <span class='hide_me' id= 'myopac_invalid_username'>
+            [% l("Username cannot contain spaces or have the same format as a barcode") %]
+        </span>
+        <span class='hide_me' id='myopac_addr_changes_saved'>
+            Address Saved
+        </span>
+        <div class='hide_me' id='prefs_update_success'>
+            [% l("Preferences successfully updated") %]
+        </div>
+        <div class='hide_me' id='prefs_update_failure'>
+            [% l("Preferences update failed!") %]
+        </div>
+        <span class='hide_me' id='myopac_pref_hold_notify_alert'>
+            [% l("This setting defines how you will be notified of holds that are ready to be picked up from the library.  By default, holds will use the notification style you choose here.  However, you will still have the option to change individual holds regardless of this setting.") %]
+        </span>
+    </div>
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac/myopac/update_email.tt2 b/Open-ILS/web/templates/default/opac/myopac/update_email.tt2
new file mode 100644 (file)
index 0000000..22b089a
--- /dev/null
@@ -0,0 +1,24 @@
+[%  PROCESS "default/opac/parts/header.tt2";
+    PROCESS "default/opac/parts/marc_misc.tt2";
+    WRAPPER "default/opac/parts/base.tt2" +
+        "default/opac/parts/myopac/base.tt2";
+    myopac_page = "update_email"  %]
+<div id='myopac_summary_div' style="padding:0px;">
+
+[% IF ctx.invalid_email %]
+    <div id='account-update-email-error'>
+        [% | l(ctx.invalid_email) %]
+        The email address "<b>[_1]</b>" is invalid.  Please try a different email address.
+        [% END %]
+    </div>
+[% END %]
+
+<form method='POST' id='account-update-email'>
+    <table> 
+        <tr><td>[% l('Current Email') %]</td><td>[% ctx.user.email | html %]</td></tr>
+        <tr><td>[% l('New Email') %]</td><td><input type='text' name='email' value='[% ctx.invalid_email | html %]'/></td></tr>
+        <tr><td colspan='2' align='center'><input type='submit'/></td></tr>
+    </table>
+</form>
+
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac/parts/advanced/global_row.tt2 b/Open-ILS/web/templates/default/opac/parts/advanced/global_row.tt2
new file mode 100644 (file)
index 0000000..ae8081e
--- /dev/null
@@ -0,0 +1,33 @@
+[%
+    contains_options = [
+        {value => 'contains', label => l('Contains')},
+        {value => 'nocontains', label => l('Does not contain')},
+        {value => 'phrase', label => l('Contains phrase')},
+        {value => 'exact', label => l('Matches exactly')}
+    ];
+    contains = CGI.param('contains');
+    queries = CGI.param('query');
+    qtypes = CGI.param('qtype') || ['keyword' x 3];
+    FOR qtype IN qtypes;
+        c = contains.shift;
+        q = queries.shift; %]
+<tr[% IF loop.first %] id="adv_global_row"[% END %]>
+    <td align='left' width='100%' nowrap='nowrap'>
+        <span class="opac-auto-078">
+            [% INCLUDE "default/opac/parts/qtype_selector.tt2"
+                query_type=qtype %]
+        </span>
+        <select name='contains' style='margin-right: 7px;'>
+            [% FOR o IN contains_options;
+                |l(o.value, o.label) -%]
+            <option value="[_1]"[% c == o.value ? ' selected="selected"' : '' %]>[_2]</option>
+            [% END; END %]
+        </select>
+        <input type='text' size='18' name='query' value="[% q | html %]" />
+        <a href="javascript:;" class="row-remover"
+            title="[% l('Remove row') %]" alt="[% l('Remove row') %]"
+            onclick='var row = this.parentNode.parentNode;var tbody = row.parentNode; if( tbody.getElementsByTagName("tr").length > 2 ) row.parentNode.removeChild(row);'><img src="[% ctx.media_prefix %]/images/adv_row_close_btn.png" /></a>
+    </td>
+</tr>
+[%      i = i + 1;
+    END %]
diff --git a/Open-ILS/web/templates/default/opac/parts/advanced/search.tt2 b/Open-ILS/web/templates/default/opac/parts/advanced/search.tt2
new file mode 100644 (file)
index 0000000..433b438
--- /dev/null
@@ -0,0 +1,204 @@
+<form id="adv_search_form" action="[% ctx.opac_root %]/results" method="GET">
+<table id='adv_global_search' class='data_grid data_grid_center' width='100%'>
+    <tr style='border-bottom: none;'>
+        <!-- Contains the user-addable(?) rows to define search class, containment and text -->
+        <td valign='top' class='opac-auto-012'>
+            <table width='100%' id='adv_global_input_table'>
+                <thead>
+                    <tr>
+                        <td>
+                            <div style="width:100%;" class="header_middle">
+                                [% l("Search Input") %]
+                            </div>
+                        </td>
+                    </tr>
+                </thead>
+                <tbody id='adv_global_tbody'>
+                    [% INCLUDE "default/opac/parts/advanced/global_row.tt2" %]
+                    <!-- add a new row -->
+                    <tr id='adv_global_addrow'>
+                        <td align='left' style="padding-top:7px;">
+                            <a href="javascript:;" id="myopac_new_global_row" onclick='addSearchRow();'>Add Search Row</a>
+                        </td>
+                    </tr>
+                </tbody>
+            </table>
+        </td>
+    </tr>
+    <tr>
+        <td align='top'>
+          <div style="width:100%;" class="header_middle">Search Filters</div>
+          <table cellpadding='10' cellspacing='0' border='0'><tr>
+            <td valign='top'>
+                <strong>[% l("Item Type") %]</strong><br />
+                [%  INCLUDE "default/opac/parts/format_selector.tt2"
+                        multiple="multiple" size="4"
+                        id="adv_global_item_type_basic" %]
+            </td>
+            <td valign='top'>
+                <strong>[% l("Language") %]</strong><br />
+                [%  INCLUDE "default/opac/parts/language_selector.tt2"
+                        multiple="multiple" size="4" %]
+            </td>
+            <td valign='top'>
+                <strong>[% l("Audience") %]</strong><br />
+                    [% INCLUDE "default/opac/parts/audience_selector.tt2"
+                        id="adv_global_audience_basic"
+                        multiple="multiple" size="4" %]
+                </select>
+                    <!--<a id='adv_global_audience_link_adv' class='classic_link adv_adv_link'
+                        href='javascript:void(0);' onclick='
+                        hideMe($("adv_global_audience_basic"));
+                        unHideMe($("adv_global_audience"));
+                        hideMe(this);
+                        unHideMe($("adv_global_audience_link_basic"));
+                        '>[% l("Advanced") %]</a>
+                    <a id='adv_global_audience_link_basic' class='hide_me classic_link adv_adv_link'
+                        href='javascript:void(0);' onclick='
+                        unHideMe($("adv_global_audience_basic"));
+                        hideMe($("adv_global_audience"));
+                        unHideMe($("adv_global_audience_link_adv"));
+                        hideMe(this);'>[% l("Basic") %]</a>-->
+            </td>
+            <td valign='top'>
+            <strong>[% l("Sort Results") %]</strong>
+              <table class='opac-auto-017'>
+                <tr>
+                    <td align='center' width='100%'>
+                        [% INCLUDE "default/opac/parts/filtersort.tt2"
+                            value=CGI.param('sort') %]
+                    </td>
+                </tr>
+              </table>
+            </td>
+          </tr></table>
+        </td>
+    </tr>
+    <tr>
+        <td colspan="2">
+            <table cellpadding='10' cellspacing='0' border='0'>
+                <tbody>
+                    <tr>
+                        <td valign='top'>
+                            <strong>[% l("Search Library") %]</strong><br />
+                            [% PROCESS "default/opac/parts/org_selector.tt2";
+                                PROCESS build_org_selector name='loc' value=loc %]
+                            <div style="position:relative;top:7px;">
+                                <input type='checkbox' name="modifier"
+                                value="available"[% CGI.param('modifier').grep('available').size ? ' checked="checked"' : '' %]
+                                    id='opac.result.limit2avail' />
+                                <label style="position:relative;top:-2px;"
+                                    for='opac.result.limit2avail'>
+                                    [% l("Limit to Available") %]</label>
+                            </div>
+                        </td>
+                        <td valign='top'>
+                            <strong>[% l("Publication Year") %]</strong><br />
+                            <select id='adv_global_pub_date_type' name='pubdate' onchange='
+                                if(this.selectedIndex == 3)
+                                    unHideMe($("adv_global_pub_date_2_span"));
+                                else
+                                    hideMe($("adv_global_pub_date_2_span"));'>
+                                    [%  FOR opt IN [
+                                            {"code" => "is", "label" => l("Is")},
+                                            {"code" => "before", "label" => l("Before")},
+                                            {"code" => "after", "label" => l("After")},
+                                            {"code" => "between", "label" => l("Between")}
+                                        ];
+                                            |l(opt.code, opt.label) %]
+                                        <option value="[_1]"[% CGI.param('pubdate') == opt.code ? ' selected="selected"' : '' %]>[_2]</option>
+                                    [%  END; END %]
+                            </select>    
+                            <div style='margin-top:5px;'>
+                                <input id='adv_global_pub_date_1' name='date1' type='text' size='4' maxlength='4' value="[% CGI.param('date1') | html %]" />
+                                <span id='adv_global_pub_date_2_span' class='[% CGI.param("pubdate") == "between" ? "" : "hide_me" %]'>
+                                   [% l("and") %] <input name='date2' id='adv_global_pub_date_2' type='text' size='4' maxlength='4' value="[% CGI.param('date2') | html %]" />
+                                </span>
+                            </div>
+                        </td>
+                    </tr>
+                    <!-- copy location selector -->
+                    <tr id='adv_copy_location_filter_row' class='hide_me'>
+                        <td align='right'>[% l("Shelving Location") %]</td>
+                        <td align='left' id='adv_copy_location_filter_td'>
+                            <select size='3' id='adv_copy_location_filter_select' multiple='multiple'>
+                            </select>
+                        </td>
+                    </tr>
+                </tbody>
+            </table>
+        </td>
+    </tr>
+    <tr class='border_4_2'>
+        <td align="left" colspan='2'>
+            <input type="image" src="[% ctx.media_prefix %]/images/search_btn.gif"
+            alt="[% l('Search') %]" class='pointer' />
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+            <a href="javascript:document.getElementById('adv_search_form').reset();"
+                id="adv_reset">[% l('Reset Form') %]</a>
+        </td>
+    </tr>
+</table>
+<input type="hidden" name="_adv" value="1" />
+</form>
+<div id='adv_quick_search_sidebar' class='sidebar_chunk hide_me'> 
+    <div id='adv_quick_search'>
+        <div class='adv_quick_search color_4'><b>[% l("Quick Search") %]</b></div>
+        <div style='margin-top: 8px;'>
+            <table><tbody><tr>
+                <td>
+                    <select id='adv_quick_type'>
+                        <option value='isbn'>[% l("ISBN") %]</option>
+                        <option value='issn'>[% l("ISSN") %]</option>
+                        <option value='cn'>[% l("Call Number") %]</option>
+                        <option value='lccn'>[% l("LCCN") %]</option>
+                        <option value='tcn'>[% l("TCN") %]</option>
+                        <option value='barcode'>[% l("Item Barcode") %]</option>
+                    </select>
+                </td><td>
+                    <input type='text' id='adv_quick_text' size='16' />
+                </td>
+            </tr></tbody></table>
+        </div>
+
+        <div style='margin-top: 8px;' class='adv_quick_search_submit'>
+            <!-- XXX TODO make a real form, and make a real submitter (quick
+            submit, FKA advGenericSearch() -->
+            <img src="[% ctx.media_prefix %]/images/search_btn.gif"
+                alt="[% l('Search') %]" id="adv_quick_submit" class='pointer' />
+        </div>
+    </div>
+</div>
+
+
+<div id='adv_marc_search_sidebar' class='sidebar_chunk hide_me'
+    style='width:400px; margin-top: 20px;'> 
+    <div class='adv_quick_search color_4'><b>[% l("MARC Expert Search") %]</b></div>
+    <table style='margin: 3px; width: 100%;' id='adv_sdbar_table'
+        class='border_4_3'>
+        <tbody>
+            <tr>
+                <td align="right">[% l("Tag:") %]</td>
+                <td align="left"><input name='advanced.marc.tag' maxlength='3' size='3' /></td>
+                <td align="right">[% l("Subfield:") %]</td>
+                <td align="left"><input name='advanced.marc.subfield' maxlength='1' size='1' /></td>
+            </tr>
+            <tr>
+                <td align="right">[% l("Value:") %]</td>
+                <td colspan='3' align="left"><input name='advanced.marc.value' size='18' /></td>
+            </tr>
+            <tr name='crow' class='hide_me'>
+                <td colspan='4' align='center'>
+                    <a href='javascript:void(0);' class='classic_link'>[% l("close") %]</a>
+                </td>
+            </tr>
+        </tbody>
+    </table>
+    <div id='adv_marc_submit' class='adv_quick_search_submit'>
+        <a style='margin-right: 4px; position:relative;top:-10px;'
+            class='classic_link' href='javascript:advAddMARC();'>[% l("Add Row") %]</a>
+        <!-- XXX TODO make a real form, and make a real submitter (FKA
+        advMARCRun()) -->
+        <img alt="Search" src="[% ctx.media_prefix %]/images/search_btn.gif" class='pointer' />
+    </div>
+</div>
diff --git a/Open-ILS/web/templates/default/opac/parts/anon_list.tt2 b/Open-ILS/web/templates/default/opac/parts/anon_list.tt2
new file mode 100644 (file)
index 0000000..e1e72fe
--- /dev/null
@@ -0,0 +1,54 @@
+        [% IF ctx.mylist.size %]
+        <form action="[% ctx.opac_root %]/mylist/del" method="POST">
+        <div id='acct_list_template2'>
+            <div style="width:100%">
+                <table cellpadding="0" cellspacing="0" border="0">
+                    <tr>
+                        <td id='anon_list_name'>
+                            [% l('Temporary List') %]
+                        </td>
+                        <td>
+                            <a href="#"><img
+                                alt="[% l('Anonymous List Help') %]"
+                                src="[% ctx.media_prefix %]/images/question-mark.png" /></a>
+                        </td>
+                    </tr>
+                </table>
+                <div class="float-right"></div>
+                <div class="clear-both pad-bottom-five"></div>
+            </div>
+            <table cellpadding='0' cellspacing='0' border='0'>
+                <thead id="acct_list_header_anon">
+                    <tr>
+                        <td width="1%" style="padding-left:10px;"><input type="checkbox"/>
+                        </td>
+                        <td width="49%" style="padding-left:5px;">[% l('Title') %]</td>
+                        <td width="49%" style="padding-left:5px;">[% l('Author(s)') %]</td>
+                        <td width="1%" class="nowrap">
+                            <select class="opac-auto-179" name="action">
+                                <option>[% l('-- Actions for this list --') %]</option>
+                                <!-- XXX not ready <option value="hold">[% l('Place Hold') %]</option> -->
+                                <option value="delete">[% l('Remove Items') %]</option>
+                            </select>
+                            <input type="submit" value="[% l('Go') %]" />
+                        </td>
+                    </tr>
+                </thead>
+                <tbody id='anon_list_tbody'>
+                    [% FOR item IN ctx.mylist;
+                        attrs = {marc_xml => ctx.mylist_marc_xml.$item};
+                        PROCESS get_marc_attrs args=attrs %]
+                    <tr>
+                        <td class="opac-auto-097b" style="padding-left: 10px;">
+                            <input type="checkbox" name="record" value="[% item %]" />
+                        </td>
+                        <td class="opac-auto-097b" style="padding-left: 5px;">[% attrs.title %]</td>
+                        <td class="opac-auto-097b" style="padding-left: 5px;">[% attrs.author %]</td>
+                    </tr>
+                    [% END %]
+                </tbody>
+            </table>
+            <br /><br />
+        </div>
+        </form>
+        [% END %]
diff --git a/Open-ILS/web/templates/default/opac/parts/audience_selector.tt2 b/Open-ILS/web/templates/default/opac/parts/audience_selector.tt2
new file mode 100644 (file)
index 0000000..b3e86bf
--- /dev/null
@@ -0,0 +1,16 @@
+[%  name = name || "fi:audience";
+    id = id || "audience_selector";
+    values = values || CGI.param(name) %]
+<select id='[% id %]' name='[% name %]'[%
+    multiple ? ' multiple="multiple"' : '';
+    size ? (' size="' _ size _ '"') : ''; %]>
+[%
+FOR opt IN [
+    {'code' => 'a,b,c,j', 'label' => l("Juvenile")},
+    {'code' => 'd', 'label' => l("General")},
+    {'code' => 'e', 'label' => l("Adult")}
+];
+    |l(opt.code, opt.label) %]
+<option value='[_1]'[% values.grep('^' _ opt.code _ '$').size ? ' selected="selected"' : '' %]>[_2]</option>
+[% END; END %]
+</select>
diff --git a/Open-ILS/web/templates/default/opac/parts/base.tt2 b/Open-ILS/web/templates/default/opac/parts/base.tt2
new file mode 100644 (file)
index 0000000..488c21d
--- /dev/null
@@ -0,0 +1,46 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns='http://www.w3.org/1999/xhtml' lang='[% ctx.locale %]' xml:lang='[% ctx.locale %]'>
+    <head>
+        <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+        [% IF ctx.authtime %]
+        <meta http-equiv="refresh" content="[% ctx.authtime %];[% ctx.logout_page %]">
+        [% END %]
+        <link rel="stylesheet" type="text/css"
+            href="[% ctx.media_prefix %]/css/skin/default/opac/semiauto.css" />
+        <link rel="stylesheet" type="text/css"
+            href="[% ctx.media_prefix %]/css/skin/default/opac/style.css" />
+        <title>[% l('Catalog - King County Library - [_1]', ctx.page_title) %]</title>
+        <link rel="unapi-server" type="application/xml" title="unAPI" href="/opac/extras/unapi" />
+        [% BLOCK html_head; END; # provide a default that can be overridden -%]
+        [%- PROCESS html_head -%]
+    </head>
+    <body>
+        [% content %] 
+        <div id="footer">
+            <a href="http://www.kcls.org/usingthelibrary/request/">[% l('Request a Purchase') %]</a> &nbsp;|&nbsp;
+            <a href="http://www.kcls.org/usingthelibrary/request/">[% l('Interlibrary Loan') %]</a> &nbsp;|&nbsp;
+            <a href="http://www.kcls.org/about/contact/">[% l('Contact Us') %]</a> &nbsp;|&nbsp;
+            <a href="http://www.kcls.org/usingthelibrary/catalog_help/">[% l('Site Help') %]</a> &nbsp;|&nbsp;
+            <a href="http://www.kcls.org/usingthelibrary/policies/privacy.cfm">[% l('Privacy Statement') %]</a> &nbsp;|&nbsp;
+            <a href="http://www.kcls.org/about/support/">[% l('Support KCLS') %]</a> &nbsp;|&nbsp;
+            <a href="http://www.kcls.org/employment/">[% l('Employment') %]</a> 
+        </div>
+        <script type="text/javascript"
+            src="[% ctx.media_prefix %]/js/ui/default/opac/simple.js"></script>
+        <!-- Google Analytics -->
+        <script type="text/javascript">
+        /* uncomment when ready */ /*
+          var _gaq = _gaq || [];
+          _gaq.push(['_setAccount', 'UA-3018520-10']);
+          _gaq.push(['_trackPageview']);
+
+          (function() {
+            var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+            ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+            var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+          })();
+        */
+        </script>
+        <!-- End Google Analytics -->
+    </body>
+</html>
diff --git a/Open-ILS/web/templates/default/opac/parts/cn_browse.tt2 b/Open-ILS/web/templates/default/opac/parts/cn_browse.tt2
new file mode 100644 (file)
index 0000000..282bfd9
--- /dev/null
@@ -0,0 +1,44 @@
+<!-- ****************** cn_browse.xml ***************************** -->
+<div id='cn_browse' class='cn_browser'>
+    <div id='cn_browse_loading' class='cn_browse_loading hide_me'>
+        [% l("Loading Callnumber Page...") %]
+    </div>
+    <div id='cn_browse_div'> 
+        <div class='color_4'>
+            <span>[% l("You are now browsing") %]</span>
+            <b id='cn_browse_where'> </b>
+        </div>
+        <table class='data_grid bookshelf' width='100%'>
+            <thead>
+                <tr>
+                    <td>
+                        <a id='cn_browse_next' class='classic_link' 
+                        href='javascript:cnBrowsePrev();'><b>[% l("&lt;&lt; Previous Page") %]</b></a>
+                    </td>
+                    <td colspan='1' align='center'>[% l("Shelf Browser") %]</td>
+                    <td>
+                        <a id='cn_browse_prev' class='classic_link' 
+                            href='javascript:cnBrowseNext();'><b>[% l("Next Page &gt;&gt;") %]</b></a>
+                    </td>
+                </tr>
+            </thead>
+            <tbody id='cn_tbody'>
+                <tr id='cn_browse_row'>
+                    <td id='cn_browse_td' class='cn_browse_item' width='25%' valign='top'>
+                        <a><img height='60' width='50' 
+                            class='cn_browse_info' name='cn_browse_pic' border='0' /></a>
+                        <div class='cn_browse_info bold' name='cn_browse_cn'></div>
+                        <div class='cn_browse_info'>
+                            <a name='cn_browse_title' class='classic_link'></a>
+                        </div>
+                        <div class='cn_browse_info'>
+                            <a name='cn_browse_author' class='classic_link'>  </a>
+                        </div>
+                        <div class='cn_browse_info' name='cn_browse_lib'>  </div>
+                    </td>
+                </tr>
+            </tbody>
+        </table>
+    </div>
+</div>
+<!-- ****************** end: cn_browse.xml ***************************** -->
diff --git a/Open-ILS/web/templates/default/opac/parts/filtersort.tt2 b/Open-ILS/web/templates/default/opac/parts/filtersort.tt2
new file mode 100644 (file)
index 0000000..795b179
--- /dev/null
@@ -0,0 +1,15 @@
+<select class="results_header_sel" id='opac.result.sort' name="sort">
+    <option value=''>[% l("Sort by Relevance") %]</option>
+    <optgroup label='[% l("Sort by Title") %]'>
+        <option value='title'[% value == 'title' ? ' selected="selected"' : '' %]>[% l("Title: A to Z") %]</option>
+        <option value='title.desc'[% value == 'title.desc' ? ' selected="selected"' : '' %]>[% l("Title: Z to A") %]</option>
+    </optgroup>
+    <optgroup label='[% l("Sort by Author") %]'>
+        <option value='author'[% value == 'author' ? ' selected="selected"' : '' %]>[% l("Author: A to Z") %]</option>
+        <option value='author.desc'[% value == 'author.desc' ? ' selected="selected"' : '' %]>[% l("Author: Z to A") %]</option>
+    </optgroup>
+    <optgroup label='[% l("Sort by Publication Date") %]'>
+        <option value='pubdate.desc'[% value == 'pubdate.desc' ? ' selected="selected"' : '' %]>[% l("Date: Newest to Oldest") %]</option>
+        <option value='pubdate'[% value == 'pubdate' ? ' selected="selected"' : '' %]>[% l("Date: Oldest to Newest") %]</option>
+    </optgroup>
+</select>
diff --git a/Open-ILS/web/templates/default/opac/parts/format_selector.tt2 b/Open-ILS/web/templates/default/opac/parts/format_selector.tt2
new file mode 100644 (file)
index 0000000..2ca397b
--- /dev/null
@@ -0,0 +1,19 @@
+[%-  name = name || "fi:format";
+    id = id || "format_selector";
+    values = values || CGI.param(name) -%]
+<select id='[% id %]' name='[% name %]'[%
+    multiple ? ' multiple="multiple"' : '';
+    size ? (' size="' _ size _ '"') : ''; %]>
+    <option value=''>[% l("All Formats") %]</option>
+[% FOR o IN formats %]
+    <option value='[% o.code %]'[% values.grep('^' _ o.code _ '$').size ? ' selected="selected"' : ''%]>[% o.name %]</option>
+[%- END %]
+<!--
+       <option value='at'>[% l("Books") %]</option>
+       <option value='at-d'>[% l("Large Print Books") %]</option>
+       <option value='i'>[% l("Audiobooks") %]</option>
+       <option value='g'>[% l("Video Recordings") %]</option>
+       <option value='j'>[% l("Music") %]</option>
+       <option value='m'>[% l("Electronic Resources") %]</option>
+-->
+</select>
diff --git a/Open-ILS/web/templates/default/opac/parts/header.tt2 b/Open-ILS/web/templates/default/opac/parts/header.tt2
new file mode 100644 (file)
index 0000000..aa34ab5
--- /dev/null
@@ -0,0 +1,61 @@
+[%- USE money = format(l('$%.2f'));
+    USE date;
+    USE CGI = CGI_utf8;
+    USE EGI18N;
+    USE POSIX;
+    SET DATE_FORMAT = l('%m/%d/%Y');
+
+    # Don't wrap in l() here; do that where this format string is actually used.
+    SET HUMAN_NAME_FORMAT = '[_1] [_2] [_3] [_4] [_5]';
+
+    # x and y are artifacts of using <input type="image" /> tags instead of
+    # true submit buttons, and their values are never used. page is used, but
+    # currently none of the use cases for rendering the query_string back
+    # into page output call for propagating the value of the page variable.
+
+    query_string = CGI.query_string |
+        replace(';x=\d+','') | replace(';y=\d+','') | replace(';page=\d*', '') |
+        replace(';', '&');
+
+    propagator = '?' _ query_string;
+
+    is_advanced = CGI.param("_adv").size;
+
+    formats = [  # XXX KCLS-specific
+        {'code' => 'a', 'name' => 'Book', 'image' => 'media_book.jpg'},
+        {'code' => 'i', 'name' => 'Book on cassette', 'image' => 'media_bookoncasset.jpg'},
+        {'code' => 'n', 'name' => 'Book on CD', 'image' => 'media_bookoncd.jpg'},
+        {'code' => 'x', 'name' => 'Download music', 'image' => 'media_downloadmusic.jpg'},
+        {'code' => 'y', 'name' => 'Download video', 'image' => 'media_downloadvideo.jpg'},
+        {'code' => 'h', 'name' => 'DVD', 'image' => 'media_dvd.jpg'},
+        {'code' => 'w', 'name' => 'eBook - Audio', 'image' => 'media_eaudio.jpg'},
+        {'code' => 'v', 'name' => 'eBook - Text', 'image' => 'media_ebooktext.jpg'},
+        {'code' => 'e', 'name' => 'Equipment', 'image' => 'media_equipment.jpg'},
+        {'code' => 'f', 'name' => 'Films', 'image' => 'media_films.jpg'},
+        {'code' => 'o', 'name' => 'Kit', 'image' => 'media_kit.jpg'},
+        {'code' => 'q', 'name' => 'Large print', 'image' => 'media_largeprint.jpg'},
+        {'code' => 'b', 'name' => 'Magazine', 'image' => 'media_magazines.jpg'},
+        {'code' => 'd', 'name' => 'Microform', 'image' => 'media_microform.jpg'},
+        {'code' => 'k', 'name' => 'Music cassette', 'image' => 'media_musiccassette.jpg'},
+        {'code' => 'j', 'name' => 'Music CD', 'image' => 'media_musiccd.jpg'},
+        {'code' => 'l', 'name' => 'Music LP', 'image' => 'media_musicrecord.jpg'},
+        {'code' => 'p', 'name' => 'Newspaper', 'image' => 'media_newspaper.jpg'},
+        {'code' => 't', 'name' => 'Online', 'image' => 'media_online.jpg'},
+        {'code' => 'u', 'name' => 'Player', 'image' => 'media_eaudio.jpg'},
+        {'code' => 'c', 'name' => 'Printed music / scores', 'image' => 'media_printedmusic.jpg'},
+        {'code' => '2', 'name' => 'Read along with cassette', 'image' => 'media_cassettewithbook.jpg'},
+        {'code' => '5', 'name' => 'Read along with CD', 'image' => 'media_cdwithbook.jpg'},
+        {'code' => 'm', 'name' => 'Software', 'image' => 'media_software.jpg'},
+        {'code' => 'g', 'name' => 'Video', 'image' => ''},
+        {'code' => 'r', 'name' => '3-D Object', 'image' => 'media_3dobject.jpg'},
+        {'code' => 'z', 'name' => 'Map', 'image' => 'media_map.jpg'},
+        {'code' => 's', 'name' => 'Slide set', 'image' => 'media_slide.jpg'}
+    ];
+
+    icon_by_format = {};
+    FOR o IN formats;
+        code = o.code;
+        icon_by_format.$code = o.image;
+    END;
+
+-%]
diff --git a/Open-ILS/web/templates/default/opac/parts/homesearch.tt2 b/Open-ILS/web/templates/default/opac/parts/homesearch.tt2
new file mode 100644 (file)
index 0000000..2021f16
--- /dev/null
@@ -0,0 +1,64 @@
+<div style='width:664px;height:35px;background:#FFFFFF;'>
+    <strong><center></center></strong>
+</div>
+<div id='hp-banner'>
+    <a href='http://www.kcls.org/newcatalog/'><img
+        src='[% ctx.media_prefix %]/images/golive.jpg'
+        alt='new catalog' title='New Catalog Information' /></a>
+</div>
+<div id='hp-buttons'>
+    <div class="float-left">
+        <img src='[% ctx.media_prefix %]/images/hp-links-left.jpg' />
+    </div>
+    <div class="float-left">
+           <div id='homesearch_thing'>
+               <table cellpadding='0' cellspacing='5' border='0' id='hp-ql-table'>
+                <tr>
+                    <td colspan='4'>
+                        <span class="opac-auto-029">
+                            [% l("Browse for") %]:
+                        </span>
+                    </td>
+                </tr>
+                <tr>
+                    <td>
+                        <a href='http://www.kcls.org/booksandreading/'>books</a>
+                    </td>
+                    <td>
+                        <a href='http://www.kcls.org/movies/movies_browse.cfm'>movies</a>
+                    </td>
+                    <td>
+                        <a href='http://www.kcls.org/ecollection/'>downloads</a>
+                    </td>
+                    <td>
+                        <a href='http://www.kcls.org/websites/'>websites</a>
+                    </td>
+                </tr>
+                <tr>
+                    <td>
+                        <a href='http://www.kcls.org/music/'>music</a>
+                    </td>
+                    <td>
+                        <a href='http://www.kcls.org/databases/subject_categories.cfm#17'>magazines</a>
+                    </td>
+                    <td>
+                        <a href='http://www.kcls.org/databases/'>databases</a>
+                    </td>
+                    <td>
+                        <a href='http://www.kcls.org/answers/'>answers</a>
+                    </td>
+                </tr>
+               </table>
+           </div>
+           <div id='hp-ql-bottom'>
+            <a href='http://www.kcls.org/locations'>Locations:
+                Find a Library Near You!
+                <img src='[% ctx.media_prefix %]/images/arrow-right.png' /></a>
+
+           </div>
+    </div>
+    <div class="float-left">
+        <img src='[% ctx.media_prefix %]/images/hp-links-right.jpg' />
+    </div>
+    <div class="clear-both"></div>
+</div>
diff --git a/Open-ILS/web/templates/default/opac/parts/language_selector.tt2 b/Open-ILS/web/templates/default/opac/parts/language_selector.tt2
new file mode 100644 (file)
index 0000000..6bdfffe
--- /dev/null
@@ -0,0 +1,40 @@
+[%- name = name || "fi:language";
+    id = id || "language_selector";
+    values = values || CGI.param(name); -%]
+<select id='[% id %]' name='[% name %]'[%
+    multiple ? ' multiple="multiple"' : '';
+    size ? (' size="' _ size _ '"') : ''; %]>
+[%-
+# Language otions for languages that exist in the catalog.
+# This file should be updated on occasion.
+#
+# develooper=# select code,value from config.language_map m
+#   join metabib.rec_descriptor r on (r.item_lang = m.code) group by 1,2;
+
+# XXX I haven't internationalized these labels because this stuff shouldn't
+# be hardcoded like this forever.
+FOR lang IN [
+    {'code' => 'eng', 'label' => 'English'},
+    {'code' => 'spa', 'label' => 'Spanish'},
+    {'code' => 'fre', 'label' => 'French'},
+    {'code' => 'ger', 'label' => 'German'},
+    {'code' => 'ita', 'label' => 'Italian'},
+    {'code' => 'chi', 'label' => 'Chinese'},
+    {'code' => 'jpn', 'label' => 'Japanese'},
+    {'code' => 'kor', 'label' => 'Korean'},
+    {'code' => 'dut', 'label' => 'Dutch'},
+    {'code' => 'gre', 'label' => 'Greek, Modern (1453- )'},
+    {'code' => 'lat', 'label' => 'Latin'},
+    {'code' => 'vie', 'label' => 'Vietnamese'},
+    {'code' => 'rus', 'label' => 'Russian'},
+    {'code' => 'nor', 'label' => 'Norwegian'},
+    {'code' => 'wel', 'label' => 'Welsh'},
+    {'code' => 'pau', 'label' => 'Palauan'},
+    {'code' => 'swe', 'label' => 'Swedish'},
+    {'code' => 'nav', 'label' => 'Navajo'},
+    {'code' => 'und', 'label' => 'Undetermined'}
+];
+    |l(lang.code, lang.label) %]
+<option value='[_1]'[% values.grep('^' _ lang.code _ '$').size ? ' selected="selected"' : '' %]>[_2]</option>
+[%  END; END -%]
+</select>
diff --git a/Open-ILS/web/templates/default/opac/parts/login/form.tt2 b/Open-ILS/web/templates/default/opac/parts/login/form.tt2
new file mode 100644 (file)
index 0000000..c0624ae
--- /dev/null
@@ -0,0 +1,171 @@
+<!-- TODO: MOVE INTO SEPARATE FORGOT-PASSWORD PAGE 
+
+<div class="hide_me">
+       <div class='login_text color_1' style='padding: 4px; text-align: center;'>
+               <span>[% l("Login") %]</span>
+       </div>
+       <br/>
+</div>
+<div class="hide_me" id="forget_pw">
+    <h1>Password Reset</h1>
+       Username or Barcode<br />
+       <input type="text" id="forget_pw_user" /><br /><br />
+       Email Address on account<br />
+       <input type="text" id="forget_pw_email" /><br />
+    <a href="#">Submit</a> &nbsp;
+    <a href="#">Cancel</a>
+</div>
+<table id='change_pw_table' class='data_grid hide_me' style='margin-left: 20px;' width='95%'>
+       <thead>
+        <tr><td colspan='2' align='center'><b>[% l("Password") %]</b></td></tr>
+    </thead>
+    <tbody>
+        <tr>
+            <td colspan='2' style='padding:10px;'>
+                [% l("This appears to be the first time you have logged in.  You will need to change your password.") %]
+                [% l("The password must be at least 7 characters in length,
+ contain at least one letter (a-z/A-Z),
+ and contain at least one number.") %]
+            </td>
+        </tr>
+        <tr>
+            <td>[% l("Enter your current password") %]</td>
+            <td><input type='password' id='change_pw_current'/></td>
+        </tr>
+        <tr>
+            <td>[% l("Enter the new password") %]</td>
+            <td><input type='password' id='change_pw_1'/></td>
+        </tr>
+        <tr>
+            <td>[% l("Re-type the new password for verification") %]</td>
+            <td><input type='password' id='change_pw_2'/></td>
+        </tr>
+        <tr><td><br/></td><td/></tr>
+        <tr class='color_1'>
+            <td colspan='2' align='center'>
+                <span class='login_text' style='margin-right: 20px;'>
+                    <input type='submit' value='[% l("Update Password") %]'  id='change_pw_button'/>
+                </span>
+            </td>
+        </tr>
+    </tbody>
+</table>
+
+
+<span id='pw_no_match' class='hide_me'>[% l("Passwords do not match") %]</span>
+<span id='pw_update_successful' class='hide_me'>[% l("Password successfully updated") %]</span>
+<span id='pw_not_strong' class='hide_me'>
+    [% l("The password provided is not strong enough.") %]
+    [% l("The password must be at least 7 characters in length, contain at least one letter (a-z/A-Z), and contain at least one number.") %]
+</span>
+
+ ^== TODO: MOVE INTO SEPARATE FORGOT-PASSWORD PAGE  -->
+
+[% IF ctx.login_failed_event %]
+<div id='login-failed-message'>
+[%
+    IF ctx.login_failed_event.textcode == 'PATRON_CARD_INACTIVE';
+        l("The barcode used to login is marked as inactive.  Please contact your local library.");
+    ELSIF ctx.login_failed_event.textcode == 'PATRON_INACTIVE';
+        l("This account has been deactivated.  Please contact your local library.");
+    ELSE;
+        l("Login failed. The username or password provided was not valid.  
+            Ensure Caps-Lock is off and try again or contact your local library.");
+    END;
+%]
+</div>
+[% END %]
+
+<div>
+    <div style="height:20px;"></div>
+    <form method='POST'>
+        <table cellpadding="0" cellspacing="0" border="0">
+            <tr>
+                <td valign="top" width="676" class="login_boxes left_brain">
+                    <table cellpadding="0" cellspacing="0" border="0"
+                        width="100%">
+                        <tr>
+                               <td colspan="2" style="padding-bottom: 10px;">
+                                <h1>[% l('Log in to Your Account') %]</h1>
+                                [% l('Please enter the following information:') %]
+                                <br /><br />
+                            </td>
+                        </tr>
+                        <tr>
+                            <td width="42%" class="lbl1">
+                                [% l('Library Card Number or Username') %]
+                                <br />
+                                <span class="lbl2">
+                                    [% l('Please include leading zeros and no spaces.') %]
+                                    <br/>
+                                    [% l('Example: 0026626051') %]
+                                </span>
+                                <br /><br />
+                            </td>
+                            <td width="58%" valign="top">
+                                <div class="input_bg">
+                                    <input type="text" id="username_field" name="username"/>
+                                </div>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td colspan="2">
+                                <div style="height:15px;"></div>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td valign="top" class="lbl1">
+                                [% l('PIN Number or Password') %]<br />
+                                <span class="lbl2">
+                                    [% | l('<br/>', '<br/>') %]
+                                       If this is your first time logging in, please enter [_1] the last 4 digits of your phone number. [_2] Example: 0926
+                                    [% END %]
+                                </span>
+                            </td>
+                            <td valign="top">
+                                <div class="input_bg">
+                                    <input name="password" type="password" />
+                                </div>
+                                <div style="padding-top:7px;">
+                                    [%
+                                        # If no redirect is offered or it's leading us back to the 
+                                        # login form, redirect the user to My Account
+                                        redirect = CGI.param('redirect_to') || ctx.referer;
+                                        IF !redirect OR redirect.match(ctx.path_info _ '$');
+                                            redirect = CGI.url('-full' => 1) _ '/opac/myopac/main';
+                                        END;
+                                        redirect = redirect  | replace('^http:', 'https:');
+                                    %]
+                                    <input type='hidden' name='redirect_to' value='[% redirect %]'/>
+                                    <input type="checkbox" name="persist" /> [% l('Remember Me?') %]
+                                </div>
+                                <div style="padding-top:14px;">
+                                    <input type='image' alt="[% l('Log in') %]" src="[% ctx.media_prefix %]/images/login-btn2.png" />
+                                    <!-- TODO
+                                    <a href="reset_password"
+                                        style="position:relative;top:-13px;left:2px;font-size:10px;">Forgot your PIN?</a>
+                                    -->
+                                </div>
+                               </td>
+                        </tr>
+                    </table>
+                    <br /><br />
+                </td>
+                   <td><div style="width:10px;"></div></td>
+                <td class="login_boxes right_brain" align="center" valign="top" width="291">
+
+                    <a href="http://www.kcls.org/about/contact/"><img 
+                        src="[% ctx.media_prefix %]/images/questions.png" alt="[% l('Questions?') %]" style="margin-top:29px;" /></a>
+
+                       <div style="width:182px;color:black;padding:5px 25px;">
+                        [% l('Visit our FAQs section for answers to common questions about how to use your account.') %]
+                       </div>
+
+                    <a href="http://www.kcls.org/usingthelibrary/catalog_help/index.cfm#FAQs"><img
+                        alt="[% l('FAQs') %]" src="[% ctx.media_prefix %]/images/faqs-btn.png" style="margin-top:13px;" /></a>
+                   </td>
+            </tr>
+        </table>
+    </form>
+    <div class="clear-both"></div>
+</div>
diff --git a/Open-ILS/web/templates/default/opac/parts/marc_misc.tt2 b/Open-ILS/web/templates/default/opac/parts/marc_misc.tt2
new file mode 100644 (file)
index 0000000..8f56196
--- /dev/null
@@ -0,0 +1,33 @@
+[% 
+    # Extract MARC fields from XML
+    #   get_marc_attrs( { marc_xml => doc } )
+    BLOCK get_marc_attrs;
+        xml = args.marc_xml;
+        args.isbn = xml.findnodes('//*[@tag="020"]/*[@code="a"]').shift.textContent;
+        args.upc = xml.findnodes('//*[@tag="024"]/*[@code="a"]').textContent;
+        args.issn = xml.findnodes('//*[@tag="022"]/*[@code="a"]').textContent;
+        args.title = xml.findnodes('//*[@tag="245"]/*[@code="a"]').textContent;
+        args.author = xml.findnodes('//*[@tag="100"]/*[@code="a"]').textContent;
+        args.publisher = xml.findnodes('//*[@tag="260"]/*[@code="b"]').textContent;
+        args.pubdate = xml.findnodes('//*[@tag="260"]/*[@code="c"]').textContent;
+        args.edition = xml.findnodes('//*[@tag="250"]/*[@code="a"]').textContent ||
+            xml.findnodes('//*[@tag="534"]/*[@code="b"]').textContent ||
+            xml.findnodes('//*[@tag="775"]/*[@code="b"]').textContent;
+        phys = xml.findnodes(
+            '//*[@tag="300"]/*[@code="a" or @code="b" or @code="c" or @code="e"]'
+        );
+        phys_content = [];
+        FOR p IN phys; phys_content.push(p.textContent); END;
+        args.phys_desc = phys_content.join("");
+
+        # clean up the ISBN
+        args.isbn_clean = args.isbn.replace('\ .*', '');
+
+        # KCLS-specific stuff; needs to change
+        args.mattype = xml.findnodes('//*[@tag="998"]/*[@code="d"]').textContent;
+        args.kcls_cn = xml.findnodes('//*[@tag="092" or @tag="099"]/*').textContent;
+        mattype = attrs.mattype;
+        args.format = ctx.find_citm(mattype).value;
+        args.format_icon = icon_by_mattype.$mattype;
+    END;
+%]
diff --git a/Open-ILS/web/templates/default/opac/parts/myopac/base.tt2 b/Open-ILS/web/templates/default/opac/parts/myopac/base.tt2
new file mode 100644 (file)
index 0000000..d41caa1
--- /dev/null
@@ -0,0 +1,34 @@
+[% myopac_pages = [
+        {url => "main", name => "Account Summary"},
+        {url => "circs", name => "Items Checked Out"},
+        {url => "holds", name => "Holds"},
+        {url => "prefs", name => "Account Preferences"},
+        {url => "lists", name => "My Lists"}
+    ];
+    skin_root = "../"
+%]
+    [% INCLUDE "default/opac/parts/topnav.tt2" %]
+    <div id="search-wrapper">
+        [% INCLUDE "default/opac/parts/utils.tt2" %]
+        [% INCLUDE "default/opac/parts/searchbar.tt2" %]
+    </div>
+    <div id="content-wrapper">
+        <div id="myopac_tabs">
+            <div id="acct_tabs">
+                [%- FOREACH page IN myopac_pages;
+                    IF page.url == myopac_page;
+                        cls_which = "on";
+                        ctx.page_title = "Your Account - " _ page.name;
+                    ELSE;
+                        cls_which = "off";
+                    END -%]
+                <a href="[% page.url %]"
+                    class="acct-[% page.url; '-'; cls_which %] acct-tab"></a>
+                [% END %]
+            </div>
+        </div>
+        <div id="main-content">
+            [% content %]
+            <div class="common-full-pad"></div>
+        </div>
+    </div>
diff --git a/Open-ILS/web/templates/default/opac/parts/org_selector.tt2 b/Open-ILS/web/templates/default/opac/parts/org_selector.tt2
new file mode 100644 (file)
index 0000000..aa99e91
--- /dev/null
@@ -0,0 +1,23 @@
+[%
+    BLOCK build_org_selector_options; %]
+        <option value='[% walker.id %]' [% IF walker.id == value %] selected='selected' [% END %]>
+            [%
+                pad = walker.ou_type.depth * 2;
+                FOR idx IN [0..pad]; '&nbsp;'; END;
+                walker.name;
+            %]
+        </option>
+        [%  FOR child IN walker.children;
+            PROCESS build_org_selector_options walker=child value=value;
+        END;
+    END;
+
+    # XXX TODO probably put this BLOCK somewhere else so it can be used widely.
+    # Org Unit Selector Widget :
+    #   PROCESS build_org_selector id='selector-id' name='selector-name'
+    BLOCK build_org_selector;
+%]
+    <select id='[% id %]' name='[% name %]'>
+    [% PROCESS build_org_selector_options walker=(org_unit || ctx.aou_tree) value=value %]
+    </select>
+[%  END %]
diff --git a/Open-ILS/web/templates/default/opac/parts/place_hold.tt2 b/Open-ILS/web/templates/default/opac/parts/place_hold.tt2
new file mode 100644 (file)
index 0000000..f3d8ef3
--- /dev/null
@@ -0,0 +1,339 @@
+[%  PROCESS "default/opac/parts/marc_misc.tt2";
+    attrs = {marc_xml => ctx.marc_xml};
+    PROCESS get_marc_attrs args=attrs;
+%]
+<div>
+    <div id='xulholds_box' class='hide_me canvas' style='margin-top: 6px;'>
+        <!-- XXX TODO staff will need this to work ("advanced" hold placement)
+        later -->
+        <center>
+            <table class='data_grid' style='margin-top: 20px;'>
+                <tbody>
+                    <tr>
+                        <td>[% l("Enter recipient barcode") %]:</td>
+                        <td>
+                            <input type='text' id='xul_recipient_barcode' />
+                        </td>
+                        <td>
+                            <input type='submit' value='[% l("Submit") %]'
+                                id='xul_recipient_barcode_submit' />
+                        </td>
+                        <td>
+                            <input type='submit' value='[% l("Cancel") %]' />
+                        </td>
+                        <td>
+                            <input type='submit'
+                                value='[% l("Place hold for my account") %]'
+                                id='xul_recipient_me' />
+                        </td>
+                    </tr>
+                </tbody>
+            </table>
+        </center>
+    </div>
+    <div id='check_holds_box' class='hide_me canvas' 
+        style='margin-top: 6px; width: 100%; text-align: center'>
+        <br/><br/><br/>
+        <b>[% l("Checking for possibility of hold fulfillment...") %]</b>
+    </div>
+    <div id='holds_box' class='canvas' style='margin-top: 6px;'>
+        [% IF ctx.hold_success %]
+        <div><big><strong>[% l("Hold was successfully placed"); %]</strong></big></div>
+        [% ELSIF ctx.hold_failed %]
+        <div><big><strong>[% l("Hold was not successfully placed"); %]</strong></big></div>
+            [% IF ctx.hold_failed_event %]
+        <div>
+            <strong>[% l('Problem:') %]</strong>
+            <span title="[% ctx.hold_failed_event.textcode %]">
+                <em>[% ctx.hold_failed_event.desc ||
+                        ctx.hold_failed_event.payload.fail_part ||
+                        ctx.hold_failed_event.textcode %]</em>
+            </span>
+        </div>
+            [% END;
+        ELSE %]
+        <form method="POST">
+            <br/>
+            <input type="hidden" name="hold_target"
+                value="[% CGI.param('hold_target') | html %]" />
+            <input type="hidden" name="hold_type"
+                value="[% CGI.param('hold_type') | html %]" />
+            <input type="hidden" name="redirect_to"
+                value="[% ctx.referer | replace('^http:', 'https:') | html %]" />
+            <h1>Place Hold</h1>
+            <p>
+                [% | l(attrs.title, ctx.find_aou(ctx.default_pickup_lib).name) %]
+                You would like to place a hold on <strong><q>[_1]</q></strong> to be picked up at [_2].
+                If this is correct, press <strong>SUBMIT</strong>.
+                [% END %]
+            </p>
+            <p>
+                [% l('If you would like to change the library pick up location, select from the location dropdown menu.') %]
+                <br class="clear-both" />
+                [% PROCESS "default/opac/parts/org_selector.tt2";
+                    PROCESS build_org_selector name='pickup_lib' value=ctx.default_pickup_lib %]
+            </p>
+            <p>
+                [% |l %]If you use the Traveling Library Center (TLC) and ABC Express
+                services, please select "Outreach" to have the item delivered
+                during your scheduled visit.[% END %]
+            </p>
+            <input type="image" name="submit" value="submit" title="[% l('Submit') %]"
+                alt="[% l('Submit') %]" src="[% ctx.media_prefix %]/images/btnSubmit.png" />
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+            <a href="javascript:history.go(-1);" id="holds_cancel"><img
+                alt="[% l('Cancel') %]" src="[% ctx.media_prefix %]/images/btnCancel.png" /></a>
+        </form>
+        <br /><br />
+        <p>
+            [% |l %]* If you need your item today, and it is checked in at your
+            library, please place your hold and then call your library to set it
+            aside. Placing a hold without calling the library will increase your
+            wait time.[% END %]
+            <br /><a href="#">[% l('Library phone numbers.') %]</a>
+        </p>
+        <p>
+            [% |l %]* For best possible service, we recommend keeping 
+            a printed copy of your most recent holds list.[% END %]
+        </p>
+        [% END %] <!-- ctx.hold_success -->
+        <table width='90%' border="1" class="hide_me">
+            <tbody>
+                <tr>
+                    <td class='holds_cell color_1' 
+                        align='center' colspan='2'>[% l("Create / Edit a Hold") %]</td>
+                </tr>
+                <tr>
+                    <td class='holds_cell'>[% l("Recipient") %]:</td>
+                    <td class='holds_cell' id='holds_recipient'> </td>
+                </tr>
+                <tr>
+                    <td class='holds_cell'>[% l("Title:") %]</td>
+                    <!-- <td class='holds_cell' id='holds_title'> </td> -->
+                </tr>
+                <tr>
+                    <td class='holds_cell'>[% l("Author") %]</td>
+                    <td class='holds_cell' id='holds_author'> </td>
+                </tr>
+                <tr>
+                    <td class='holds_cell'>[% l("Format") %]</td>
+                    <td class='holds_cell' id='holds_format'> </td>
+                </tr>
+                <tr id='hold_physical_desc_row'>
+                    <td class='holds_cell'>[% l("Physical Description:") %]</td>
+                    <td class='holds_cell' id='holds_physical_desc'> </td>
+                </tr>
+
+                <tr class='hide_me' id='holds_cn_row'>
+                    <td class='holds_cell'>[% l("Call Number:") %]</td>
+                    <td class='holds_cell'><b id='holds_cn'/> </td>
+                </tr>
+
+                <tr class='hide_me' id='holds_copy_row'>
+                    <td class='holds_cell'>[% l("Copy Barcode:") %]</td>
+                    <td class='holds_cell'><b id='holds_copy'/> </td>
+                </tr>
+
+                <tr class='hide_me' id='holds_type_row'>
+                    <td class='holds_cell'>[% l("Hold Type:") %]</td>
+                    <td class='holds_cell hide_me' id='holds_is_cn'>
+                        <b>[% l("Volume Hold") %]</b>
+                    </td>
+                    <td class='holds_cell hide_me' id='holds_is_copy'>
+                        <b>[% l("Copy Hold") %]</b>
+                    </td>
+                </tr>
+                <tr>
+                    <td class='holds_cell'>[% l("Contact telephone number") %]:</td>
+                    <td class='holds_cell'>
+                        <input id='holds_phone' size='13' maxlength='12'/>
+                        <span style='margin-left: 4px; font-size: 7pt;'>
+                            [% l("(XXX-YYY-ZZZZ)") %]
+                        </span>
+                    </td>
+                </tr>
+                <tr>
+                    <td class='holds_cell'>[% l("Enable phone notifications for this hold?") %]</td>
+                    <td class='holds_cell'>
+                        <input type='checkbox' id='holds_enable_phone'
+                            checked='checked' />
+                    </td>
+                </tr>
+                <tr>
+                    <td class='holds_cell'>[% l("Contact email address") %]:</td>
+                    <td class='holds_cell' id='holds_email'> 
+                        <span class='hide_me' id='holds.no_email'>
+                           ([% l("Patron has no configured email address") %])<br/>
+                           ([% l("See") %] <a class='classic_link' id='holds.no_email.my_account'>[% l("My Account") %]</a> [% l("for setting your email address") %])
+                        </span>
+                        <span class='hide_me' id='holds.no_email.xul'>
+                           [% l("(Patron has no configured email address)") %] 
+                        </span>
+                    </td>
+                </tr>
+                <tr>
+                    <td class='holds_cell'>[% l("Enable email notifications for this hold?") %]</td>
+                    <td class='holds_cell'>
+                        <input type='checkbox' id='holds_enable_email'
+                            checked='checked'/>
+                    </td>
+                </tr>
+                <!--
+                <tr id='holds_depth_selector_row' class='hide_me'>
+                    <td class='holds_cell'>Hold Range</td>
+                    <td class='holds_cell'>
+                        <select id='holds_depth_selector'></select>
+                    </td>
+                </tr>
+                -->
+                <tr>
+                    <td class='holds_cell'>[% l("Pickup location") %]</td>
+                    <td class='holds_cell'>
+                        <!-- <select id='holds_org_selector'> </select> -->
+                    </td>
+                </tr>
+
+                <tr>
+                    <td class='holds_cell'>[% l("Expiration date") %]</td>
+                    <td class='holds_cell'>
+                        <input size='10' maxlength='10'
+                         id='holds_expire_time' />
+                    </td>
+                </tr>
+
+                <tr>
+                    <td class='holds_cell'>
+                        [% l("Suspend this hold") %]
+                        <a class='classic_link'
+                            href='#'>[% l("(Help)") %]</a>
+                        </td>
+                    <td class='holds_cell'>
+                        <input type='checkbox' id='holds_frozen_chkbox' /> 
+                    </td>
+                </tr>
+                <tr id='hold_frozen_thaw_row' class='hide_me'>
+                    <td class='holds_cell'>
+                        <!-- XXX TODO there used to be script here dealing with
+                        frozen holds -->
+                        [% l("Automatically activate hold on:") %]
+                    </td>
+                    <td class='holds_cell'>
+                        <input size='10' maxlength='10'
+                            id='holds_frozen_thaw_input' />
+                    </td>
+                </tr>
+
+                <tr id='holds_alt_formats_row_extras' class='hide_me'>
+                    <td colspan='2' align='center'>
+                        <div style='padding: 8px;'>
+                            <a class='classic_link' href='#'
+                                style='padding: 5px;'>[% l("Advanced Hold Options") %]</a>
+                        </div>
+                    </td>
+                </tr>
+
+                <tr id='holds_alt_formats_row' class='hide_me'>
+
+                    <td class='holds_cell'>
+                        <div style='margin-bottom: 5px;'>
+                            <span>[% l("Acceptable Alternative Formats:") %] </span>
+                            <span><a class='classic_link red' href='#'>[% l("(Help)") %]</a></span>
+                        </div>
+                        <div>[% l("(control-click to select multiple formats)") %]</div>
+                    </td>
+
+                    <td class='holds_cell'>
+                        <select id='hold_alt_form_selector' multiple='multiple' style='width: 14em;'>
+                            <option value='at'    class='hide_me'>[% l("Books") %]</option>
+                            <option value='at-d' class='hide_me'>[% l("Large Print Books") %]</option>
+                            <option value='i'        class='hide_me'>[% l("Audiobooks") %]</option>
+                            <option value='g'        class='hide_me'>[% l("Video Recordings") %]</option>
+                            <option value='j'        class='hide_me'>[% l("Music") %]</option>
+                        </select>
+                    </td>
+                </tr>
+                <tr>
+                    <td class='holds_cell' align='center' colspan='2'>
+                        <!-- <button id='holds_submit'>[% l("Place Hold") %]</button> -->
+                        <button class='hide_me' id='holds_update'>[% l("Update Hold") %]</button>
+                        <span style='padding: 20px;'> </span>
+                        <!-- <button id='holds_cancel'>[% l("Cancel") %]</button> -->
+                    </td>
+                </tr>
+            </tbody>
+        </table>
+        <div class='hide_me' id='holds_success'>[% l("Hold was successfully placed") %]</div>
+        <div class='hide_me' id='holds_failure'>[% l("Hold was not successfully placed") %]</div>
+        <span class='hide_me' id='holds_bad_phone'>
+            [% l("The phone number does not have the correct format. The expected format is XXX-YYY-ZZZZ") %]
+        </span>
+        <span class='hide_me' id='hold_not_allowed'>
+            [% |l %]No items were found that could fulfill the requested holds.  
+                It's possible that choosing a different format will result in a successful hold.  
+                It is also possible that you have exceeded the number of allowable holds.  
+                For further information, please consult your local librarian.[% END %]
+        </span>
+    </div>
+    <div id="anonListTable" class="hide_me" style="margin-top: 6px;">
+        <select id="holdsCacheSel" class="hide_me"></select><br />
+        <a href="#">Place hold on selected</a><br />
+        <a href="#">Remove selected</a>
+        
+        <table id="temp_list_holds" cellpadding='0' cellspacing='0' border='0'
+            style="margin-top:10px;">
+            <tr>
+                <td width="1%" style="padding-left:10px;">
+                    <input type='checkbox' title='Select All'
+                        id='anon_selector' />
+                </td>
+                <td width="1%">
+                </td>
+                <td width="98%" style="padding-left:40px;">
+                    <strong>Title</strong>
+                </td>
+            </tr>
+        </table>
+        <table width='100%' style="margin-left:7px;margin-bottom:10px;">
+            <thead>
+                <tr><td width='20'></td><td width='30'></td><td></td></tr>
+            </thead>
+            <tbody id="anonListParent">
+                <tr id="anonListTemp">
+                  <td><input type='checkbox' name='anon_selector' /></td>
+                  <td name="curr_row"></td>
+                  <td name="title"></td>
+                </tr>
+            </tbody>
+        </table>
+        <a href="#">Back to search results</a>
+    </div>
+
+    <span class='hide_me' id='format_words'>
+        <span name='at'>[% l("Books") %]</span>
+        <span name='at-d'>[% l("Large Print Books") %]</span>
+        <span name='i'>[% l("Audiobooks") %]</span>
+        <span name='g'>[% l("Video Recordings") %]</span>
+        <span name='j'>[% l("Music") %]</span>
+        <span name='m'>[% l("Electronic Resources") %]</span>
+    </span>
+
+    <span class='hide_me' id='holds_explain_adv'>
+        [% |l %]If you wish to broaden the scope of your hold to include other versions of this title, 
+        select the formats that would be acceptable.  The first available copy will be sent to you.[% END %]
+    </span>
+
+    <span class='hide_me' id='holds_pick_good_org'>[% l("Please select a physical location where your hold can be delivered.") %]</span>
+    <span class='hide_me' id='hold_dup_exists'>[% l("A hold already exists on the requested item.") %]</span>
+    <span class='hide_me' id='hold_dup_exists_override'>[% l("A hold already exists on the requested item. Would you like to create the hold anyway?") %]</span>
+
+    <span id='hold_failed_patron_barred' class='hide_me'>
+        [% |l %]PATRON BARRED. Please see any notes in the "Staff Notes" section of your 
+        "My Account" page or contact your local library.[% END %]
+    </span>
+
+    <span id='invalid_hold' class='hide_me'>
+        [% |l %]This hold is no longer valid. It's likely that the target for the hold was 
+        deleted from the system.  Please cancel this hold and place a new one.[% END %]
+    </span>
+    <span id='holds_invalid_recipient' class='hide_me'>[% l("The patron barcode entered as the hold recipient is invalid.") %]</span>
+</div>
diff --git a/Open-ILS/web/templates/default/opac/parts/qtype_selector.tt2 b/Open-ILS/web/templates/default/opac/parts/qtype_selector.tt2
new file mode 100644 (file)
index 0000000..8c31f0d
--- /dev/null
@@ -0,0 +1,16 @@
+[%  query_types = [
+    {value => "keyword", label => l("Keyword")},
+    {value => "title", label => l("Title")},
+    {value => "author", label => l("Author")},
+    {value => "subject", label => l("Subject")},
+    {value => "series", label => l("Series")},
+    {value => "id|bibcn", label => l("Call Number")}
+] %]
+<select name="qtype">
+    [%  query_type = query_type || CGI.param('qtype');
+        FOR qt IN query_types -%]
+    <option value='[% qt.value %]'[%
+        query_type == qt.value ? ' selected="selected"' : ''
+    %]>[% qt.label %]</option>
+    [% END -%]
+</select>
diff --git a/Open-ILS/web/templates/default/opac/parts/record/body.tt2 b/Open-ILS/web/templates/default/opac/parts/record/body.tt2
new file mode 100644 (file)
index 0000000..93d2bf7
--- /dev/null
@@ -0,0 +1,121 @@
+<!-- ****************** page_rdetail.xml ***************************** -->
+[%  record = ctx.record;
+    attrs = {marc_xml => ctx.marc_xml};
+    PROCESS "default/opac/parts/marc_misc.tt2";
+    PROCESS get_marc_attrs args=attrs %]
+<div id='canvas_main' class='canvas'>
+    <div id="rdetail_header" class="hide_me">[%#
+        XXX Does it make sense for now to even have this section?  Why
+        should the record detail page be aware of the ongoing search?
+        The user can use the back button to go back to their search results
+        like on any other website. %]
+        <div style="float:left;">
+            Search Results&nbsp;&nbsp;&nbsp;
+            <span id="rdetail_result_count" class="hide_me">
+                Showing Item <strong id='np_offset'></strong>
+                &nbsp;of&nbsp;<strong id='np_count'></strong>
+            </span>
+        </div>
+        <div id="rdetail_result_nav">
+            <span class="hide_me">
+                <a class='np_nav_link classic_link' id='np_start'
+                    href='#'
+                    title="[% l("First results page") %]">[% l("Start") %]</a>
+                </span>
+                <a class='np_nav_link classic_link hide_me' id='np_prev'
+                    href='#'
+                    title='[% l("Previous page") %]'><span
+                        class="nav_arrow_fix">&#9668;</span> Previous</a>
+                <span style="padding:0px 10px;"> </span>
+                <a class='np_nav_link classic_link hide_me' id='np_next'
+                    href='#'
+                    title='[% l("Next page") %]'>Next <span
+                        class="nav_arrow_fix">&#9658;</span></a>
+                <span class="hide_me"><a class='np_nav_link classic_link'
+                    id='np_end' href='#'
+                    title="[% l("Last results page") %]">[% l("End") %]</a></span>
+        </div>
+        <div class="clear-both"></div>
+    </div>
+
+    <table width='100%' id='np_table' border='0' class="hide_me">
+        <tbody>
+            <tr class='color_4'>
+                <td style='vertical-align: top;' align="center">
+                    <span style="float:left"><a href="javascript:;"
+                        onclick="history.go(-1);">&laquo; Back</a></span>
+                    <span></span>
+                </td>
+            </tr>
+        </tbody>
+    </table>
+
+    <table style='' class='rdetail_header color_1 hide_me' width='100%'
+        border="0" cellspacing="0" cellpadding="0">
+        <tbody>
+            <tr>
+                <td width='33%' align='left' class="hide_me">
+                    <span>[% l("Record Summary") %]</span>
+                </td>
+                <td align='right' style='padding-right: 7px;' width='33%'>
+                    <span id='rdetail_exp_refworks_span' class='hide_me'
+                        style='padding-right: 7px;'>
+                        <a id='rdetail_exp_refworks'>[% l("Export to RefWorks") %]</a>
+                    </span>
+                    <span style='padding-right: 7px;' class='hide_me'
+                        id='rdetail_more_actions'>
+                        <select id='rdetail_more_actions_selector'
+                            style='max-width: 11em;' class="hide_me">
+                            <option value='start'>
+                                [% l("More Actions...") %]
+                            </option>
+                            <option disabled='disabled'>
+                                --------------
+                            </option>
+                            <option disabled='disabled'>
+                                [% l("Add to bookbag") %]
+                            </option>
+                            <option disabled='disabled'>
+                                --------------
+                            </option>
+                            <option value='new_bookbag'>
+                                [% l("Create a new bookbag") %]
+                            </option>
+                        </select>
+                    </span>
+                </td>
+            </tr>
+        </tbody>
+    </table>
+
+    <div style='font-weight: bold; padding: 5px; margin: 5px; width: 100%;'
+        class='hide_me color_4' id='rdetail_deleted_exp'>
+        [% l("This record has been deleted from the database.  We recommend that you remove this title from any bookbags it may have been added to.") %]
+    </div>
+
+    [% INCLUDE "default/opac/parts/record/summary.tt2" %]
+    <br />
+    <div style="width:100%;" class="hide_me">
+        <div style="float:right;" class="hide_me" id="lib_info_more">
+            <button>More...</button>
+        </div>
+        <div style="float:right;" class="hide_me" id="lib_info_less">
+            <button>...Less</button>
+        </div>
+    </div>
+    [% INCLUDE "default/opac/parts/record/extras.tt2" %]
+
+    <div class='hide_me' id='rdetail_bb_none'>
+        [% l("(none)") %]
+    </div>
+    <div class='hide_me' id='rdetail_bb_item_success'>
+        [% l("Item successfully added to bookbag") %]
+    </div>
+    <div class='hide_me' id='rdetail_bb_new'>
+        [% l("Enter the name of the new bookbag") %]
+    </div>
+    <div class='hide_me' id='rdetail_bb_success'>
+        [% l("Bookbag successfully created") %]
+    </div>
+</div>
+<!-- ****************** end; page_rdetail.xml ***************************** -->
diff --git a/Open-ILS/web/templates/default/opac/parts/record/cn_details.tt2 b/Open-ILS/web/templates/default/opac/parts/record/cn_details.tt2
new file mode 100644 (file)
index 0000000..2865026
--- /dev/null
@@ -0,0 +1,91 @@
+<table class="hide_me">
+    <tbody>
+        <tr class='opac-auto-009' id='rdetail_volume_details_row' templateRow='1'>
+            <td colspan='10'>
+                <div style='text-align: center; margin-top: 6px; margin-bottom: 6px'>
+                    <a name='print' href='#' class='classic_link'>[% l("print these details") %]</a>
+                    <table class='data_grid data_grid_center' style='width: 100%'>
+                        <tbody name='copies_tbody' class='copy_details_table' width='100%'>
+
+                                <!-- XXX keeping for now for reference...
+                                <td>
+                                    <span name='barcode'> </span>
+                                    <a class='hide_me classic_link copy_more_info'
+                                        name='details_link'>[% l("more info...") %]</a>
+                                    <a class='hide_me classic_link copy_more_info'
+                                        name='less_details_link'>[% l("less info") %]</a>
+                                    <a class='hide_me classic_link copy_more_info'
+                                        name='copy_hold_link' href='#'>[% l("place hold") %]</a>
+                                </td>
+                                <td name='status'> </td>
+                                <td name='location'> </td>
+                                <td name='age_protect_value' class='hide_me'>[% l("- Disabled -") %]</td>
+                                <td name='create_date_value' class='hide_me'> </td>
+                                <td name='copy_holdable_td' class='hide_me'>
+                                    <span name='copy_is_holdable'> </span>
+                                </td>
+                                <td name='copy_due_date_td' class='hide_me'>
+                                    <span name='copy_due_date'> </span>
+                                </td>
+                            </tr>
+                                -->
+
+                            <tr name='copy_extras_row' class='hide_me'>
+                                <td colspan='10'>
+                                    <table width='100%' class='data_grid'>
+                                        <tbody name='extras_tbody'>
+                                            <tr name='extras_row' class='hide_me'>
+                                                <td name='type' width='20%'>
+                                                    <span name='note' class='hide_me'>
+                                                        <b>[% l("Copy Note") %]</b>
+                                                    </span>
+                                                    <span name='cat' class='hide_me'>
+                                                        <b>[% l("Copy Category") %]</b>
+                                                    </span>
+                                                </td>
+                                                <td>
+                                                    <span name='key'> </span> : <span name='value'> </span>
+                                                </td>
+                                            </tr>
+                                        </tbody>
+                                    </table>
+                                </td>
+                            </tr>
+                        </tbody>
+                    </table>
+                </div>
+            </td>
+        </tr>
+    </tbody>
+</table>
+
+<span class='hide_me' id='rdetail.yes'>[% l("Yes") %]</span>
+<span class='hide_me' id='rdetail.no'>[% l("No") %]</span>
+
+<div id='rdetail_print_details' class='hide_me'>
+    <div style='text-align: center; padding: 20px; width: 100%'>
+        <div style='width:100%; border: 2px solid #E0F0E0; margin-bottom: 20px;'>
+            <input type='submit' value='[% l("Print Page") %]' onclick='window.print();' />
+        </div>
+        <div name='body'>
+            <table>
+                <tbody name='tbody'>
+                    <tr><td>[% l("Library") %]</td><td colspan='2' name='lib'></td></tr>
+                    <tr><td>[% l("Title") %]</td><td colspan='2' name='title'></td></tr>
+                    <tr><td>[% l("Author") %]</td><td colspan='2' name='author'></td></tr>
+                    <tr><td>[% l("Edition") %]</td><td colspan='2' name='edition'></td></tr>
+                    <tr><td>[% l("Publication Date") %]</td><td colspan='2' name='pubdate'></td></tr>
+                    <tr><td>[% l("Publisher") %]</td><td colspan='2' name='publisher'></td></tr>
+                    <tr><td>[% l("Physical Description") %]</td><td colspan='2' name='phys'></td></tr>
+                    <tr>
+                        <td colspan='3' class='opac-auto-004'> </td>
+                    </tr>
+                    <tr name='cnrow'>
+                        <td><b>[% l("Call Number") %]</b></td>
+                        <td><b colspan='2' name='cn'></b></td>
+                    </tr>
+                </tbody>
+            </table>
+        </div>
+    </div>
+</div>
diff --git a/Open-ILS/web/templates/default/opac/parts/record/copyinfo.tt2 b/Open-ILS/web/templates/default/opac/parts/record/copyinfo.tt2
new file mode 100644 (file)
index 0000000..9d4673f
--- /dev/null
@@ -0,0 +1,68 @@
+<!-- ****************** rdetail_copyinfo.xml ***************************** -->
+<div id='rdetail_copy_info_div' class='rdetail_extras_div hide_me'>
+    <div style='width: 100%; text-align: center; padding-bottom: 5px;'>
+        <span>
+            <a href='javascript:void(0);' id='copy_info_local_link' 
+                class='rdetail_copy_nav_link hide_me classic_link'><b>[% l("View Copy Information for this location only") %]</b></a>
+        </span>
+        <span width=''>
+            <a href='javascript:void(0);' id='copy_info_all_link' 
+                class='rdetail_copy_nav_link classic_link'><b>[% l("View copy information for all libraries") %]</b></a>
+        </span>
+    </div>
+    <table id='rdetail_copy_info_table' class='data_grid'>
+        <thead>
+            <tr>
+                <td class='rdetail_copy_info_header_cell'>[% l("Library") %]</td>
+                <td class='rdetail_copy_info_header_cell'>[% l("Callnumber") %]</td>
+                <td name='rdetail_copylocation_header' class='rdetail_copy_info_header_cell hide_me'>
+                    [% l("Copy Location") %]
+                </td>
+                <td class='rdetail_copy_info_header_cell'>[% l("Actions") %]</td>
+                <td nowrap='nowrap' class='rdetail_copy_info_header_cell' id='rdetail_copy_info_status'> 
+                    <div name='rdetail_status_cell'> </div>
+                </td>
+            </tr>
+        </thead>
+        <tbody id='rdetail_copy_info_tbody'>
+            <tr id='rdetail_copy_info_row' class='hide_me'>
+                <td name='rdetail_library_cell'>
+                    <a name='lib_print_link' class='hide_me classic_link'
+                        style='font-size: 8pt; padding-left: 20px;'>[% l("Print Call Numbers for this library") %]</a>
+                </td>
+                <td name='rdetail_callnumber_cell'> </td>
+                <td class="hide_me" name='rdetail_copylocation_cell'> </td>
+                <td name='rdetail_actions_cell'> 
+                    <div style='padding-bottom: 1px;'>
+                        <a style='font-size: 8pt;'
+                            name='details' class='hide_me classic_link'>[% l("Copy Details") %]</a>
+                    </div>
+                    <div style='margin-top: 2px;'>
+                        <a name='browse' style='font-size: 8pt;'
+                            class='hide_me classic_link'>[% l("Browse Call Numbers") %]</a>
+                    </div>
+                    <div style='margin-top: 2px;' name='hold_div' class='hide_me'>
+                        <a name='hold' style='font-size: 8pt;' href='javascript:void(0);'
+                            class='classic_link'>[% l("Place Hold") %]</a>
+                    </div>
+                </td>
+                <td nowrap='nowrap' class='rdetail_copy_count_cell vertical' 
+                    name='rdetail_copy_count_cell'>
+                </td>
+            </tr>
+            <tr id='rdetail_copy_info_loading'>
+                <td>
+                    [% l("Loading copy information...") %]
+                </td>
+            </tr>
+        </tbody>
+    </table>
+    <!-- <table class='hide_me'>
+        <tbody>
+        <tr class='opac-auto-009' id='rdetail_volume_details_row'><td colspan='10'></td></tr>
+        </tbody>
+    </table> -->
+    <br/><br/>
+    <div id='rdetail_copy_info_none' class='hide_me'>[% l(" * There are no copies in this location") %]</div>
+</div> <!-- copy info -->
+<!-- ****************** end: rdetail_copyinfo.xml ***************************** -->
diff --git a/Open-ILS/web/templates/default/opac/parts/record/extras.tt2 b/Open-ILS/web/templates/default/opac/parts/record/extras.tt2
new file mode 100644 (file)
index 0000000..6db9b6e
--- /dev/null
@@ -0,0 +1,317 @@
+<div id="rdetail_main_div">
+    <table class='hide_me rdetails_extra_links'>
+        <thead>
+            <tr>
+                <td id='rdetail_annotation_link' class='hide_me rdetail_extras_td'
+                    style='padding-right: 15px; padding-left: 15px;' >
+                    <a href='javascript:rdetailShowExtra("annotation");' 
+                        class='classic_link'>[% l("Annotation") %]</a>
+                </td>
+            </tr>
+        </thead>
+    </table>
+
+    <div id='rdetail_extras_div' style='width: 100%;'> 
+        <div id='rdetail_extras_loading' class='hide_me' 
+            style='padding: 10px;'>[% l("Loading...") %]</div>
+
+        <div rel="rdetail_summary_div" rel2="summary" class="rdetail_extras hide_me" id="rdetail_summary_link">
+            <div class="rdetail_extras_hr"></div>
+            <div class="rdetail_extras_link">
+                <a href='javascript:rdetailShowExtra("summary");'><img
+                    alt="" src="[% ctx.media_prefix %]/images/rdetail_arrow.png" /></a>
+                <a href='javascript:rdetailShowExtra("summary");'
+                    class="rdetail_extras_lbl">Summary</a>
+            </div>
+        </div>
+        <div id='rdetail_summary_div' class='rdetail_extras_div hide_me'> 
+            <table style="margin-bottom:10px;" cellpadding="0" cellspacing="0" border="0">
+                <tr>
+                    <td width="1" style="padding-right:7px;" valign="top">
+                        <strong>Summary: </strong>
+                    </td>
+                    <td>
+                        <div id='rdetail_summary_container'></div>
+                    </td>
+                </tr>
+            </table>
+            <iframe width="100%" height="500" id="content_cafe_summary" frameborder="0"></iframe>
+        </div>
+        
+        <div rel="rdetail_subject_div" rel2="subject" class="rdetail_extras hide_me" id="rdetail_subject_link">
+            <div class="rdetail_extras_hr"></div>
+            <div class="rdetail_extras_link">
+                <a href='javascript:rdetailShowExtra("subject");'><img
+                    alt="" src="[% ctx.media_prefix %]/images/rdetail_arrow.png" /></a>
+                <a href='javascript:rdetailShowExtra("subject");' class="rdetail_extras_lbl">subject</a>
+            </div>
+        </div>
+
+        <div id='rdetail_subject_div' class='rdetail_extras_div hide_me'> 
+            <table cellpadding="0" cellspacing="0" border="0">
+                <tr>
+                    <td width="1" style="padding-right:7px;" valign="top">
+                        <strong>Subject: </strong>
+                    </td>
+                    <td>
+                        <div id='rdetail_subject_container'></div>
+                    </td>
+                </tr>
+                <tr>
+                    <td width="1" style="padding:5px 7px 0px 0px;" valign="top">
+                        <strong>Genre: </strong>
+                    </td>
+                    <td style="padding-top:5px;">
+                        <div id='rdetail_genre_cont'></div>
+                    </td>
+                </tr>
+                <tr>
+                    <td width="1" style="padding:5px 7px 0px 0px;white-space:nowrap;"
+                        nowrap="nowrap" valign="top">
+                        <strong>Topic Heading: </strong>
+                    </td>
+                    <td style="padding-top:5px;">
+                        <div id='rdetail_topic_cont'></div>
+                    </td>
+                </tr>
+                <tr>
+                    <td width="1" style="padding:5px 7px 0px 0px;white-space:nowrap;"
+                        nowrap="nowrap" valign="top">
+                        <strong>Geographic Setting: </strong>
+                    </td>
+                    <td style="padding-top:5px;">
+                        <div id='rdetail_geo_cont'></div>
+                    </td>
+                </tr>
+                <tr>
+                    <td width="1" style="padding:5px 7px 0px 0px;white-space:nowrap;"
+                        nowrap="nowrap" valign="top">
+                        <strong>Biographical Subject: </strong>
+                    </td>
+                    <td style="padding-top:5px;">
+                        <div id='rdetail_bio_cont'></div>
+                    </td>
+                </tr>
+                <tr>
+                    <td width="1" style="padding:5px 7px 0px 0px;white-space:nowrap;"
+                        nowrap="nowrap" valign="top">
+                        <strong>Character Attributes: </strong>
+                    </td>
+                    <td style="padding-top:5px;">
+                        <div id='rdetail_attrib_cont'></div>
+                    </td>
+                </tr>
+                <tr>
+                    <td width="1" style="padding:5px 7px 0px 0px;" valign="top">
+                        <strong>Setting: </strong>
+                    </td>
+                    <td style="padding-top:5px;">
+                        <div id='rdetail_setting_cont'></div>
+                    </td>
+                </tr>
+                <tr>
+                    <td width="1" style="padding:5px 7px 0px 0px;white-space:nowrap;"
+                        nowrap="nowrap" valign="top">
+                        <strong>Time Period: </strong>
+                    </td>
+                    <td style="padding-top:5px;">
+                        <div id='rdetail_time_cont'></div>
+                    </td>
+                </tr>
+            </table>
+        </div>
+
+        <div rel="rdetail_content_div" rel2="content"
+            class="rdetail_extras hide_me" id="rdetail_content_link">
+            <div class="rdetail_extras_hr"></div>
+            <div class="rdetail_extras_link">
+                <a href='javascript:rdetailShowExtra("content");'><img alt=""
+                    src="[% ctx.media_prefix %]/images/rdetail_arrow.png" /></a>
+                <a href='javascript:rdetailShowExtra("content");' class="rdetail_extras_lbl">Contents</a>
+            </div>
+        </div>
+
+        <div id='rdetail_content_div' class='rdetail_extras_div hide_me'>
+            <strong>Contents:</strong>
+            <div id='rdetail_content_div_inner' style="padding-bottom:10px;"></div>
+            <strong>[% l("Table of Contents") %]:</strong>
+            <div id='rdetail_toc_div' class='rdetail_extras_div'></div>
+        </div>
+        
+        <div rel="rdetail_authors_div" rel2="authors"
+            class="rdetail_extras hide_me" id="rdetail_authors_link"><div class="rdetail_extras_hr"></div>
+            <div class="rdetail_extras_link">
+                <a href='javascript:rdetailShowExtra("authors");'><img
+                    alt="" src="[% ctx.media_prefix %]/images/rdetail_arrow.png" /></a>
+                <a href='javascript:rdetailShowExtra("authors");' class="rdetail_extras_lbl">Author</a>
+            </div>
+        </div>
+        <div id='rdetail_authors_div' class='rdetail_extras_div hide_me'>
+            <strong>Authors:</strong>
+            <div id="rdetail_authors_inner" style="padding-bottom:10px;"></div>
+            <strong>Added Authors:</strong>
+            <div id="rdetail_moar_authors" style="padding-bottom:10px;"></div>
+            <strong>Credits:</strong>
+            <div id="rdetail_credits" style="padding-bottom:10px;"></div>
+            <strong>Cast:</strong>
+            <div id="rdetail_cast" style="padding-bottom:10px;"></div>
+            <strong>Author Notes:</strong>
+            <div id='rdetail_anotes_div' class='rdetail_extras_div'> </div>
+        </div>
+        
+        <div rel="rdetail_series_div" rel2="series"
+            class="rdetail_extras hide_me" id="rdetail_series_link"><div class="rdetail_extras_hr"></div>
+            <div class="rdetail_extras_link">
+                <a href='javascript:rdetailShowExtra("series");'><img
+                    alt="" src="[% ctx.media_prefix %]/images/rdetail_arrow.png" /></a>
+                <a href='javascript:rdetailShowExtra("series");'
+                    class="rdetail_extras_lbl">series</a>
+            </div>
+        </div>
+
+        <div id='rdetail_series_div' class='rdetail_extras_div hide_me'> 
+            <strong>Series:</strong>
+            <div id='rdetail_series_container'></div>
+        </div>
+        
+        <div rel="rdetail_awards_div" rel2="awards"
+            class="rdetail_extras hide_me" id="rdetail_awards_link">
+            <div class="rdetail_extras_hr"></div>
+            <div class="rdetail_extras_link">
+                <a href='javascript:rdetailShowExtra("awards");'><img
+                    alt="" src="[% ctx.media_prefix %]/images/rdetail_arrow.png" /></a>
+                <a href='javascript:rdetailShowExtra("awards");'
+                    class="rdetail_extras_lbl">awards, reviews &amp; suggested reads</a>
+            </div>
+        </div>
+
+        <div id='rdetail_awards_div' class='rdetail_extras_div hide_me'> 
+            <strong>Awards:</strong>
+            <div id='rdetail_awards_cont' style="margin-bottom:20px;"></div>
+                <strong>Patron Reviews:</strong>
+                <div id='rdetail_chilifresh_reviews' class='hide_me' style="margin-bottom:20px;">
+                    <div id='chilifreshReviewLink' name='chilifreshReviewLink' class='chili_review'></div>
+                    <div id='chilifreshReviewResult' name='chilifreshReviewResult' class='hidden'></div>
+                </div>
+                <strong>Reviews:</strong>
+                <div id='rdetail_review_container' style="margin-bottom:20px;"></div>
+                <strong>Suggested Reads:</strong>
+                <div id='rdetail_novelist_div' class='rdetail_extras_div'>
+                <div id="NoveListSelect" class="NoveListSelect">
+                    <div id="NoveListAnchor" class="NoveListSelect"></div>
+                    <div id="novsuggestions"></div>
+                    <div id="nextreads"></div>
+                    <div id="novrelatedauthors"></div>
+                    <div id="novrelateditems"></div>
+                </div>
+            </div>
+        </div>
+        
+        <div rel="rdetail_reviews_div" rel2="reviews" class="rdetail_extras hide_me"
+            id="rdetail_reviews_link">
+            <div class="rdetail_extras_hr"></div>
+            <div class="rdetail_extras_link">
+                <a href='javascript:rdetailShowExtra("reviews");'><img
+                    alt="" src="[% ctx.media_prefix %]/images/rdetail_arrow.png" /></a>
+                <a href='javascript:rdetailShowExtra("reviews");'
+                    class="rdetail_extras_lbl">[% l("Reviews") %]</a>
+            </div>
+        </div>
+
+        <div id='rdetail_reviews_div' class='rdetail_extras_div hide_me'> </div>
+
+        <div rel="rdetail_excerpt_div" rel2="excerpt"
+            class="rdetail_extras hide_me" id="rdetail_excerpt_link">
+            <div class="rdetail_extras_hr"></div>
+            <div class="rdetail_extras_link">
+                <a href='javascript:rdetailShowExtra("excerpt");'><img
+                    alt="" src="[% ctx.media_prefix %]/images/rdetail_arrow.png" /></a>
+                <a href='javascript:rdetailShowExtra("excerpt");'
+                    class="rdetail_extras_lbl">[% l("Excerpt") %]</a>
+            </div>
+        </div>
+
+        <div id='rdetail_excerpt_div' class='rdetail_extras_div hide_me'> </div>
+        
+        <div rel="rdetail_preview_div" rel2="preview"
+            class="rdetail_extras hide_me" id="rdetail_preview_link">
+            <div class="rdetail_extras_hr"></div>
+            <div class="rdetail_extras_link">
+                <a href='javascript:rdetailShowExtra("preview");'><img
+                    alt="" src="[% ctx.media_prefix %]/images/rdetail_arrow.png" /></a>
+                <a href='javascript:rdetailShowExtra("preview");'
+                    class="rdetail_extras_lbl">[% l("Preview") %]</a>
+            </div>
+        </div>
+
+        <div id='rdetail_preview_div' class='rdetail_extras_div hide_me'> </div>
+        
+        <div rel="rdetail_novelist_div" rel2="novelist"
+            class="rdetail_extras hide_me" id="rdetail_novelist_link">
+            <div class="rdetail_extras_hr"></div>
+            <div class="rdetail_extras_link">
+                <a href='javascript:rdetailShowExtra("novelist");'><img
+                    alt="" src="[% ctx.media_prefix %]/images/rdetail_arrow.png" /></a>
+                <a href='javascript:rdetailShowExtra("novelist");'
+                    class="rdetail_extras_lbl">[% l("Suggestions by NoveList") %]</a>
+            </div>
+        </div>
+
+        <div rel="rdetail_cn_browse_div" rel2="cn" class="rdetail_extras hide_me"
+            id="rdetail_viewcn_link">
+            <div class="rdetail_extras_hr"></div>
+            <div class="rdetail_extras_link">
+                <a href='javascript:rdetailShowExtra("cn");'><img
+                    alt="" src="[% ctx.media_prefix %]/images/rdetail_arrow.png" /></a>
+                <a href='javascript:rdetailShowExtra("cn");'
+                    class="rdetail_extras_lbl">[% l("Shelf Browser") %]</a>
+            </div>
+        </div>
+
+        <div id='rdetail_cn_browse_div' style='text-align: center;' class='hide_me'>
+            <div id='cn_browse_none' class='hide_me color_4'
+                style='width: 90%; text-align: center; margin: 10px;'>
+                [% l("There are no call numbers for this item at this location.") %]
+            </div>
+
+            <div id='rdetail_cn_browse_select_div' 
+                style='width: 100%; border: 1px solid black; padding: 6px; margin-top: 5px;'>
+                <span>[% l("Local Call Numbers:") %] </span>
+                <select id='cn_browse_selector'> </select>
+            </div>
+            [% INCLUDE "default/opac/parts/cn_browse.tt2" %]
+        </div>
+
+        [% INCLUDE "default/opac/parts/record/cn_details.tt2" %]
+
+        <div rel="rdetail_copy_info_div" rel2="copyinfo"
+            class="hide_me rdetail_extras" id="rdetail_copy_info_link">
+            <div class="rdetail_extras_hr"></div>
+            <div class="rdetail_extras_link">
+                <a href='javascript:rdetailShowExtra("copyinfo");'><img
+                    alt="" src="[% ctx.media_prefix %]/images/rdetail_arrow.png" /></a>
+                <a href='javascript:rdetailShowExtra("copyinfo");'
+                    class="rdetail_extras_lbl">[% l("Copy Summary") %]</a>
+            </div>
+        </div>
+
+        [% INCLUDE "default/opac/parts/record/copyinfo.tt2" %]
+
+        <div rel="rdetail_marc_div" rel2="marc" class="rdetail_extras hide_me" id="rdetail_viewmarc_link">
+            <div class="rdetail_extras_hr"></div>
+            <div class="rdetail_extras_link">
+                <a href='javascript:rdetailShowExtra("marc");'><img
+                    alt="" src="[% ctx.media_prefix %]/images/rdetail_arrow.png" /></a>
+                <a href='javascript:rdetailShowExtra("marc");'
+                    class="rdetail_extras_lbl">[% l("MARC Record") %]</a>
+            </div>
+        </div>
+        <div id='rdetail_marc_div' class='rdetail_extras_div hide_me'>
+            <div id='rdetail_view_marc_box'></div>
+        </div>
+    </div>
+    <div id='rdetail_preview_full_text' class='hide_me'>[% l("Full text") %]</div>
+    <div id='rdetail_preview_title' class='hide_me'>[% l("See the full text of this book.") %]</div>
+    <div id='rdetail_preview_badge' class='hide_me'>[% l("Show a preview of this book from Google Book Search") %]</div>
+</div>
+<!-- XXX TODO Novelist stuff here? -->
diff --git a/Open-ILS/web/templates/default/opac/parts/record/summary.tt2 b/Open-ILS/web/templates/default/opac/parts/record/summary.tt2
new file mode 100644 (file)
index 0000000..f151888
--- /dev/null
@@ -0,0 +1,291 @@
+<!-- ****************** rdetail_summary.xml ***************************** -->
+<abbr class="unapi-id" title='tag:HTTP_HOST,OILS_TIME_YEAR:biblio-record_entry/OILS_OPAC_RID'></abbr><!-- XXX FIXME or remove -->
+<!-- This holds the record summary information -->
+
+<table width="100%" border="0" cellpadding="0" cellspacing="0" id="rdetail_details_table">
+    <tbody id="rdetail_details_tbody">
+        <tr>
+            <td width="90" valign="top" id="rdetail_image_cell">
+                [% ident = attrs.isbn_clean || attrs.upc; IF ident; %]
+                <a id='rdetail_img_link' href='[% ctx.media_prefix %]/opac/extras/ac/jacket/large/[% ident %]'><img
+                    alt="[% l('Image of item') %]" id='rdetail_image'
+                    src='[% ctx.media_prefix %]/opac/extras/ac/jacket/small/[% ident %]' /></a>
+                [% END %]
+                <br />
+                <div class='jacket_attrib hide_me' id='rdetail.jacket_attrib_div'>
+                    <div>[% l("Image provided by") %]</div>
+                    <div>
+                        <a target='_blank' href='[% l("http://amazon.com/dp/") %]'
+                            class='classic_link' id='rdetail.jacket_attrib_link'>[% l("Amazon") %]</a>
+                    </div>
+                </div>
+            </td>
+    
+            <td valign="top">
+                <table border="0" cellpadding="0" cellspacing="0" width="100%">
+                    <tr>
+                        <td valign="top">
+                            <span id='rdetail_title'>[% attrs.title %]</span><br />
+                            [% IF attrs.author %]
+                            <span class='opac-auto-030'>[% l("Author") %]:</span>
+                            <em><a title='[% l("Perform an author search") %]'
+                                    id='rdetail_author'
+                                    href="[% ctx.opac_root %]/results?qtype=author&query=[% attrs.author | replace('[,\.:;]', '') | uri %]&loc=[% CGI.param('loc') | uri %]">[% attrs.author %]</a>
+                            </em>
+                            [% END %]
+                        </td>
+                        <td align="right" valign="top" nowrap="nowrap" style="white-space:nowrap;">
+                            <div style="width:230px;text-align:left;margin-top:3px;">
+                                <div style="float:right;">
+                                    <div class="rdetail_aux_utils opac-auto-010">
+                                        <a href="[% ctx.opac_root %]/place_hold[% propagator; propagator.length > 1 ? "&" : ""; %]hold_target=[% record.id %]&hold_type=T" id="rdetail_place_hold" class="no-dec"><img
+                                            src="[% ctx.media_prefix %]/images/green_check.png" alt="[% l('place hold') %]" />
+                                            <span style="position:relative;top:-3px;left:3px;">Place Hold</span></a>
+                                    </div>
+                                    <div class="rdetail_aux_utils opac-auto-121">
+                                        [%  operation = ctx.mylist.grep(record.id).size ? "delete" : "add";
+                                            label = (operation == "add") ? "Add to" : "Remove from"; %]
+                                        <form action="[% ctx.opac_root %]/mylist/[% operation %]" method="POST">
+                                            <input type="hidden" name="record" value="[% record.id %]" />
+                                            <div class="pos-abs">
+                                                <div class="opac-auto-149">
+                                                    <input type="submit" title="[% l(label _ ' my list') %]" value="[% l(label _ ' my list') %]" class="subtle-button" />
+                                                </div>
+                                            </div>
+                                            <input type="image"
+                                                alt="[% l(label _ ' my list') %]"
+                                                src="[% ctx.media_prefix %]/images/clipboard.png" />
+                                        </form>
+                                    </div>
+                                </div>
+                                <div style="float:right;margin-right:17px;">
+                                    <img id="rdetail_tor_pic" alt="[% l('Format') %]" class="hide_me" src="" />
+                                </div>
+                            </div>
+                        </td>
+                    </tr>
+                </table>
+                <div class='opac-auto-018'>
+                    <table border="0" cellpadding="0" width="100%">
+                        <tr>
+                            <td nowrap='nowrap' valign="top">
+                                [% IF attrs.isbn %]<strong id="rdetail_isbn_lbl">[% l("ISBN") %]</strong>[% END %]
+                            </td>
+                            <td valign="top" id='rdetail_isbn'>[% attrs.isbn %]</td>
+                            <td nowrap='nowrap' valign="top">
+                                [% IF attrs.phys_desc %]<strong id="rdetail_phys_lbl">[% l("Physical Description") %]</strong>[% END %]
+                            </td>
+                            <td valign="top" id='rdetail_physical_desc'>[% attrs.phys_desc %]</td>
+                        </tr>
+                        <tr>
+                            <td nowrap='nowrap' valign="top">
+                                <strong id="rdetail_ed_lbl">[% IF attrs.edition; l("Edition"); END %]</strong>
+                            </td>
+                            <td valign="top" id='rdetail_edition'>[% attrs.edition %]</td>
+                            <td nowrap='nowrap' valign="top">
+                                <strong id="rdetail_form_lbl">[% IF attrs.format; l("Format"); END %]</strong>
+                            </td>
+                            <td valign="top">
+                                [% IF attrs.format %]
+                                <img alt="[% l('Format') %]" class='tor_pic'
+                                    title="[% attrs.format %]"
+                                    src="[% ctx.media_prefix _ '/images/' _ attrs.format_icon %]" />
+                                [%  END %]
+                            </td>
+                        </tr>
+                        <tr>
+                            <td nowrap='nowrap' valign="top">
+                                <strong id="rdetail_pubdate_lbl">[% IF attrs.pubdate; l("Publication Date"); END %]</strong>
+                            </td>
+                            <td valign="top" id='rdetail_pubdate'>[% attrs.pubdate %]</td>
+                            <td nowrap='nowrap' valign="top">
+                                <strong id="rdetail_sum_lbl">Summary</strong>
+                            </td>
+                            <td valign="top" id='rdetail_abstract'></td>
+                        </tr>
+                        <tr>
+                            <td nowrap='nowrap' valign="top">
+                                <strong id="rdetail_pub_lbl">[% IF attrs.publisher; l("Publisher"); END %]</strong>
+                            </td>
+                            <td valign="top" id='rdetail_publisher'>[% attrs.publisher %]</td>
+                            [% BLOCK render_subject;
+                            loc = CGI.param('loc') | uri;
+                            FOR node IN ctx.marc_xml.findnodes('//*[starts-with(@tag,"6")]');
+                                all_terms = [];
+                                FOR subfield IN node.childNodes;
+                                    NEXT UNLESS subfield.nodeName == "subfield";
+                                    code = 0;
+                                    FOR a IN subfield.attributes;
+                                        IF a.nodeName == "code";
+                                            code = a.nodeValue;
+                                        END;
+                                    END;
+                                    NEXT UNLESS code.match('[a-z]');
+
+                                    IF code.match('[vxyz]');
+                                        " &mdash; ";
+                                    END;
+                                    # at this point, we actually have a partial
+                                    # term to use.
+                                    single_term = subfield.textContent | html;
+                                    all_terms.push(subfield.textContent);
+                                    total_term = all_terms.join(" ").replace('\s+$', '') ; # XXX need to take care of any &'s, right?
+                                    '<a href="' _ ctx.opac_root _ '/results?qtype=subject&query=' _ total_term _ '&loc=' _ loc _ '">' _ single_term _ '</a>';
+                                END;
+                                "<br />";
+                            END %]
+                            [% END %]
+                            [% s = PROCESS render_subject; IF s.match('\S') %]
+                            <td nowrap='nowrap' valign="top">
+                                <strong id="rdetail_sub_lbl">[% l("Subjects") %]</strong>
+                            </td>
+                            <td valign="top">[% s %]</td>
+                            [% END %]
+                        </tr>
+                    </table>
+                </div>
+            </td>
+        </tr>
+    </tbody>
+</table>
+<br /><br />
+
+<table cellpadding="0" cellspacing="0" border="0" width="100%" id="rdetails_status">
+    <thead>
+        <tr id="rdetails_status_head">
+            <td>[% l("Location") %]</td>
+            <td>[% l("Call Number") %]</td>
+            <td>[% l("Barcode") %]</td>
+            <td>[% l("Shelving Location") %]</td>
+            [% IF ctx.is_staff %]
+            <td>[% l("Age Hold Protection") %]</td>
+            <td>[% l("Create Date") %]</td>
+            <td>[% l("Holdable") %]</td>
+            [% END %]
+            <td>[% l("Status") %]</td>
+            <td>[% l("Due Date") %]</td>
+        </tr>
+    </thead>
+    <tbody class="copy_details_table">
+        [% FOR copy_info IN ctx.copies %]
+        <tr>
+            <td>[%
+                # XXX KCLS-specific kludging
+                org_name = ctx.find_aou(copy_info.circ_lib).name;
+                dir = org_name | lower | replace('[^\w]', '') |
+                    replace('.+320th', '320th'); %]
+                <a href="http://www.kcls.org/[% dir %]/"
+                    class="classic_link">[% org_name %]</a>
+            </td>
+            <td>[% copy_info.call_number_label %]</td>
+            <td>[% copy_info.barcode %]</td>
+            <td>[% copy_info.copy_location %]</td>
+            [% IF ctx.is_staff %]
+            <td>
+                [% copy_info.age_protect ?
+                    ctx.find_crahp(copy_info.age_protect).name : l('None') %]
+            </td>
+            <td>[% date.format(
+                ctx.parse_datetime(copy_info.create_date),
+                DATE_FORMAT
+            ) %]</td>
+            <td>[% (copy_info.holdable == 't' AND
+                    copy_info.location_holdable == 't' AND
+                    copy_info.status_holdable == 't') ? l('Yes') : l('No') %]</td>
+            [% END %]
+            <td>[% copy_info.copy_status %]</td>
+            <td>[%
+                IF copy_info.due_date;
+                    date.format(
+                        ctx.parse_datetime(copy_info.due_date),
+                        DATE_FORMAT
+                    );
+                ELSE;
+                    '-';
+                END %]</td>
+        </tr>
+        [% END %]
+        <tr>
+        [% IF ctx.copy_offset > 0;
+            new_offset = ctx.copy_offset - ctx.copy_limit;
+            IF new_offset < 0; new_offset = 0; END %]
+            <td>
+                <a href="[% ctx.opac_root %]/record/[% record.id %]?copy_offset=[% new_offset %]&copy_limit=[% ctx.copy_limit %]">&laquo; [%
+                    l('Previous [_1]', ctx.copy_offset - new_offset)
+                %]</a>
+            </td>
+        [% END %]
+        [% IF ctx.copies.size >= ctx.copy_limit %]
+            <td>
+                <a href="[% ctx.opac_root %]/record/[% record.id %]?copy_offset=[% ctx.copy_offset + ctx.copy_limit %]&copy_limit=[% ctx.copy_limit %]">[%
+                    l('Next [_1]', ctx.copy_limit)
+                %] &raquo;</a>
+            </td>
+        [% END %]
+        </tr>
+    </tbody>
+</table>
+
+<div id="rdetail_locs_expand" class="hide_me">
+    <a href="#"><img
+        src="[% ctx.media_prefix %]/images/plus_sign.png" /></a>
+    <a style="position:relative;top:-3px;" href="#">Show more locations</a>
+</div>
+
+<div id="rdetail_locs_collapse" class="hide_me">
+    <a href="#"><img
+        src="[% ctx.media_prefix %]/images/plus_sign.png" /></a>
+    <a style="position:relative;top:-3px;" href="#">Collapse locations</a>
+</div>
+
+<div id="rdetail_extras_expand" class="hide_me">
+    <a href="#"><img
+        src="[% ctx.media_prefix %]/images/plus_sign.png" /></a>
+    <a style="position:relative;top:-3px;" href="#">Expand all tabs</a>
+</div>
+
+<div id="rdetail_extras_collapse" class="hide_me">
+    <a href="#"><img src="[% ctx.media_prefix %]/images/plus_sign.png" /></a>
+    <a style="position:relative;top:-3px;" href="#">Collapse all tabs</a>
+</div>
+
+<div class="hide_me">
+    <table id='' border="0" width="100%">
+        <tbody id='rdetail_details_tbody'>
+            <tr>
+                <td id='' rowspan='2' valign="top" align="center" style="padding-right:10px;">
+                </td>
+                <td class='rdetail_desc' valign="top" colspan="3">
+                    <table border="0" width="100%">
+                        <tr>
+                            <td valign="top">
+                                <div style="padding-bottom:7px;">
+                                    <strong>[% l("Title") %]:</strong>
+                                </div>
+                            </td>
+                            <td width="1" valign="top" align="right" style="white-space:nowrap;">
+                                <a href="[% ctx.opac_root %]/place_hold[% propagator; propagator.length > 1 ? "&" : ""; %]hold_target=[% record.id %]&hold_type=T"><img alt="[% l('Place Hold') %]"
+                                    src="[% ctx.media_prefix %]/images/place_hold.gif" /></a>
+                                <a href="#" id="rd_reviews_and_more" target="_blank"><img
+                                    alt="[% l('Reviews and More') %]" src="[% ctx.media_prefix %]/images/reviews.gif" /></a>
+                                <a href="#" id=""><img alt="[% l('Add to My List') %]"
+                                    src="[% ctx.media_prefix %]/images/add_mylist.gif" /></a>
+                            </td>
+                        </tr>
+                    </table>
+                </td>        
+            </tr>
+            <tr>
+                <td nowrap='nowrap' colspan="3" valign="bottom" style="padding-bottom:16px;">
+                </td>
+            </tr>
+            <tr>
+                <td><div style="height:20px;"></div></td>
+            </tr>
+        </tbody>
+    </table>
+    <!-- Empty span used for creating unAPI links -->
+    <abbr name="unapi" class="unapi-id"> <!-- unAPI URI goes here --> </abbr>
+</div> <!-- details_body -->
+
+<!-- ****************** end: rdetail_summary.xml ***************************** -->
diff --git a/Open-ILS/web/templates/default/opac/parts/result/lowhits.tt2 b/Open-ILS/web/templates/default/opac/parts/result/lowhits.tt2
new file mode 100644 (file)
index 0000000..9393c49
--- /dev/null
@@ -0,0 +1,95 @@
+<div id='result_low_hits'>
+    <div id="zero_search_hits">
+        <div>
+            <p>[% l('Sorry, no entries were found for') %]
+                [% IF is_advanced; l('your search'); ELSE %]
+                <q>[% CGI.param('query') | html %]</q>
+                [% END %]
+                <br />
+                <span id="zero_hits_label1" class="hide_me">Did you mean
+                    <strong><a id="spell_check_link" href="javascript:;"></a></strong>?</span>
+            </p>
+            <table cellpadding="0" cellspacing="0" border="0">
+                <tr>
+                    <td valign="top" style="padding-right:10px;">
+                        <span id="zero_hits_label2" class="hide_me">Other Possibilities:</span>
+                    </td>
+                    <td id="zero_hits_suggestions"></td>
+                </tr>
+            </table>
+        </div>
+        <div style="float:right;width:353px;background:#ccc;padding:10px;margin-top:7px;">
+            <p>
+                <strong>Still not finding what you are looking for?</strong><br />
+                Request that KCLS purchase the material you are looking for by making a
+                <a href="javascript:;">Purchase Request</a><br />
+                <strong>Note:</strong> You must be logged in to make a Purchase Request<br />
+            </p>
+            <p>
+                <strong>Keyword Search Tips</strong><br />
+                Change to <strong>Advanced Keyword Search.</strong>
+            </p>
+            <p>
+                <strong>Adjacency</strong><br />
+                Multiple words are not searched together as a phrase. They will
+                be found in various parts of the record. To search for a phrase, enclose your
+                search terms in quotation marks.<br />
+                (example:  <strong>&quot;garcia marquez&quot;</strong>)
+            </p>
+            <p>
+                <strong>Truncation</strong><br />
+                Words may be right-hand truncated using an asterisk. Use a single asterisk *
+                to truncate from 1-5 characters. Use a double asterisk ** for open-ended truncation.<br />
+                (example: <strong>environment* agency</strong>)
+            </p>
+            <p>
+                <strong>Wildcards</strong><br />
+                You may use a question mark to replace a single character anywhere within a word.<br />
+                example: <strong>wom?</strong>)
+            </p>
+        </div>
+    </div>
+    <div class="hide_me">
+        <div style='text-align: center; padding-bottom: 8px;' class="hide_me">
+            <div id='result_low_hits_msg' class='hide_me'>[% l("Few hits were returned for your search.") %]</div>
+            <div id='result_zero_hits_msg' class='hide_me'>[% l("Zero hits were returned for your search.") %]</div>
+        </div>
+
+        <!-- spell checker -->
+        <div id='did_you_mean' class='lowhits_div hide_me'>
+            <span>[% l("Maybe you meant:") %] </span>
+            <!-- <a class='classic_link' id='spell_check_link'> </a> -->
+        </div>
+
+        <div id='low_hits_remove_format' class='lowhits_div hide_me'>
+            <span>[% l("You will find more hits when searching all item formats:") %] </span>
+            <a id='low_hits_remove_format_link' class='classic_link'>[% l("Search again with all formats?") %]</a>
+        </div>
+
+        <div id='low_hits_cross_ref' class='lowhits_div hide_me'>
+            <span>[% l("You may also like to try these related searches:") %]</span>
+            <div style='padding: 5px;'>
+                <a id='low_hits_xref_link' class='classic_link' style='padding-right: 5px;'> </a>
+            </div>
+        </div>
+
+        <div id='low_hits_expand_range' class='lowhits_div hide_me'>
+            <span>[% l("You may also wish to expand your search range to:") %] </span>
+            <a id='low_hits_expand_link' class='classic_link' style='padding-right: 5px;'> </a>
+        </div>
+
+        <div id='low_hits_search_type' class='lowhits_div hide_me'>
+            <span>[% l("You can try searching the same terms by:") %]</span>
+            <a id='low_hits_title_search' class='hide_me classic_link' 
+                style='padding-right: 5px;'>[% l("title") %]</a>
+            <a id='low_hits_author_search' class='hide_me classic_link' 
+                style='padding-right: 5px;'>[% l("author") %]</a>
+            <a id='low_hits_subject_search' class='hide_me classic_link' 
+                style='padding-right: 5px;'>[% l("subject") %]</a>
+            <a id='low_hits_series_search' class='hide_me classic_link' 
+                    style='padding-right: 5px;'>[% l("series") %]</a>
+            <a id='low_hits_keyword_search' class='hide_me classic_link' 
+                style='padding-right: 5px;'>[% l("keyword") %]</a>
+        </div>
+    </div>
+</div>
diff --git a/Open-ILS/web/templates/default/opac/parts/result/table.tt2 b/Open-ILS/web/templates/default/opac/parts/result/table.tt2
new file mode 100644 (file)
index 0000000..4b14e04
--- /dev/null
@@ -0,0 +1,252 @@
+[%  PROCESS "default/opac/parts/marc_misc.tt2";
+
+    ctx.result_start = 1 + ctx.page_size * page;
+    ctx.result_stop = 1 + ctx.page_size * (page + 1);
+    IF ctx.result_stop > ctx.hit_count; ctx.result_stop = ctx.hit_count; END;
+
+    result_count = ctx.result_start;
+%]
+<div style="height: 10px;"></div>
+[% BLOCK results_count_header %]
+<div class="results_header_nav1">
+    <table cellpadding="0" cellspacing="0" border="0" width="100%">
+        <tr>
+            <td class="h1" width="116">[% l('Search Results') %]</td>
+            <td valign="bottom" nowrap="nowrap" class="result_number">
+                [% |l(ctx.result_start, ctx.result_stop, ctx.hit_count) %]
+                Results <strong>[_1]</strong> - <strong>[_2]</strong> of <strong>[_3]</strong>
+                [% END %]
+                <span style='padding-left: 6px;'>
+                    [% |l(page + 1, page_count) %](page <strong>[_1]</strong> of <strong>[_2]</strong>)[% END %]
+                </span>
+            </td>
+            <td align="right" valign="bottom">
+                <span class='start_end_links_span'>
+                    [% IF page > 0 %]
+                    <a class='search_page_nav_link'
+                        href="[% propagator _ '&page=' _ (page - 1) %]"
+                        title='[% l("Previous page") %]'>
+                        <span class="nav_arrow_fix">&#9668;</span> Previous
+                    </a>
+                    [% END %]
+                    <span class='hide_me'
+                        style='padding-left: 11px; padding-right:11px;'>
+                        <span></span>
+                    </span>
+                    [% IF (page + 1) < page_count %]
+                    <a class='search_page_nav_link'
+                        href="[% propagator _ '&page=' _ (page + 1) %]"
+                        title='[% l("Next page") %]'>
+                        Next <span class="nav_arrow_fix">&#9658;</span>
+                    </a>
+                    [% END %]
+                </span>
+            </td>
+        </tr>
+    </table>
+</div>
+[% END %]
+[% ctx.results_count_header = PROCESS results_count_header;
+    ctx.results_count_header %]
+<div id="result_table_div">
+    <table cellpadding="0" cellspacing="0" border="0" width="100%">
+        <tr>
+            <td valign="top" width="1" style="padding-right:20px;">
+                <div style="width:174px;" class="hide_me" id="tehSideBar">SIDEBAR TODO
+                </div>
+            </td>
+            <td class='opac-auto-015' width="1"></td>
+            <td valign="top">
+                <table id="res_table" cellpadding="0" cellspacing="0"
+                    border="0" width="100%" style="margin-top:10px;">
+                    <tbody id="result_table">
+                    [%  FOR rec IN ctx.records;
+                            attrs = {marc_xml => rec.marc_xml};
+                            PROCESS get_marc_attrs args=attrs %]
+                        <tr>
+                            <td class='result_table_row' align='left' width='100%'>
+                                <table cellpadding="0" cellspacing="0" class='result_table_subtable'>
+                                    <tbody class='result_table_subtbody'>
+                                        <tr name='counts_row'>
+                                            <td width="58" valign="top"
+                                                style="font-weight:bold;padding-left:10px;"
+                                                name="results_row_count">[%
+                                                    result_count; result_count = result_count + 1
+                                                %].</td>
+                                            <td class='result_table_pic_header'
+                                                width="78" nowrap="nowrap" valign="top">
+                                                [% ident = attrs.isbn_clean || attrs.upc; IF ident; %]
+                                                <a href="[% ctx.opac_root %]/record/[% rec.bre.id _ propagator %]"><img alt="Image of item"
+                                                        name='item_jacket' class='result_table_pic' width="55"
+                                                        src='[% ctx.media_prefix %]/opac/extras/ac/jacket/small/[% ident %]' /></a><br />
+                                                [% END %]
+                                            </td>
+                                            <td class='result_table_title_cell'
+                                                name='result_table_title_cell'
+                                                valign="top">
+                                                <div class="bold">
+                                                    <a title="[% attrs.title %]" name='item_title'
+                                                        href="[% ctx.opac_root %]/record/[% rec.bre.id _ propagator %]"
+                                                        class='search_link'>[% attrs.title %]</a>
+                                                </div>
+                                                <span style="font-size:11px;">
+                                                    <div>
+                                                        <em>
+                                                            <a title="[% l("Perform an Author Search") %]"
+                                                                name='item_author'
+                                                                href="[% ctx.opac_root %]/results?qtype=author&query=[% attrs.author | replace('[,\.:;]', '') | uri %]&loc=[% CGI.param('loc') | uri %]"
+                                                                class='search_link'>[% attrs.author %]</a>
+                                                        </em> &nbsp;&nbsp;
+                                                        [% attrs.pubdate %]
+                                                    </div>
+                                                    <table cellpadding="0" cellspacing="0" border="0"
+                                                        class="results_info_table">
+                                                        <tr name='bib_cn_list' class='result_table_title_cell'>
+                                                            <td colspan='2'>
+                                                                <strong>Call number:</strong>
+                                                                [% args.kcls_cn %]
+                                                            </td>
+                                                        </tr>
+                                                        <tr name="results_pub_tr" class="[% attrs.publisher ? '' : 'hide_me' %]">
+                                                            <td valign="top">
+                                                                <strong>Publisher:</strong>
+                                                            </td>
+                                                            <td>[% attrs.publisher; %]</td>
+                                                        </tr>
+                                                        <tr name="results_isbn_tr" class="[% attrs.isbn ? '' : 'hide_me' %]">
+                                                            <td valign="top">
+                                                                <strong>ISBN:</strong>
+                                                            </td>
+                                                            <td>[% attrs.isbn %]</td>
+                                                        </tr>
+                                                        <tr name="results_edition_tr" class="[% attrs.edition ? '' : 'hide_me' %]">
+                                                            <td valign="top">
+                                                                <strong>Edition:</strong>
+                                                            </td>
+                                                            <td>[% attrs.edition %]</td>
+                                                        </tr>
+                                                        <tr name="results_phys_desc_tr" class="[% attrs.phys_desc ? '' : 'hide_me' %]">
+                                                            <td nowrap="nowrap" valign="top">
+                                                                <strong>Phys. Desc.:</strong>
+                                                            </td>
+                                                            <td>
+                                                                [% args.phys_desc %]
+                                                            </td>
+                                                        </tr>
+                                                    </table>
+                                                    <div>
+                                                        [% l('[_1] of [quant,_2,copy,copies] available',
+                                                            rec.copy_counts.available, rec.copy_counts.visible) %]
+                                                    </div>
+                                                </span>
+                                                <div class="hide_me">
+                                                    <span name='result_table_extra_span' class='hide_me'>
+                                                        <span name='result_table_pub_box'
+                                                            style='padding-left: 10px;'>
+                                                            <span name='result_table_edition_span'
+                                                                style='padding-left: 10px;'></span> |
+                                                            <span name='result_table_pub_span'> </span> |
+                                                            <span name='result_table_phys_span'> </span>
+                                                        </span>
+                                                    </span>
+                                                </div>
+                                            </td>
+                                            <!-- Copy this td for each copy count appended -->
+                                            <td nowrap='nowrap' name="copy_count_cell"
+                                                class='copy_count_cell hide_me' width="1"> </td>
+                                            <td name='result_table_format_cell'
+                                                class='result_table_format_cell' align="center" width="1"
+                                                style="padding:0px 10px;">
+                                                <img alt="Format" src="" class="hide_me" name="" />
+                                                <span class='hide_me opac-auto-031'>
+                                                    <span>[% l("Match Score: ") %] </span>
+                                                    <span name='relevancy_span'> </span>
+                                                </span>
+                                                <!-- Empty span used for creating unAPI links -->
+                                                <span class="hide_me">
+                                                    <abbr style='padding-left: 8px;' name="unapi" class="unapi-id">
+                                                    <!-- unAPI URI goes here -->
+                                                    </abbr>
+                                                </span>
+                                                <!-- Empty span used for creating Google Book Search-->
+                                                <span name="googleBooksLink" class="hide_me">
+                                                    <a style='padding-left: 8px;'
+                                                        class='classic_link hide_me'
+                                                        name="googleBooks-link">[% l("Browse in Google Books Search") %]</a>
+                                                </span>
+                                            </td>
+                                            <td nowrap='nowrap' width="1" align="right">
+                                                <div style="width:250px;text-align:left;">
+                                                    <div style="float:right;">
+                                                        <div class="results_aux_utils opac-auto-010"><a
+                                                                href="[% ctx.opac_root %]/place_hold[% propagator; propagator.length > 1 ? "&" : ""; %]hold_target=[% rec.bre.id %]&hold_type=T" name="place_hold_link" class="no-dec"><img
+                                                                src="[% ctx.media_prefix %]/images/green_check.png"
+                                                                alt="place hold" /><span
+                                                                    style="position:relative;top:-3px;left:3px;">Place Hold</span></a>
+                                                        </div>
+                                                        <div class="results_aux_utils opac-auto-011">
+                                                            [%  operation = ctx.mylist.grep(rec.bre.id).size ? "delete" : "add";
+                                                                label = (operation == "add") ? "Add to" : "Remove from"; %]
+                                                            <form action="[% ctx.opac_root %]/mylist/[% operation %]" method="POST">
+                                                                <input type="hidden" name="record" value="[% rec.bre.id %]" />
+                                                            <div style="position:absolute;">
+                                                                <div style="position:relative;top:5px; left: 25px;">
+                                                                    <input type="submit" title="[% l(label _ ' my list') %]" value="[% l(label _ ' my list') %]" class="subtle-button" />
+                                                                </div>
+                                                            </div>
+                                                                <input type="image"
+                                                                alt="[% l(label _ ' my list') %]"
+                                                                src="[% ctx.media_prefix %]/images/clipboard.png" />
+                                                        </form>
+                                                        </div>
+                                                        <div style="padding-top:7px;" class="results_aux_utils">
+                                                            <a title="Reviews and More" target="_blank" class="no-dec"
+                                                                name="reviews_and_more" href="javascript:;"><img
+                                                                alt="reviews &amp; more"
+                                                                src="[% ctx.media_prefix %]/images/starz.png" /> <span
+                                                                    style="position:relative;top:-5px;">Reviews &amp; More</span></a>
+                                                        </div>
+                                                    </div>
+                                                    <div style="float:right;margin-right:17px;">
+                                                    [%  key = attrs.mattype;
+                                                        format_desc = ctx.find_citm(key).value;
+                                                        icon_filename = icon_by_mattype.$key;
+                                                        IF icon_filename; %]
+                                                        <img alt="[% format_desc %]" title="[% format_desc %]"
+                                                            src="[% ctx.media_prefix _ '/images/' _ icon_filename %]" />
+                                                    [% END %]
+                                                    </div>
+                                                </div>
+                                            </td>
+                                        </tr>
+                                        <!-- Placeholder for ChiliFresh Review -->
+                                        <tr class="hide_me" name="chilifreshReview">
+                                            <td></td>
+                                            <td valign="top" colspan="5">
+                                                <div style="position:relative;left:-19px;">
+                                                    <span name="chilifreshReviewLink" class="chili_review"></span>
+                                                    <div name="chilifreshReviewResult" style="display:none"></div>
+                                                </div>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td colspan="5">
+                                                <div style="height:0px;border-top:1px solid #b7b7b7;border-bottom:1px solid #d4d4d4;margin:15px 0px;"></div>
+                                                <!-- <hr class='opac-auto-013' color="#FFCC33" /> -->
+                                            </td>
+                                        </tr>
+                                    </tbody>
+                                </table>
+                            </td>
+                        </tr>
+                    [% END %]
+                    </tbody>
+                </table>
+            </td>
+        </tr>
+    </table>
+</div>
+<div>
+    [% ctx.results_count_header %]
+    <!-- ChiliFresh XXX script TODO -->
+</div>
diff --git a/Open-ILS/web/templates/default/opac/parts/searchbar.tt2 b/Open-ILS/web/templates/default/opac/parts/searchbar.tt2
new file mode 100644 (file)
index 0000000..158a93f
--- /dev/null
@@ -0,0 +1,75 @@
+[% PROCESS "default/opac/parts/org_selector.tt2" %]
+<div id="search-box">    
+    [% UNLESS took_care_of_form -%]
+    <form action="[% ctx.opac_root %]/results" method="GET">
+    [%- END %]
+    <table cellpadding="0" cellspacing="10" border="0">
+        <tr>
+            <td colspan="3">
+                <span class="search_catalog_lbl">[% l('Search the Catalog') %]</span>
+                <a href="[% ctx.opac_root %]/advanced"
+                    id="home_adv_search_link"><span
+                    class="adv_search_font">[% l('Advanced Search') %]</span></a>
+            </td>
+        </tr>
+        <tr>
+            [% IF is_advanced %]
+            <td colspan="2">
+                <input type="hidden" name="_adv" value="1" />
+            [% ELSE %]
+            <td>
+            [% INCLUDE "default/opac/parts/qtype_selector.tt2" %]
+            </td>
+            [% END %]
+            [% IF ctx.processed_search_query OR NOT is_advanced %]
+            <td>
+                <div id="search_box_wrapper">
+                    <!-- Note: when common browsers support HTML5 placeholder text, we can remove the JS -->
+                    <input type="text" id="search_box" name="query" value="[% is_advanced ? ctx.processed_search_query : CGI.param('query') || l("Search Keyword") | html %]"
+                        [% IF is_advanced %]style="width: 450px"[% END %]
+                        onfocus="if (this.value=='[% l("Search Keyword") %]'){this.value='';this.style.color='#000';}"
+                        onblur="if (this.value==''){this.value='[% l("Search Keyword") %]';this.style.color='#999';}" />
+                </div>
+                <input name='page' type='hidden' value="0" />
+            </td>
+            <td valign="top">
+                <div class="pos-abs">
+                    <div class="opac-auto-143">
+                        <input type="image" alt="[% l('Search') %]" src="[% ctx.media_prefix %]/images/go-btn.png"
+                            onmouseover="this.src='[% ctx.media_prefix %]/images/go-btn-hover.png';"
+                            onmouseout="this.src='[% ctx.media_prefix %]/images/go-btn.png';" />
+                    </div>
+                </div>
+            </td>
+            [% END %]
+        </tr>
+        [% UNLESS is_advanced %]
+        <tr>
+            <td>
+                [% INCLUDE "default/opac/parts/format_selector.tt2" value=CGI.param("format") %]
+            </td>
+            <td>
+                <span id='depth_selector_span'>
+                    [% PROCESS build_org_selector name='loc' value=CGI.param('loc') %]
+                </span>
+                <span id='lib_selector_span'>
+                    <a id='lib_selector_link' class='classic_link'
+                        href='#'>[% l("Choose a library to search") %]</a>
+                </span>
+            </td>
+        </tr>
+        [% END %]
+    </table>
+    [% UNLESS took_care_of_form %]</form>[% END %]
+    [% IF is_advanced AND CGI.param('qtype') %]
+    <div class="opac-auto-102">
+        [ <a href="[% ctx.opac_root %]/advanced?[% query_string %]">[%
+            l('Click to Refine Your Original Search')
+        %]</a> ]
+    </div>
+    [% END %]
+    <div id="breadcrumb">
+        <a href="[% ctx.opac_root %]/home">[% l('Catalog Home') %]</a> &gt;
+    </div>
+    <div class="clear-both"></div>
+</div>
diff --git a/Open-ILS/web/templates/default/opac/parts/tips.tt2 b/Open-ILS/web/templates/default/opac/parts/tips.tt2
new file mode 100644 (file)
index 0000000..f4e73ed
--- /dev/null
@@ -0,0 +1,11 @@
+<!-- ****************** tips.xml ***************************** -->
+<div class="hide_me">
+    <div id='tips' class='tips hide_me'>
+        <div class='hide_me'>
+            <span>[% l("Click on a folder icon in the sidebar to access related quick searches") %]</span>
+            <span>[% l("If you don't find what you want try expanding your search using the range selector at the right of the search bar") %]</span>
+        </div>
+        <strong>[% l("Tip:") %]</strong>
+    </div>
+</div>
+<!-- ****************** end: tips.xml ***************************** -->
diff --git a/Open-ILS/web/templates/default/opac/parts/topnav.tt2 b/Open-ILS/web/templates/default/opac/parts/topnav.tt2
new file mode 100644 (file)
index 0000000..f2401d8
--- /dev/null
@@ -0,0 +1,117 @@
+<div id="header">
+    <div class="float-left">
+        <a href="http://www.kcls.org"><img alt="[% l('KCLS Logo') %]" 
+            src="[% ctx.media_prefix %]/images/KCLS_logo_horiz.gif" /></a>
+    </div>
+    <div class="float-right">
+        [% IF !ctx.user %]
+        <div id="your-acct-login">
+            <a href="[% ctx.opac_root %]/myopac/main" id="home_myopac_link"><img
+                alt="[% l('Your Account Log in') %]"
+                src="[% ctx.media_prefix %]/images/login-btn.png"
+                onmouseover="this.src='[% ctx.media_prefix %]/images/login-btn-hover.png';"
+                onmouseout="this.src='[% ctx.media_prefix %]/images/login-btn.png';" /></a>
+        </div>
+        [% ELSE %]
+        <div id="dash_wrapper">
+            <div class="float-right">
+                <table cellpadding="0" cellspacing="0" border="0">
+                    <tr>
+                        <td>
+                            <img src="[% ctx.media_prefix %]/images/dash-corner-left1.png" />
+                        </td>
+                        <td id="dash_corner_mid1a">
+                            <span id="dash_user">
+                                [%  l('[_1] [_2]', ctx.user.first_given_name, ctx.user.family_name) %]
+                            </span>
+                        </td>
+                        <td id="dash_corner_mid1b">
+                            <img src="[% ctx.media_prefix %]/images/dash-divider.jpg" />
+                        </td>
+                        <td id="dash_corner_mid1c">
+
+                            <a href="[% ctx.opac_root %]/myopac/main" class="pos-rel-top4"><img
+                                alt="[% l('My Account') %]"
+                                src="[% ctx.media_prefix %]/images/acct-btn.png"
+                                onmouseover="this.src='[% ctx.media_prefix %]/images/acct-btn-hover.png';"
+                                onmouseout="this.src='[% ctx.media_prefix %]/images/acct-btn.png';" /></a>
+
+                            <a href="[% ctx.opac_root %]/logout" class="pos-rel-top4"
+                                id="logout_link"><img
+                                alt="[% l('Logout') %]"
+                                src="[% ctx.media_prefix %]/images/logout-btn.png"
+                                onmouseover="this.src='[% ctx.media_prefix %]/images/logout-btn-hover.png';"
+                                onmouseout="this.src='[% ctx.media_prefix %]/images/logout-btn.png';" /></a>
+                        </td>
+                        <td>
+                            <img src="[% ctx.media_prefix %]/images/dash-corner-right1.png" />
+                        </td>
+                    </tr>
+                </table>
+            </div>
+            <div id="dashboard">
+                <div class="pos-abs">
+                    <div class="pos-rel-top4">
+                        <table cellpadding="0" cellspacing="0" border="0">
+                            <tr>
+                                <td>
+                                    <img src="[% ctx.media_prefix %]/images/dash-corner-left2.png" />
+                                </td>
+                                <td id="dash_corner_mid2a">
+                                    <div id="dash_number_row">
+                                        <div class="pos-abs">
+                                            <div class="dash-pos-out">
+                                                <div class="dash-align-out">
+                                                    <span id="dash_checked">[% ctx.user_stats.checkouts.total_out %]</span> [% l("Checked Out") %]
+                                                </div>
+                                            </div>
+                                        </div>
+                                        <div class="pos-abs">
+                                            <div class="dash-pos-holds">
+                                                <div class="dash-align-holds">
+                                                    <span id="dash_holds">[% ctx.user_stats.holds.total %]</span> [% l("On Hold") %]
+                                                </div>
+                                            </div>
+                                        </div>
+                                        <div class="pos-abs">
+                                            <div class="dash-pos-pickup">
+                                                <div class="dash-align-pickup">
+                                                    <span id="dash_pickup">[% ctx.user_stats.holds.ready %]</span> [% l("Ready for Pickup") %]
+                                                </div>
+                                            </div>
+                                        </div>
+                                        <div class="pos-abs">
+                                            <div class="dash-pos-fines">
+                                                <div class="dash-align-fines">
+                                                    <span id="dash_fines">[% money(ctx.user_stats.fines.balance_owed) %]</span> [% l("Fines") %]
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </td>
+                                <td>
+                                    <img src="[% ctx.media_prefix %]/images/dash-corner-right2.png" />
+                                </td>
+                            </tr>
+                        </table>
+                    </div>
+                </div>
+            </div>
+        </div>
+        [% END %]
+    </div>
+    <div class="common-no-pad"></div>
+</div>
+<div id="gold-links-holder">
+    <div id="gold-links">
+        <div id="header-links">
+            <a href="http://www.kcls.org/usingthelibrary/index.cfm">Using the Library</a>
+            <a href="http://www.kcls.org/booksandreading/">Books &amp; Reading</a>
+            <a href="http://www.kcls.org/research/index.cfm">Research &amp; Homework</a>
+            <a href="http://www.kcls.org/programs/">Programs &amp; Classes</a>
+            <a href="http://www.kcls.org/events/">Events</a>
+            <a href="/opac/extras/mobile/">Mobile Catalog</a>
+            <a href="http://www.kcls.org/about/">About KCLS</a>
+        </div>
+    </div>
+</div>
diff --git a/Open-ILS/web/templates/default/opac/parts/utils.tt2 b/Open-ILS/web/templates/default/opac/parts/utils.tt2
new file mode 100644 (file)
index 0000000..aa70a6c
--- /dev/null
@@ -0,0 +1,30 @@
+        <div class="big-block">
+            <div id="user-ql"></div>
+            <div class="float-right">
+                <div class="pos-rel">
+                    <img
+                        src="[% ctx.media_prefix %]/images/utils-corner-left.png"
+                        class="float-left" />
+                    <div class="left-corner"> 
+                        <a href="javascript:history.go(-1)"
+                            id="util_back_btn"><img alt="Back"
+                            src="[% ctx.media_prefix %]/images/tool_back.png" /></a>
+                        <a href="[% ctx.opac_root %]/home"
+                            id="util_home_btn"><img alt="Homepage"
+                            src="[% ctx.media_prefix %]/images/tool_home.png" /></a>
+                        <a href="javascript:window.print();"
+                            id="util_print_btn"><img alt="Print Page"
+                            src="[% ctx.media_prefix %]/images/tool_print.png" /></a>
+                        <a href="http://www.kcls.org/usingthelibrary/catalog_help/index.cfm"
+                            id="util_help_btn"><img alt="Help"
+                            src="[% ctx.media_prefix %]/images/tool_help.png" /></a>
+                        <a href="javascript:history.go(+1)"
+                            id="util_forw_btn"><img alt="Forward"
+                            src="[% ctx.media_prefix %]/images/tool_forward.png" /></a>
+                    </div>
+                    <img
+                        src="[% ctx.media_prefix %]/images/utils-corner-right.png"
+                        class="float-left" />
+                </div>
+            </div>
+        </div>
diff --git a/Open-ILS/web/templates/default/opac/place_hold.tt2 b/Open-ILS/web/templates/default/opac/place_hold.tt2
new file mode 100644 (file)
index 0000000..792b5c2
--- /dev/null
@@ -0,0 +1,16 @@
+[%  PROCESS "default/opac/parts/header.tt2";
+    WRAPPER "default/opac/parts/base.tt2";
+    INCLUDE "default/opac/parts/topnav.tt2";
+    ctx.page_title = l("Place Hold") %]
+    <div id="search-wrapper">
+        [% INCLUDE "default/opac/parts/utils.tt2" %]
+        [% INCLUDE "default/opac/parts/searchbar.tt2" %]
+    </div>
+    <div id="content-wrapper">
+        <div id="main-content">
+            <div class="common-full-pad"></div>        
+            [% INCLUDE "default/opac/parts/place_hold.tt2" %]
+            <div class="common-full-pad"></div>        
+        </div>
+    </div>
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac/record.tt2 b/Open-ILS/web/templates/default/opac/record.tt2
new file mode 100644 (file)
index 0000000..7f2a705
--- /dev/null
@@ -0,0 +1,15 @@
+[%  PROCESS "default/opac/parts/header.tt2";
+    WRAPPER "default/opac/parts/base.tt2";
+    INCLUDE "default/opac/parts/topnav.tt2";
+    ctx.page_title = l("Record Detail") %]
+    <div id="search-wrapper">
+        [% INCLUDE "default/opac/parts/utils.tt2" %]
+        [% INCLUDE "default/opac/parts/searchbar.tt2" %]
+    </div>
+    <div id="content-wrapper">
+        <div id="main-content">
+            [% INCLUDE "default/opac/parts/record/body.tt2" %]
+            <div class="common-full-pad"></div>        
+        </div>
+    </div>
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac/results.tt2 b/Open-ILS/web/templates/default/opac/results.tt2
new file mode 100644 (file)
index 0000000..db1f298
--- /dev/null
@@ -0,0 +1,74 @@
+[%  PROCESS "default/opac/parts/header.tt2";
+    USE POSIX;
+
+    WRAPPER "default/opac/parts/base.tt2";
+    INCLUDE "default/opac/parts/topnav.tt2";
+    ctx.page_title = l("Search Results");
+
+    page = CGI.param('page') || 0;
+    page_count = POSIX.ceil(ctx.hit_count / ctx.page_size);
+%]
+    <form action="[% ctx.opac_root %]/results" method="GET">
+    <div id="search-wrapper">
+        [% INCLUDE "default/opac/parts/utils.tt2" %]
+        [% INCLUDE "default/opac/parts/searchbar.tt2" took_care_of_form=1 %]
+    </div>
+    <div class="almost-content-wrapper">
+        <div id="results_header_bar">
+            <div id="results_header_inner">
+                <div class="results_header_btns">
+                    <a href="[% ctx.opac_root %]/home"><img alt="[% l('Another Search') %]"
+                        src="[% ctx.media_prefix %]/images/another_search.png"
+                        onmouseover="this.src='[% ctx.media_prefix %]/images/another_search_hover.png';"
+                        onmouseout="this.src='[% ctx.media_prefix %]/images/another_search.png';" /></a>
+                </div>
+                <div class="results_header_btns">
+                    <a href="[% ctx.opac_root %]/advanced"><img alt="[% l('Advanced Search') %]"
+                        src="[% ctx.media_prefix %]/images/adv_search.png"
+                        onmouseover="this.src='[% ctx.media_prefix %]/images/adv_search_hover.png';"
+                        onmouseout="this.src='[% ctx.media_prefix %]/images/adv_search.png';" /></a>
+                </div>
+                [% IF ctx.mylist.size %]
+                <div class="results_header_btns cached_list_div">
+                    <a href="[% ctx.opac_root; ctx.user ? '/myopac/lists' : '/mylist' %]"><img
+                        alt="View My List"
+                        src="[% ctx.media_prefix %]/images/view_my_list.png"
+                        onmouseover="this.src='[% ctx.media_prefix %]/images/view_my_list_hover.png';"
+                        onmouseout="this.src='[% ctx.media_prefix %]/images/view_my_list.png';" /></a>
+                </div>
+                [% END %]
+                <div class="results_header_div"></div>
+                [% UNLESS is_advanced %]
+                    <div class="results_header_lbl">Sort by</div>
+                    [% INCLUDE "default/opac/parts/filtersort.tt2" value=CGI.param('sort') %]
+                    <div class="results_header_div"></div>
+                    <!-- XXX still needed?<div class="results_header_lbl">View</div>
+                    <select class="results_header_sel">
+                        <option>Simple</option>
+                        <option>Detailed</option>
+                    </select>
+                    <div class="results_header_div"></div> -->
+                    <input type="checkbox" id="limit_to_available"
+                        name="modifier" value="available"
+                        [% CGI.param('modifier').grep('available').size
+                            ? ' checked="checked"' : '' %] />
+                    <label for="limit_to_available" class="results_header_lbl">
+                        [% l('Limit to available items') %]
+                    </label>
+                [% END %]
+                <div class="clear-both"></div>
+            </div>
+        </div>
+    </div>
+    </form>
+    <div id="content-wrapper">
+        <div id="main-content">
+            <div id="tehResultsPage">
+                [% path = "default/opac/parts/result/" _
+                    (ctx.records.size ? "table.tt2" : "lowhits.tt2");
+                INCLUDE $path %]
+            </div>
+            <div class="common-full-pad"></div>    
+        </div>
+    </div>
+[% END %]