C/W MARS OPAC templates
authorJim Keenan <jkeenan@cwmars.org>
Mon, 25 Jan 2016 16:45:29 +0000 (11:45 -0500)
committerJim Keenan <jkeenan@cwmars.org>
Mon, 25 Jan 2016 16:45:29 +0000 (11:45 -0500)
Signed-off-by: Jim Keenan <jkeenan@cwmars.org>
49 files changed:
Open-ILS/src/cwopac_templates/kpac/getit.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/kpac/parts/footer.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/kpac/parts/header.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/advanced.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/browse.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/css/style.css.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/myopac/holds.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/myopac/lists.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/myopac/main.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/myopac/prefs_settings.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/myopac/update_username.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/acjs.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/adv_qtype_selector.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/browse_qtype_selector.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/config.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/cw-place_hold.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/footer.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/form.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/help.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/hold_status.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/home_searchbar.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/homesearch.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/login/form.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/login/help.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/login/password_hint.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/metarecord_hold_filters.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/misc_util.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/myopac/main_refund_policy.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/password_hint.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/place_hold.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/qtype_selector.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/record/addedcontent.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/record/awards.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/record/contents.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/record/copy_table.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/record/extras.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/record/marcextras.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/record/summary.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/result/copy_counts.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/result/lowhits.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/result/table.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/searchbar.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/seo_meta.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/table.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/topnav.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/topnav_links.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/parts/topnav_logo.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/password_reset.tt2 [new file with mode: 0644]
Open-ILS/src/cwopac_templates/opac/password_reset_msg.tt2 [new file with mode: 0644]

diff --git a/Open-ILS/src/cwopac_templates/kpac/getit.tt2 b/Open-ILS/src/cwopac_templates/kpac/getit.tt2
new file mode 100644 (file)
index 0000000..8161f75
--- /dev/null
@@ -0,0 +1,136 @@
+[%  
+    PROCESS "opac/parts/header.tt2";
+    PROCESS "opac/parts/misc_util.tt2"; # MARC 
+    WRAPPER "kpac/parts/subpage.tt2";
+    attrs = {marc_xml => ctx.marc_xml};
+    INCLUDE get_marc_attrs args=attrs;
+    ctx.page_title = attrs.title | html 
+%]
+
+<div id="search_results_parent">
+    [% INCLUDE 'kpac/parts/record_row.tt2' rec_id=ctx.bre_id%]
+</div>
+          
+<div class="checkout_options">
+    <table cellpadding="0" cellspacing="0" border="0">
+        <tr>
+            <td valign="top" class="left_brain_cell">
+                <div class="left_brain">
+
+                    [% WRAPPER 'kpac/parts/help_popups.tt2' popup_id='card_help' %]
+                        <img src="[% ctx.media_prefix %]/images/kpac/library_card.png" alt="[% l('library card') %]" /></div></td>
+                    [% END %]
+                    [% WRAPPER 'kpac/parts/help_popups.tt2' popup_id='password_help' %]
+                        <p>[% l('Enter your password') %]</p>
+                    [% END %]
+
+                    <div class="top_side">
+                        <h2>[% l('get it!') %]</h2>
+                        <p>[% l('If you would like to place a hold on this item, please enter the ' _
+                            'following information and click Submit below:') %]</p>
+                    </div>
+
+                    <form method='POST'><!-- login + place hold form -->
+
+                        <div class="checkout_box">
+                            <div class="box1_top">&nbsp;</div>
+                            <div class="box_inside">
+
+                                [% IF !ctx.user %]
+                                    [% seed = l(' Enter Numbers... ') %]
+                                    <p>[% l('Library Card Number without spaces:') %]</p>
+                                    <div class="input_box">
+                                        <input name="username" type="text" class="text_box" style="color:#aaa;" value="[% seed %]" 
+                                            onfocus="if(this.value=='[% seed %]'){this.value='';this.style.color='#424242';}" 
+                                            onblur="if(this.value==''){this.value='[% seed %]'; this.style.color='#aaa';}" />
+                                    </div>
+                                    <a class="help_btn" href="javascript:;" 
+                                        onclick="helpPopup('card_help', this, event);"><img 
+                                        src="[% ctx.media_prefix %]/images/kpac/question_mark.png" alt="[% l('pin number help') %]" /></a>
+
+                                    <div class="clear">&nbsp;</div>
+                                    <div class="hr">&nbsp;</div>
+
+                                    <p>[% l('Password') %]</p>
+                                    <div class="input_box">
+                                        <input name="password" type="password" class="text_box" style="color:#aaa;" value="[% seed %]" 
+                                            onfocus="if(this.value=='[% seed %]'){this.value='';this.style.color='#424242';}" 
+                                            onblur="if(this.value==''){this.value='[% seed %]'; this.style.color='#aaa';}" />
+                                    </div>
+
+                                    <a class="help_btn" href="javascript:;" 
+                                        onclick="helpPopup('password_help', this, event);"><img 
+                                        src="[% ctx.media_prefix %]/images/kpac/question_mark.png" alt="[% l('password help') %]" /></a>
+
+                                    <div class="clear">&nbsp;</div>
+                                    <div class="hr">&nbsp;</div>
+                                [% END %]
+
+                                <p>[% l('Choose a Pickup Library:') %]</p>
+                                <div class="pickup_lib">
+                                    [%  def_lib = ctx.default_pickup_lib || ctx.physical_loc;
+                                        PROCESS "opac/parts/org_selector.tt2";
+                                        INCLUDE build_org_selector name='pickup_lib' 
+                                        value=def_lib id='pickup_lib' 
+                                        can_have_vols_only=1 hold_pickup_lib=1 %]
+                                </div>
+                            </div>
+                        </div>
+                        <div class="submit_btn">
+                            <input type='hidden' name='action' value='hold'/>
+                            <input type='image' src="[% ctx.media_prefix %]/images/kpac/review_submit_btn.png" alt="[% l('Submit') %]"/>
+                        </div>
+                    </form>
+                </div>
+            </td>
+
+            <td valign="top">
+                <div class="right_brain">
+                    <div class="top_side">
+                        <h2>[% l('save it!') %]</h2>
+                        <p>[% l('If you would like to save this item to a list to be requested later, click Submit below.') %]</p>
+                        [% IF ctx.user AND ctx.bookbags AND ctx.bookbags.size > 0 %]
+                        <br/>
+                        <p>
+                            [% l('You may also save this item to a list you have already created by selecting one of your lists below.') %]
+                        </p>
+                        [% END %]
+                    </div>
+                    <form method='POST'>
+                        <input type='hidden' name='action' value='save'/>
+                        [% IF ctx.user AND ctx.bookbags AND ctx.bookbags.size > 0 %]
+                            <div class="checkout_box">
+                                <div class="box1_top">&nbsp;</div>
+                                <div class="box_inside">
+                                    <p>[% l('Add to one of your lists?') %]</p>
+                                    <select name='bookbag'>
+                                        <option value='' selected='selected'>[% l('-- Temporary List --') %]</option>
+                                        [% FOR bbag IN ctx.bookbags %]
+                                            <option value="[% bbag.id %]">[% bbag.name | html %]</option>
+                                        [% END %]
+                                    </select>
+                                </div>
+                            </div>
+                        [% END %]
+                        <div class="submit_btn">
+                            <input type='image' src="[% ctx.media_prefix %]/images/kpac/review_submit_btn.png" alt="[% l('Submit') %]" />
+                        </div>
+                    </div>
+                </div>
+            </td>
+        </tr>
+    </table>
+</div>
+
+<div class="sub_navigation2 checkout">
+    <table cellpadding="0" cellspacing="0" border="0" width="100%">
+        <tr>
+            [%  # in the absence of a sane referer, return to the detail page
+                url = ctx.kpac_root _ (ctx.referer.match('results') ? '/results' : '/record/' _ ctx.bre_id) %]
+            <td><a href="[% mkurl(url) %]"><img src="[% ctx.media_prefix %]/images/kpac/cancel_back_btn.png" /></a></td>
+            <td width="100%" class="nav_mid_bg">&nbsp;</td>
+        </tr>
+    </table>
+</div>
+         
+[% END %]
diff --git a/Open-ILS/src/cwopac_templates/kpac/parts/footer.tt2 b/Open-ILS/src/cwopac_templates/kpac/parts/footer.tt2
new file mode 100644 (file)
index 0000000..8770024
--- /dev/null
@@ -0,0 +1,11 @@
+<div class="footer_wrapper">
+V <a href="http://www.cwmars.org/content/contact-cw-mars-inc">Contact Us</a>
+<!--
+    <a href="javascript:;">[% l('Contact Us') %]</a>
+    <a href="javascript:;">[% l('Site Help') %]</a>
+    <a href="javascript:;">[% l('Site Map') %]</a>
+-->
+    <a href="[% mkurl(ctx.opac_root _ '/home') %]">[% l('Back to Main Catalog') %]</a>
+    <div class="clear">&nbsp;</div>
+</div>
+
diff --git a/Open-ILS/src/cwopac_templates/kpac/parts/header.tt2 b/Open-ILS/src/cwopac_templates/kpac/parts/header.tt2
new file mode 100644 (file)
index 0000000..bb53978
--- /dev/null
@@ -0,0 +1,38 @@
+<div class="main_header_wrapper">
+    <div class="logo_wrapper">
+        <a href="http://catalog.cwmars.org">
+            <span class="logo_left">&nbsp;</span>
+            <span class="logo_middle"><img src="[% ctx.media_prefix %]/images/kpac_small_logo.png" alt="[% l('CWMARS main catalog') %]" /></span>
+            <span class="logo_right">&nbsp;</span>
+        </a>
+    </div>
+
+    <div class="header_utils">
+<a href="http://catalog.cwmars.org">Main Catalog</a>
+        <!--
+        <a href="javascript:;" class="text_size_btn"><span>[% l('Text size') %]</span> &nbsp; <img 
+            alt="[% l('text size') %]" src="[% ctx.media_prefix %]/images/kpac/text_size_btn.png" /></a>
+        -->
+<!--
+        <a href="javascript:window.print()" class="print_btn"><span>[% l('Print') %]</span> &nbsp; <img 
+            alt="[% l('print') %]" src="[% ctx.media_prefix %]/images/kpac/print_btn.png" /></a>
+-->
+    </div>
+    <div class="header_menu">
+        <!-- menu rendered in reverse order -->
+        [% IF ctx.user %]
+            [% redir = CGI.url('-base' => 1) _ ctx.kpac_root _ '/home' %]
+            <a href="[% mkurl(ctx.logout_page, 
+                {redirect_to => redir.replace('^https:', 'http:')}, 1) %]">[% 
+                    l('Logout ([_1] [_2])', ctx.user.first_given_name, ctx.user.family_name) %]</a>
+        [% ELSE %]
+            <a href="[% mkurl(ctx.opac_root _ '/login').replace('^http:', 'https:') %]">[% l('Login') %]</a>
+        [% END %]
+<!--
+        <a href="javascript:;">[% l('Get a Library Card') %]</a>
+        <a href="javascript:;">[% l('Help') %]</a>
+-->
+    </div>
+    <div class="clear">&nbsp;</div>
+</div>
+
diff --git a/Open-ILS/src/cwopac_templates/opac/advanced.tt2 b/Open-ILS/src/cwopac_templates/opac/advanced.tt2
new file mode 100644 (file)
index 0000000..7743aa6
--- /dev/null
@@ -0,0 +1,52 @@
+[%- PROCESS "opac/parts/header.tt2";
+    WRAPPER "opac/parts/base.tt2";
+    INCLUDE "opac/parts/topnav.tt2";
+    ctx.page_title = l("Advanced Search");
+    pane = CGI.param("pane") || "advanced";
+    loc = ctx.search_ou;
+
+    ctx.metalinks.push('<meta name="robots" content="noindex">');
+-%]
+[%# The only two customizations in this file are to hide the Search the Catalog words
+    and add Go to to appear in front of Basic Search. The first was changed to clean up
+    the display. The second was member-suggested for clarity for patrons. - jfk
+%]
+    <h2 class="sr-only">[% l('Advanced Search') %]</h2>
+    <div id="search-wrapper">
+        <div id="search-box">
+<!--            <span class="search_catalog_lbl mobile_hide">[% l('Search the Catalog') %]</span> -->
+            <span class="adv_search_catalog_lbl">Go to <a href="[% mkurl(ctx.opac_root _ '/home') %]"
+                    id="home_adv_search_link">[%l('Basic Search')%]</a></span>
+
+            <span class="browse_the_catalog_lbl"><a href="[% mkurl(ctx.opac_root _ '/browse') %]">[%
+                    l('Browse the Catalog')%]</a></span>
+        </div>
+        <div id="adv_search_parent">
+            <div id="adv_search_tabs">
+                <a href="[% mkurl('', {pane => 'advanced'}) %]"
+                    [% IF pane == 'advanced' %]class="on" [% END %]
+                    id="adv_search">[% l('Advanced Search') %]</a>
+                <a href="[% mkurl('', {pane => 'numeric'}) %]"
+                    [% IF pane == 'numeric' %]class="on" [% END %]
+                    id="num_search">[% l('Numeric Search') %]</a>
+                <a href="[% mkurl('', {pane => 'expert'}) %]"
+                    [% IF pane == 'expert' %]class="on" [% END %]
+                    id="expert_search">[% l('Expert Search') %]</a>
+            </div>
+        </div>
+    </div>
+    <div id="content-wrapper">
+        <div id="main-content">
+            <div class="advanced_div">
+            [% IF pane == 'advanced' %]
+            [% INCLUDE "opac/parts/advanced/search.tt2" %]
+            [% ELSIF pane == 'numeric' %]
+            [% INCLUDE "opac/parts/advanced/numeric.tt2" %]
+            [% ELSIF pane == 'expert' %]
+            [% INCLUDE "opac/parts/advanced/expert.tt2" %]
+            [% END %]
+            </div>
+            <div class="common-full-pad"></div>        
+        </div>
+    </div>
+[% END %]
diff --git a/Open-ILS/src/cwopac_templates/opac/browse.tt2 b/Open-ILS/src/cwopac_templates/opac/browse.tt2
new file mode 100644 (file)
index 0000000..a770c19
--- /dev/null
@@ -0,0 +1,231 @@
+[%# The only customization in this file is to increase the blimit
+    in the section below to 25 from its default of 10. This is to
+    give browsers the feeling they are actually browsing rather
+    than looking at a little list.
+%]
+
+[%- # This is the bib and authority combined record browser.
+
+    PROCESS "opac/parts/header.tt2";
+    PROCESS "opac/parts/misc_util.tt2";
+    PROCESS "opac/parts/org_selector.tt2";
+    WRAPPER "opac/parts/base.tt2";
+    INCLUDE "opac/parts/topnav.tt2";
+
+    ctx.page_title = l("Browse the Catalog");
+    blimit = CGI.param('blimit') || ctx.opac_hits_per_page || 25;
+
+    depart_list = ['blimit', 'bterm', 'bpivot'];
+    ctx.metalinks.push('<meta name="robots" content="noindex">');
+%]
+
+    <h2 class="sr-only">[% l('Catalog Browse') %]</h2>
+    <div id="search-wrapper">
+        [%# XXX TODO Give searchbar.tt2 more smarts so we can just do:
+          # INCLUDE "opac/parts/searchbar.tt2" %]
+        <div id="search-box">
+            <span class="search_catalog_lbl"><a href="[% mkurl(ctx.opac_root _ '/home', {}, depart_list) %]" rel="nofollow" vocab="">[% l('Basic Search') %]</a></span>
+            <span class="adv_search_catalog_lbl"><a href="[% mkurl(ctx.opac_root _ '/advanced', {}, depart_list) %]"
+                    id="home_adv_search_link" rel="nofollow" vocab="">[%l('Advanced Search')%]</a></span>
+        
+            <span class="browse_the_catalog_lbl mobile_hide">[% l('Browse the Catalog') %]</span>
+        </div>
+    </div>
+    <div id="content-wrapper">
+        <div id="main-content">
+            <div id="browse-the-catalog">
+                <div id="browse-controls" class='searchbar'>
+                    <form method="get" onsubmit="$('browse-submit-spinner').className = ''; return true">
+                        <input type="hidden" name="blimit"
+                            value="[% blimit %]" />
+
+                        [% control_qtype = INCLUDE "opac/parts/qtype_selector.tt2"
+                            id="browse-search-class" browse_only=1 plural=1 %]
+
+                        [% control_bterm = BLOCK %]<input type="text" name="bterm" id="browse-term"
+                            value="[% CGI.param('bterm') | html %]" />[% END %]
+                        [% control_locg = INCLUDE build_org_selector id='browse-context'
+                            show_loc_groups=1
+                            arialabel=l('Select holding library') %]
+                        [% l('Browse for [_1] starting with [_2] in [_3]', control_qtype, control_bterm, control_locg) %]
+
+                       <input id='search-submit-go' type="submit" value="[% l('Browse') %]" alt="[% l('Browse') %]" class="opac-button"/>
+                        <img id="browse-submit-spinner" 
+                        src="[% ctx.media_prefix %]/opac/images/progressbar_green.gif" 
+                        class="hidden" style="width: 16px; height: 16px;" 
+                        alt="[% l('Search in progress icon') %]" />
+                    </form>
+                </div>
+
+                [% BLOCK browse_pager %]
+                <div class="browse-pager">
+                    [% IF ctx.back_pivot %]
+                    <a class="opac-button" href="[% mkurl('', {bpivot => ctx.back_pivot}) %]" onclick="$('browse-pager-spinner-[% id %]').className = '';" rel="nofollow" vocab="">&larr; [%l ('Back') %]</a>
+                    [% END %]
+                    [% IF ctx.pager_shortcuts;
+                        current_qtype = CGI.param('qtype') || 'title' %]
+                    <span class="browse-shortcuts">
+                        [% FOR shortcut IN ctx.pager_shortcuts %]
+                            <a href="[% mkurl('', {qtype => current_qtype, bterm => shortcut.0}, ['bpivot','query']) %]" rel="nofollow" vocab="">[% shortcut.1 %]</a>
+                        [% END %]
+                    </span>
+                    [% END %]
+
+                    [% IF ctx.forward_pivot %]
+                    <a class="opac-button" href="[% mkurl('', {bpivot => ctx.forward_pivot}) %]" onclick="$('browse-pager-spinner-[% id %]').className = '';" rel="nofollow" vocab="">[%l ('Next') %] &rarr;</a>
+                    [% END %]
+
+                    <img id="browse-pager-spinner-[% id %]" 
+                        src="[% ctx.media_prefix %]/opac/images/progressbar_green.gif" 
+                        class="hidden" style="width: 16px; height: 16px;" 
+                        alt="[% l('Search in progress icon') %]" />
+                </div>
+                [% END %]
+
+                [% PROCESS browse_pager id=0 %]
+
+                <div id="browse-results">
+                [% IF ctx.browse_error %]
+                    <span class="browse-error">
+                        [% l("An error occurred browsing records. " _
+                        "Please try again in a moment or report the issue " _
+                        "to library staff.") %]
+                    </span>
+                [% ELSE %]
+                    [% IF ctx.browse_leading_article_warning %]
+                    <div class="browse-leading-article-warning">
+                            [% l("Your browse term seems to begin with an article (a, an, the). You might get better results by omitting the article.") %]
+                            [% IF ctx.browse_leading_article_alternative %]
+                            <p>
+                            [% alternative_link = BLOCK %]
+                            <a href="[% mkurl('', {bterm => ctx.browse_leading_article_alternative}, ['bpivot']) %]" rel="nofollow" vocab="">[% ctx.browse_leading_article_alternative | html %]</a>
+                            [%-  END; # alternative_link BLOCK
+                                l("Did you mean [_1]?", alternative_link);
+                            END # IF %]
+                            </p>
+                    </div>
+                    [% END %]
+
+                    <ul class="browse-result-list">
+                    [% FOR result IN ctx.browse_results %]
+                        <li class="browse-result">
+                            <span class="browse-result-value[% result.row_number == 0 && !CGI.param('bpivot') ? ' browse-result-best-match' : '' %]">
+                                [% IF result.sources > 0 %] <!-- bib-linked browse value -->
+                                    <a href="[% mkurl(
+                                        ctx.opac_root _ '/results', {
+                                            'fi:has_browse_entry' => (result.browse_entry _ ',' _ result.fields)
+                                        }) %]" rel="nofollow" vocab="">[% result.value | html %]</a>
+                                    <span class="browse-result-sources">([%
+                                        IF result.accurate == 'f';
+                                            l("At least"); " ";
+                                        END;
+                                    result.sources %])</span>
+                                [% ELSE %] <!-- only authority links -->
+                                    [% result.value | html %]
+                                [% END %]
+                            </span>
+
+                            [% auth_headings_ul_added = 0; %]
+                                [% seenit = {}; # for headings we've rendered
+                                   FOR a IN result.sees;
+                                    PROCESS authority_notes authority=a;
+
+                                    # Other than displaying public general
+                                    # notes, we can go no further sans
+                                    # control_set.
+                                    NEXT UNLESS a.control_set;
+
+                                    # get_authority_fields is fast and cache-y.
+                                    acs = ctx.get_authority_fields(a.control_set);
+                                    FOR field_group IN a.headings;
+                                        field_id = field_group.keys.0;
+                                        field = acs.$field_id;
+                                        headings = field_group.values.0;
+                                        FOR h IN headings;
+                                            # We could display headings without
+                                            # links here when h.target is
+                                            # undef, if we wanted to, but note
+                                            # that h.target_count is only
+                                            # defined when h.target is.
+
+                                            IF h.target AND h.target_count AND result.list_authorities.grep('^' _ h.target _ '$').size == 0;
+                                                id = h.target; NEXT IF seenit.$id; seenit.$id = 1; 
+                                                IF !auth_headings_ul_added;
+                                                    # only add a <ul> if we have at least one <li> (WCAG 2.0)
+                                                    auth_headings_ul_added = 1; %]
+                                                <ul class="browse-result-authority-headings"> 
+                                                [% END %]
+
+                                                <li><span class="browse-result-authority-field-name">[% field.name %]</span>
+                                                <a href="[% mkurl(ctx.opac_root _ '/browse', {bterm => h.heading}, ['bpivot']) %]" rel="nofollow" vocab="">[% h.heading | html %]</a>
+                                                <span class="browse-result-authority-bib-links">([% h.target_count %])</span>
+                                                </li>
+                                            [% END %]
+                                        [% END %]
+                                    [% END %]
+                                [% END %]
+                                [% FOR a IN result.authorities; # I don't think we'll ever get here...
+                                    PROCESS authority_notes authority=a IF !sees.grep(a.id);
+
+                                    # Other than displaying public general
+                                    # notes, we can go no further sans
+                                    # control_set.
+                                    NEXT UNLESS a.control_set;
+
+                                    # get_authority_fields is fast and cache-y.
+                                    acs = ctx.get_authority_fields(a.control_set);
+                                    FOR field_group IN a.headings;
+                                        field_id = field_group.keys.0;
+                                        field = acs.$field_id;
+                                        headings = field_group.values.0;
+                                        FOR h IN headings;
+                                            # We could display headings without
+                                            # links here when h.target is
+                                            # undef, if we wanted to, but note
+                                            # that h.target_count is only
+                                            # defined when h.target is.
+
+                                            IF h.target AND h.target_count AND result.list_sees.grep('^' _ h.target _ '$').size == 0 AND !h.main_entry;
+                                                id = h.target; NEXT IF seenit.$id; seenit.$id = 1; 
+                                                IF !auth_headings_ul_added;
+                                                    # only add a <ul> if we have at least one <li> (WCAG 2.0)
+                                                    auth_headings_ul_added = 1; %]
+                                                <ul class="browse-result-authority-headings"> 
+                                                [% END %]
+                                                <li><span class="browse-result-authority-field-name">[% field.name %]</span>
+                                                <a href="[% mkurl(ctx.opac_root _ '/results', {query => 'identifier|authority_id[' _ h.target _ ']'}) %]" rel="nofollow" vocab="">[% h.heading | html %]</a>
+                                                <span class="browse-result-authority-bib-links">([% h.target_count %])</span>
+                                                </li>
+                                            [% END %]
+                                        [% END %]
+                                    [% END %]
+                                [% END %]
+                            [% IF auth_headings_ul_added %]</ul>[% END %]
+                        </li>
+                    [% END %]
+                    </ul>
+                [% END %]
+                </div>
+
+                [% PROCESS browse_pager id=1 %]
+            </div>
+
+            <div class="common-full-pad"></div>        
+        </div>
+    </div>
+
+    [% BLOCK authority_notes;
+        # Displays public general notes (sometimes called "scope notes" ?)
+        FOR note IN authority.notes %]
+            <div class="browse-public-general-note">
+                <span class="browse-public-general-note-label">
+                    [% l("Note:") %]
+                </span>
+                <span class="browse-public-general-note-body">
+                [% FOR piece IN note; piece | html; END %]
+                </span>
+            </div>
+        [% END;
+    END;    # end of BLOCK authority_notes %]
+
+[% END %]
diff --git a/Open-ILS/src/cwopac_templates/opac/css/style.css.tt2 b/Open-ILS/src/cwopac_templates/opac/css/style.css.tt2
new file mode 100644 (file)
index 0000000..c0c73a8
--- /dev/null
@@ -0,0 +1,2159 @@
+[%-
+    PROCESS "opac/parts/css/colors.tt2";
+    PROCESS "opac/parts/css/fonts.tt2";
+%]
+
+.suppress {
+   display:none;
+}
+
+body {
+    margin:0;
+    font-family: Arial, Helvetica, sans-serif;
+    font-size: [% css_fonts.size_base %];
+    background: [% css_colors.primary %];
+}
+
+button, input {
+    font-family: Arial, Helvetica, sans-serif;
+    font-size: [% css_fonts.size_base %];
+}
+
+img {
+    border: none;
+}
+
+#topnav_logo {
+    margin: 2em 0;
+}
+
+#homesearch_main_logo {
+    padding-top: 60px;
+    margin: auto;
+    width: 50%;
+}
+
+a {
+    color: [% css_colors.primary %];
+}
+
+#search-wrapper input[type=text] {
+    margin:0;
+    padding:0;
+}
+
+#search-wrapper select, .results_header_lbl select {
+    border:1px solid [% css_colors.border_standard %];
+    margin:0;
+    padding:0;
+    width: 12em;
+}
+
+.searchbar {
+    font-weight: bold;
+    padding-top: 10px;
+    margin-left: 1em;
+}
+
+/*
+#search-wrapper select {
+    border:0px solid [% css_colors.border_dark %];
+    filter:alpha(opacity=0);
+    -moz-opacity:0;
+    -khtml-opacity:0;
+    opacity:0;
+    padding:0;
+    margin:0;
+    height:18px;
+}
+*/
+h1 {
+    margin:0;
+    margin-bottom: 5px;
+    font-size: [% css_fonts.size_biggest %];
+    font-weight:normal;
+}
+
+h2 {
+    font-size: [% css_fonts.size_bigger %];
+    font-weight:bold;
+}
+
+h2.graphic880 {
+    font-size: [% css_fonts.size_bigger %];
+    font-weight:normal;
+}
+
+.hide_me, .hidden {
+    display: none;
+    visibility: hidden;
+}
+
+div.select-box-wrapper {
+    position:absolute;
+    padding-top:2px;
+    padding-left:3px;
+    overflow:hidden;
+    text-align:left;
+}
+
+#dash_wrapper {
+    margin-left: 0.5em;
+}
+
+#dash_wrapper div {
+    background: [% css_colors.primary %];
+    border-radius: 5px;
+    padding: 0em 1em;
+}
+
+.dash_divider {
+    margin: 1em;
+    color: [% css_colors.primary_fade %];
+    display:inline-block;
+}
+
+#dashboard {
+    margin-top: 1em;
+    height: 3em;
+}
+
+#dashboard span.dash-align a {
+    font-weight: bold;
+    text-decoration: none;
+}
+
+#dash_user {
+    font-weight: bold;
+}
+
+#logout_link { left: 1px; }
+
+#dash_checked { color: [% css_colors.text_attention %]; }
+#dash_holds { color: [% css_colors.text_attention %]; }
+#dash_pickup { color: [% css_colors.text_goodnews %]; }
+
+/*  
+#dash_fines { color: [% css_colors.text_badnews %]; }
+the color contrast between "text_badnews" and "primary"
+is too low for WCAG compliance.  Use "text_attention" 
+for now until a better color is picked - if needed.
+*/
+#dash_fines { color: [% css_colors.text_attention %]; }
+
+#dash_wrapper #dash_user_message_button_container {
+    display: inline;
+    padding: 0;
+}
+#dash_wrapper #unread_message_count_floater {
+    position: absolute;
+    background-color: [% css_colors.text_alert %];
+    padding-left: 0.2em;
+    padding-right: 0.2em;
+    display: inline-block;
+    font-size: 95%;
+    border-radius: 0;
+    z-index: 2;
+    margin-top: 0.2em;
+    margin-left: -1.5em;
+}
+
+#header-wrap {
+      background:#fff;
+/*    background: linear-gradient([% css_colors.primary %], [% css_colors.primary_fade %]); */
+/*    background: -moz-linear-gradient([% css_colors.primary %], [% css_colors.primary_fade %]); */
+/*    background: -o-linear-gradient([% css_colors.primary %], [% css_colors.primary_fade %]); */
+/*    background: -webkit-linear-gradient([% css_colors.primary %], [% css_colors.primary_fade %]); */
+/*    background-color: [% css_colors.primary_fade %]; */
+}
+#header {
+    color:#fff;
+/*    color: [% css_colors.background %]; */
+    margin-left: 1em;
+    margin-right: 1em;
+    font-size: [% css_fonts.size_small %];
+}
+
+#header a {
+    color: [% css_colors.background %];
+}
+
+#header a:hover {
+    color: [% css_colors.text_invert %];
+    text-decoration: none;
+}
+
+#header-links {
+    color: [% css_colors.text_invert %];
+    font-size: [% css_fonts.size_small %];
+    font-weight: bold;
+    position: relative;
+    top:4px;
+    
+}
+
+#header-links a {
+    color: [% css_colors.text_invert %];
+    display: block;
+    float:left;
+    margin-right:22px;
+    text-decoration: none;
+}
+
+#header-links a:hover {
+    color: [% css_colors.text_invert %];
+    text-shadow: 0 0 0.2em [% css_colors.primary %], 0 0 0.2em [% css_colors.primary %];
+    text-decoration: none;
+}
+
+#header #header-links2 {
+    position:relative;
+    top:-8px;
+    color: [% css_colors.text_invert %];
+    padding-bottom: 15px;
+}
+
+#header #header-links2 a {
+    color: [% css_colors.text_invert %];
+}
+
+#header #header-links2 a:hover {
+    text-decoration: underline;
+}
+
+#your-acct-login {
+    padding-top:2em;
+}
+
+#gold-links {
+    margin-left: 1em;
+    padding-left:0px;
+}
+
+#gold-links-home {
+    margin:auto;
+    padding-left:0px;
+}
+
+#gold-links-holder {
+    height: 24px;
+    background: [% css_colors.background_invert %];
+}
+
+#util-bar {
+    margin-left: 1em;
+    padding-left:0px;
+    height:0px;
+}
+
+#search-wrapper {
+    border-bottom: 1px solid [% css_colors.border_standard %];
+    padding-bottom: 5px;
+    background: [% css_colors.background %];
+}
+
+#search-wrapper #breadcrumb {
+    margin-top:0px;
+    font-size: [% css_fonts.size_smaller %];
+    float:left;
+}
+
+#search-wrapper #search-within {
+    margin-top:10px;
+    float:right;
+    position:relative;
+    left:-173px;
+}
+
+#search-wrapper #breadcrumb a {
+    color: [% css_colors.text %];
+}
+
+#search-wrapper #search_frm label {
+    font-size: [% css_fonts.size_smaller %];
+}
+
+#search-wrapper #search-box {
+    margin-left: 1em;
+    padding-left: 0px;
+    padding-top: 10px;
+    padding-bottom: 10px;
+}
+
+#adv_search_tabs, #acct_tabs, #acct_fines_tabs, #acct_checked_tabs, #acct_holds_tabs, #acct_prefs_tabs, #results_header_inner{
+    margin-left: 2px;
+    overflow: auto;
+}
+
+#adv_search_tabs a, #acct_tabs a, #acct_fines_tabs a, #acct_checked_tabs a, #acct_holds_tabs a, #acct_prefs_tabs a {
+    float: left;
+    text-align: center;
+    vertical-align: middle;
+    display: block;
+    margin: 10px 7px 0px 0px;
+    padding: 10px 0px 10px 0px;
+    -moz-border-radius: 10px 10px 0px 0px; 
+    border-radius: 10px 10px 0px 0px;
+    font-weight: bold;
+    color: [% css_colors.text_invert %];
+    background: [% css_colors.control %];
+    font-weight: bold;
+    text-decoration: none;
+}
+
+#adv_search_tabs a, #acct_tabs a, #acct_fines_tabs a {
+    padding: 1em 1em 0.5em;
+}
+
+#adv_search_tabs a:hover, #acct_tabs a:hover, #acct_fines_tabs a:hover, #acct_checked_tabs a:hover, #acct_holds_tabs a:hover, #acct_prefs_tabs a:hover {
+    background: [% css_colors.primary %]; 
+    color: [% css_colors.text_invert %];
+    text-decoration: none;
+}
+
+#adv_search_filters {
+    position: relative;
+}
+#adv_search_rows {
+    border-bottom: none;
+}
+.adv_filter_block {
+    padding: 15px;
+    float: left;
+    clear: both;
+}
+.adv_filter_block_item {
+    float: left;
+    padding: 5px;
+}
+
+#adv_special_block {
+    float: left;
+    padding: 5px;
+    margin-top: 5px;
+}
+
+#adv_search_submit {
+    position: relative;
+    margin-left: 10px;
+
+}
+
+.checkbox_col {
+    width: 1%;
+    padding-left: 10px !important;
+}
+
+#adv_search.on, #num_search.on, #expert_search.on {
+    color: [% css_colors.accent_darker %];
+    background: [% css_colors.background %];
+    text-decoration: none;
+}
+
+#adv_search_tabs a.acct-tab-on, #acct_tabs a.acct-tab-on, #acct_fines_tabs a.acct-tab-on {
+    color: [% css_colors.accent_darker %];
+    background: [% css_colors.background %];
+    text-decoration: none;
+}
+
+.acct-tab-off {
+    background: [% css_colors.control %];
+}
+
+#acct_checked_tabs a, #acct_holds_tabs a, #acct_prefs_tabs a {
+    margin-top: 0px;
+    font-size: [% css_fonts.size_smaller %];
+    color: [% css_colors.accent_darker %];
+    padding: 10px 10px 10px 10px;
+}
+
+#acct_checked_tabs div.selected a, #acct_holds_tabs div.selected a, #acct_prefs_tabs div.selected a {
+    background: [% css_colors.accent_lightest %];
+    color: [% css_colors.accent_darker %];
+}
+
+#acct_checked_tabs, #acct_holds_tabs, #acct_prefs_tabs {
+    padding-bottom: 12px;
+    color: [% css_colors.accent_medium %];
+}
+
+#acct_select, #acct_prefs_select {
+     display: none;
+}
+
+#mobile_acct_search_links {
+      background: [% css_colors.primary_fade %];
+}
+
+.rdetail_header {
+    padding: 5px 7px 6px 0px;
+    margin-left: 1em;
+    border-bottom: 1px dotted [% css_colors.accent_light %];
+}
+
+.rdetail_results a {
+    color:[% css_colors.primary_fade %];
+    font-weight:bold;
+    font-size: [% css_fonts.size_bigger %];
+}
+
+.rdetail_result_count {
+    color: [% css_colors.text %];
+    font-weight: normal;
+    padding-left: 1em;
+    display: inline-block;
+}
+
+.rdetail_result_nav {
+    font-weight:normal;
+    padding-left: 1em;
+    display: inline-block;
+}
+
+#rdetail_details_table {
+    margin-top: 15px;
+}
+
+#rdetail_image { border: none; }
+#rdetail_image_cell {
+    padding-top: 3px;
+    padding-right: 10px;
+}
+
+h2.rdetail_uris {
+    margin-top: 1em;
+}
+div.rdetail_uris {
+    padding: 0.5em 1em 0.5em 1em;
+    background-color: [% css_colors.accent_lighter2 %];
+}
+div.rdetail_uris ul li {
+    position: relative;
+    left: 1em;
+}
+
+div.rdetail_show_copies {
+    margin-top: 1em;
+}
+
+div#rdetail_actions_div {
+    float: right;
+    background: [% css_colors.background %];
+}
+
+span#rdetail_copy_counts {
+    display: inline-block;
+    border-right: thin;
+    vertical-align: top;
+    margin-right: 1em;
+    padding-right: 1em;
+}
+
+span#rdetail_hold_counts {
+    display: inline-block;
+    vertical-align: top;
+}
+span#rdetail_hold_counts p {
+    padding-left: 2em;
+}
+
+#rdetail_image_div {
+    float: left;
+    margin-right: 1em;
+}
+
+.rdetail_aux_utils {
+    border-left:1px dotted [% css_colors.accent_light %];
+    padding-left: 17px;
+    padding-bottom: 6px;
+    padding-right: 70px;
+}
+
+div.place_hold {
+    border-bottom: 1px dotted [% css_colors.accent_light %];
+    padding-top: 10px;
+}
+
+div.toggle_list { padding-top: 6px; }
+
+div.share_record {
+    padding-top: 6px;
+    border-top: 1px dotted [% css_colors.accent_light %];
+}
+
+div.format_icon {
+    float: right;
+    margin-right: 17px;
+}
+
+.result_util {
+    border-bottom: 1px dotted [% css_colors.accent_light %];
+    padding-top: 6px;
+}
+
+.results_aux_utils {
+    display: table-cell;
+}
+
+.result_util {
+    padding-left: 1em;
+}
+
+.results_reviews {
+    top: -5px;
+}
+
+#rdetail_copies {
+    padding-top: 1.5em;
+}
+
+#rdetails_status td {
+    padding: 7px 0px 3px 13px;
+    white-space: nowrap;
+}
+
+#rdetails_status td[headers=copy_header_library], 
+#rdetails_status td[headers=copy_header_shelfloc] {
+    white-space: normal;
+}
+
+#rdetails_status thead th {
+    background-color: [% css_colors.accent_lighter2 %];
+    padding: 13px 0px 13px 13px;
+    font-size: [% css_fonts.size_smaller %];
+    font-weight: bold;
+    text-align: left;
+}
+
+#rdetails_status tbody td {
+    padding-left: 13px;
+    text-align: left;
+}
+#rdetails_status tbody td.copy_note {
+    color: [% css_colors.primary %];
+    text-wrap:normal;
+    white-space:pre-wrap !important;
+    word-wrap:normal;
+}
+
+.rdetail_extras {
+/*    background: [% css_colors.primary_fade %]; */
+    background:#fff;
+/*    border: 1px solid [% css_colors.primary %]; */
+    padding-top:1px;
+    clear:both;
+}
+
+#rdetail_extras_div {
+    margin: 1em 0; 
+}
+
+/* .rdetail_extras_hr { */
+/*    height: 1px; */
+/*    background: [% css_colors.accent_light %]; */
+/*    margin-left: 1px; */
+/*    margin-right: 1px; */
+/* } */
+
+.rdetail_extras_link {
+    padding: 6px 12px;
+    font-size: [% css_fonts.size_smaller %];
+    font-weight: bold;
+}
+
+.rdetail_extras_lbl {
+      position:relative;
+      top:-4px;
+      left:7px;
+      color:#00593d
+/*    color: [% css_colors.text_invert %]; */
+/*    text-decoration: none; */
+}
+
+##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;
+}
+
+.almost-content-wrapper {
+    background: [% css_colors.background %];
+}
+
+#content-wrapper {
+    background: [% css_colors.background %];
+    min-height: 260px;
+    border-bottom: 1px solid [% css_colors.border_dark %];
+}
+
+.content-wrapper-record-page { top: -15px; position: relative; }
+
+#main-content-home {
+    padding-left: 17px;
+    margin-left: 1em;
+}
+#main-content {
+    padding-left: 0px;
+    margin: 0 1em;
+    clear: both;
+}
+
+#main-content-after-bar {
+    margin-left: 1em;
+    padding-left: 4px;
+}
+
+#results-side-bar { float: left; width: 174px; margin-right: 5px; background: [% css_colors.background %]; }
+
+#main-content .login_boxes {
+    border: 1px solid [% css_colors.accent_lighter %];
+    background: linear-gradient(bottom, [% css_colors.accent_ultralight %] 15%, [% css_colors.accent_lightest %] 55%, [% css_colors.accent_ultralight %] 85%);
+    background: -moz-linear-gradient(bottom, [% css_colors.accent_ultralight %] 15%, [% css_colors.accent_lightest %] 55%, [% css_colors.accent_ultralight %] 85%);
+    background: -ms-linear-gradient(bottom, [% css_colors.accent_ultralight %] 15%, [% css_colors.accent_lightest %] 55%, [% css_colors.accent_ultralight %] 85%);
+    background: -o-linear-gradient(bottom, [% css_colors.accent_ultralight %] 15%, [% css_colors.accent_lightest %] 55%, [% css_colors.accent_ultralight %] 85%);
+    background: -webkit-linear-gradient(bottom, [% css_colors.accent_ultralight %] 15%, [% css_colors.accent_lightest %] 55%, [% css_colors.accent_ultralight %] 85%);
+
+    color: [% css_colors.accent_darker %];
+}
+
+#main-content .login_boxes h1 {
+    font-weight: normal;
+    font-size: [% css_fonts.size_biggest %];
+    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;
+    margin:0;
+    padding:0;
+    background: [% css_colors.background %];
+    font-size: [% css_fonts.size_bigger %];
+    color: [% css_colors.text %];
+}
+
+#main-content .left_brain .input_bg {
+    padding:10px 10px 0px 13px;
+    width:167px;
+    height:29px;
+}
+
+.login-help-box {
+    float: left;
+    width: 200px;
+    text-align: center;
+    margin-left: 2em;
+}
+
+.login-help-button {
+    font-size: [% css_fonts.size_biggest %];
+    padding: 1.5em;
+}
+
+#login-failed-message {
+    font-size: [% css_fonts.size_bigger %];
+    font-weight: bold;
+    color: [% css_colors.text_alert %];
+    padding-top: 1em;
+}
+
+#holds_temp_parent td {
+    border-bottom:1px solid [% css_colors.border_standard %];
+}
+
+#holds_temp_parent input, #holds_temp_parent select {
+    margin:0;
+}
+
+#holds_temp_parent tr td div {
+    margin-top: 10px;
+    margin-bottom: 10px;
+}
+
+#holds_temp_parent tr td div.format_icon {
+    margin-top: 6px;
+    margin-bottom: 6px;
+    float: none;
+}
+
+#results_header_bar {
+    background: [% css_colors.accent_medium %];
+    border-top:1px solid [% css_colors.accent_mediumdark %];
+    border-bottom:1px solid [% css_colors.accent_mediumdark %];
+}
+
+.results_header_lbl {
+    font-weight: bold;
+    float: left;
+    color: [% css_colors.text %];
+    /* this border is not visible, but it keeps these labels the same size
+    as the buttons */
+    border: 1px solid [% css_colors.accent_medium %];
+    background: [% css_colors.accent_medium %];
+    margin: 0.5em 0.3em;
+    padding: 0.3em;
+}
+/* we need a negative margin on the select to allow the containing <label>
+to determine the actual size of the element.  By doing this, we can increase
+the odds that the buttons and the select will be the same size, and therefore
+collapse correctly when the window width decreases */
+.results_header_lbl select {
+    margin: -0.5em 0;
+}
+
+#limit_to_available {
+    vertical-align: middle;
+}
+
+.results_header_sel {
+    /* width: 88px; */
+    float:left;
+    margin:0;
+}
+
+.results_header_nav1 {
+    padding: 5px 7px 6px 0px;
+    border-bottom: 1px dotted [% css_colors.accent_light %];
+}
+
+.results_header_nav1 .h1 {
+    font-size: [% css_fonts.size_bigger %];
+    font-weight:bold;
+    color:[% css_colors.primary_fade %];
+}
+
+.table_no_border_space {
+  border-spacing: 0px;
+}
+.table_no_cell_pad td {
+  padding: 0px;
+}
+.table_no_border {
+  border-collapse: collapse;
+}
+
+#result_table_table {
+  margin-top:10px;
+}
+
+#result_table_div {
+    margin-top: 1em;
+}
+
+tr.result_table_row > td.results_row_count,
+tr.result_table_row > td.result_table_pic_header,
+tr.result_table_row > td.result_table_title_cell {
+    vertical-align: top;
+}
+
+.result_metadata {
+    float: left;
+    width: 30em;
+    padding-right: 2em;
+}
+
+tr.result_table_row:nth-child(n+2) > td {
+    border-top: 1px solid [% css_colors.accent_lighter2 %];
+}
+
+tr.result_table_row > td.result_table_pic_header {
+    white-space: nowrap;
+    width: 78px;
+    padding-left: 1em;
+}
+
+.result_number {
+    padding-left: 1em;
+    white-space: nowrap;
+}
+
+.result_count_number {
+   font-weight: bold;
+}
+
+.result_table_subtable {
+    width: 100%;
+    padding-top: 1em;
+}
+
+div.result_table_utils_cont {
+    text-align:left;
+    float: left;
+}
+
+.icon_text {
+}
+
+#myopac_summary_div p {
+    margin:0;
+    margin-bottom: 10px;
+}
+
+#acct_sum_checked_table td {
+    padding-bottom:5px;
+}
+
+.zero_search_hits_main { float:left; width:300px; margin-top: 2ex; }
+.zero_search_hits_saved { float:left; width:200px; margin-top: 2ex; margin-right: 2em; }
+
+#zero_search_hits p {
+    margin-top:0;
+}
+
+#zero_hits_term {
+    font-weight: bold;
+}
+
+#zero_search_hits #spell_check_link {
+}
+
+#zero_search_hits #zero_hits_suggestions {
+}
+
+#lowhits_help {
+    float: right;
+    width: 353px;
+    background: [% css_colors.accent_light %];
+    padding: 10px;
+    margin-top: 7px;
+}
+
+.results_info_table td {
+    padding-right: 10px;
+}
+
+#myopac_holds_main_table {
+    border-collapse: collapse;
+}
+
+#myopac_holds_main_table td {
+    border: 1px solid [% css_colors.border_dark %];
+    
+}
+
+#myopac_prefs_div .data_grid {
+    border-collapse:collapse;
+}
+
+#myopac_prefs_div .data_grid td {
+    background:[% css_colors.accent_ultralight %];
+    border-bottom:3px solid [% css_colors.background %];
+    padding:6px 0px 7px 17px;
+}
+
+.header_middle {
+    height:22px;
+    font-size: [% css_fonts.size_bigger %];
+    font-weight:bold;
+    color:[% css_colors.primary_fade %];
+    padding: 0px 7px 0px 0px;
+    border-bottom: 1px dotted [% css_colors.accent_light %];
+    clear: both;
+}
+
+.header_middle a {
+    font-weight: normal;
+}
+
+#acct_sum_block {
+     float:left;
+     clear:left;
+}
+
+.acct_sum_table {
+    border-collapse: collapse;
+    background: [% css_colors.accent_ultralight %];
+}
+
+.acct_sum_table tr {
+    border-bottom: 2px solid white;
+}
+
+.acct_sum_table td {
+    padding: 1em;
+}
+
+.acct_sum_table a {
+    text-transform: none;
+    position:relative;
+    top:-1px;
+}
+
+.acct_sum_table .view_link {
+    font-weight: normal;
+}
+
+table.acct_notes {
+    border-collapse: collapse;
+    margin: -1em 0 0.5em 0;
+}
+
+table.acct_notes * {
+    border: solid thin;
+    padding: 0.5em; 
+}
+
+table.acct_notes th {
+    font-weight: bold;
+}
+
+#myopac_sum_fines {
+    float:right;
+    padding: 15px 0px 0px 23px;
+    background: [% css_colors.accent_ultralight %];
+    width: 177px;
+    height: 166px;
+}
+
+#myopac_sum_fines_placehold { float: right; 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_main_header, #acct_holds_main_header, #acct_checked_hist_header, #acct_list_header, #acct_list_header_anon, #temp_list_holds, #acct_messages_main_header {
+    border-collapse: collapse;
+}
+
+.hold_notes {
+    text-transform: none;
+    font-weight: normal;
+}
+
+.hold_note_title { font-weight: bold; }
+
+#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, #acct_messages_main_header td {
+    background: [% css_colors.accent_lighter2 %];
+    padding: 10px;
+}
+
+#acct_checked_main_header th, #acct_holds_main_header th, #acct_checked_hist_header th, #acct_list_header th, #acct_list_header_anon th, #temp_list_holds th, #acct_messages_main_header th {
+    text-align: left;
+    padding: 0px 10px 0px 10px;
+}
+
+#acct_list_header select, #acct_list_header_anon select {
+    font-weight:normal;
+    text-transform:none;
+}
+
+.search_catalog_lbl {
+    font-size: [% css_fonts.size_bigger %];
+}
+.adv_search_catalog_lbl {
+    font-size: [% css_fonts.size_bigger %];
+}
+
+.browse_the_catalog_lbl {
+    font-size: [% css_fonts.size_bigger %];
+}
+
+.lbl1 {
+    font-size: [% css_fonts.size_bigger %];
+    font-weight:bold;
+}
+
+.lbl2 {
+    font-size: [% css_fonts.size_smaller %];
+    font-weight:normal;
+    position:relative;
+    top:3px;
+    max-width:300px;
+}
+
+#myopac_tabs, #adv_search_parent, #fines_payments_wrapper {
+    background: [% css_colors.primary_fade %];
+    padding-top:5px;
+    margin-bottom:20px;
+}
+
+#fines_payments_wrapper {
+    padding-left: 5px; 
+    padding-right: 5px;
+}
+
+.myopac_payments_table th { text-align: left; }
+.myopac_payments_table thead th { border-bottom: 1px dashed [% css_colors.accent_darker %]; }
+.myopac_payments_table thead th:first-child { width: 8em; }
+.myopac_payments_table tbody tr:nth-child(odd) { background-color: [% css_colors.accent_lighter %]; }
+.myopac_payments_table form { display: inline; }
+.myopac_payments_table input[type="submit"] { padding: 1px; }
+
+.payment-error {
+    font-weight: bold; color: [% css_colors.text_alert %];
+    padding: 10px; border: 1px solid [% css_colors.accent_medium_dark %];
+}
+
+.payment-processing {
+    font-weight: bold;
+    color: [% css_colors.text_greatnews %];
+    font-size: [% css_fonts.size_bigger %];
+    padding: 10px; border: 1px solid [% css_colors.accent_medium_dark %];
+    text-align: center;
+}
+#adv_search_input { width: 100%; }
+#adv_search_parent {
+    margin-bottom:0px;
+}
+#search-submit-spinner {
+    height: 16px;
+    width: 16px;
+}
+div.adv_search_available {
+    margin-top: 1em;
+}
+
+#myopac_loading {
+    width:100%;
+    text-align:center;
+    padding-top:20px;
+    font-size: [% css_fonts.size_bigger %];
+    font-weight:bold;
+}
+
+.chili_link {
+    width:100px !important;
+    text-align: center !important;
+}
+
+.chili_review div.chili_link div {
+    margin: auto;
+}
+
+[%- IF we_want_to_turn_on_facet_styling.defined; %]
+/* some facet styling */
+.facetClassContainer { margin: 2px; border: 1px solid [% css_colors.accent_light %]; }
+.facetClassLabelContainer { border: 1px solid [% css_colors.accent_light %]; }
+.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 [% css_colors.accent_light %];
+    color: [% css_colors.accent_mediumdark %];
+    width: 3em;
+    margin-right: 3px
+}
+.facetField { border-top: 1px solid [% css_colors.accent_light %]; }
+.facetFields { padding-left: 5px; }
+.facetFieldLineValue { overflow: hidden; text-overflow: ellipsis; }
+[%- END -%]
+
+div#facet_sidebar {
+    float: left;
+    margin-right: 1em;
+}
+
+.facet_box_temp {
+    padding-bottom:3px;
+}
+
+.facet_box_temp .header {
+    height: 2.3em;
+    background:[% css_colors.primary %];
+    -moz-border-top-left-radius: 5px;
+    border-top-left-radius: 5px;
+    -moz-border-top-right-radius: 5px;
+    border-top-right-radius: 5px;
+    font-weight:bold;
+    color:[% css_colors.text_invert %];
+    padding-top:4px;
+}
+
+.facet_box_temp .header .title {
+    float:left;
+    padding-top:6px;
+    padding-left:12px;
+}
+
+/* in this context, where h4 is primarily for structure, 
+   avoid the normal large font and margin for h4's */
+.facet_box_temp h4 {
+    font-size : 100%; 
+    margin: 0px;
+}
+
+.facet_box_temp .header a.button {
+    float:right;
+    padding-top:6px;
+    padding-right:6px;
+    color:[% css_colors.text_invert %];
+}
+
+.facet_box_wrapper .box_wrapper .box {
+    border-top:1px solid [% css_colors.border_standard %];
+    border-left:1px solid [% css_colors.border_standard %];
+    border-right:1px solid [% css_colors.border_standard %];
+    padding: 0 0.5em;
+    width: 14em;
+    overflow: hidden;
+}
+
+.facet_template {
+    box-sizing: border-box;
+    -moz-box-sizing: border-box;
+    display: table;
+    margin: 0.5em 0;
+    width: 100%;
+}
+
+.facet_template div {
+    display: table-cell;
+    padding: 2px;
+}
+
+.facet_template .count {
+    text-align: right;
+    color: [% css_colors.accent_mediumdark %];
+}
+
+.facet_template_selected {
+    background-color: [% css_colors.accent_lighter2 %];
+    border: 1px solid [% css_colors.accent_medium %];
+}
+
+#footer-wrap {
+    background: linear-gradient([% css_colors.primary_fade %], [% css_colors.primary %]);
+    background: -moz-linear-gradient([% css_colors.primary_fade %], [% css_colors.primary %]);
+    background: -o-linear-gradient([% css_colors.primary_fade %], [% css_colors.primary %]);
+    background: -webkit-linear-gradient([% css_colors.primary_fade %], [% css_colors.primary %]);
+    background-color: [% css_colors.primary %];
+}
+
+#footer {
+    padding-top:5px;
+    padding-bottom: 10px;
+    margin-left: 1em;
+    font-size: [% css_fonts.size_small %];
+}
+
+#footer a {
+    color: [% css_colors.text_invert %];
+    text-decoration: none;
+    text-shadow: 0 0 0.2em [% css_colors.primary %], 0 0 0.2em [% css_colors.primary %];
+}
+
+#copyright_text, #footer_logo {
+    color: [% css_colors.text_invert %];
+}
+
+.color_4 {
+    font-weight: bold;
+}
+
+.advanced_div { padding-top: 15px; }
+#adv_global_search { width: 100%; }
+#adv_global_search select { width: 13em; }
+#adv_global_addrow td { padding-top: 7px; }
+#adv_global_input_table { width: 100%; }
+#adv_global_input_table select { width: 7em; }
+.adv_adv_link {
+    font-size: [% css_fonts.size_smaller %];
+    color: [% css_colors.text_alert %];
+}
+#acct_prefs_header { float: left; }
+.search_page_nav_link {
+    cursor: pointer;
+    padding-left: 1em;
+}
+#opac.result.sort { width: 160px; }
+.renew-summary, .message-update-summary { font-size: [% css_fonts.size_bigger %]; font-style: italic; margin: 0.5ex 0; }
+.failure-text { margin-left: 4em; font-style: italic; color: [% css_colors.text_alert %]; }
+.refine-controls { font-size: [% css_fonts.size_bigger %]; padding: 0.5ex 0; }
+#adv_search_refine input[type=text] { border: 1px inset [% css_colors.accent_light %] !important; }
+#adv_search_refine select { border: 1px inset [% css_colors.accent_light %] !important; }
+#adv_search_refine {
+    padding-left: 5em; background-color: [% css_colors.accent_lighter2 %]; margin: 2ex 0;
+}
+.row-remover { position: relative; top: 1px; vertical-align: middle; }
+.subtle-button {
+    background-color: [% css_colors.background %];
+    color: [% css_colors.primary %]; text-decoration: none;
+    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: [% css_colors.background_alert %] !important; border: 0 !important; }
+
+#account-update-email table { text-align: center; padding: 20px; margin-top: 18px; border-collapse: collapse; }
+#account-update-email table td { padding: 5px 15px 5px 15px; border-bottom: 1px solid [% css_colors.accent_lighter %]; text-align: left;}
+#account-update-email-error { font-size: [% css_fonts.size_biggest %]; padding: 10px; border:1px solid [% css_colors.border_standard %];}
+a.dash-link:hover { text-decoration: underline !important; }
+#list_create_table td { vertical-align: middle; padding: 0 8px; }
+#list_create_table {
+    background-color: [% css_colors.accent_light %];
+    padding-bottom: 4px;
+    margin-bottom: 10px;
+    border-bottom: 1px dotted [% css_colors.accent_medium %];
+}
+.list-create-table-buttons input[type=image] { margin-top: 2px; }
+.result_table_format_cell { padding: 0px 10px; text-align: center; }
+.results_row_count { font-weight: bold; }
+#hold_editor h1 { font-size: [% css_fonts.size_bigger %]; font-weight: bold; }
+#hold_editor h2 { font-size: [% css_fonts.size_big %]; font-weight: normal; text-indent: 2em; font-style: italic; }
+#hold_editor h1, #hold_editor h2 { margin: 2px 0; }
+#hold_editor_table { background-color: [% css_colors.accent_lighter %]; padding: 0.5em; }
+#hold_editor_table th { text-align: right; padding-right: 1em; }
+#hold_editor_table td { padding: 0.25em 0; }
+.fmt-note { vertical-align: middle; padding-left: 1em !important; }
+.hold-editor-controls { text-align: center; padding-top: 1em !important; }
+.hold-editor-controls a { padding-left: 2em; }
+
+.text-right { text-align: right; }
+.text-right-top { text-align: right; vertical-align: top; }
+.rdetail-author-div {
+    padding-bottom: 10px;
+    display: inline-block;
+}
+
+.invisible { visibility: hidden; }
+.rdetail-extras-summary { margin: 10px; }
+.staff-hold { background-color: [% css_colors.accent_lightest %]; }
+.expert-search tbody tr th { text-align: right; padding-left: 2em; }
+.expert-search-row { padding-top: 10px; }
+#adv_expert_row label { font-weight: bold; }
+
+.bookshelf tr.browse_border td {
+    border-bottom: 1px dashed [% css_colors.accent_dark %];
+    font-size: 1px;
+    height: 1px;
+    padding-bottom: 1ex;
+}
+.cn_browse_item { padding: 2ex; }
+.results-paginator-list { padding-left: 1em; }
+.results-paginator-selected { color: [% css_colors.text_alert %]; }
+.inactive-hold { background: [% css_colors.accent_lightest %]; }
+.unread-patron-message { font-weight: bold; }
+
+#hold-items-list td { padding: 5px; margin-bottom: 20px; }
+.hold-items-list-title { font-size: [% css_fonts.size_bigger %]; }
+.hold-items-list-problem { color: [% css_colors.text_alert %]; }
+
+.hold_success_links > span { margin: 0 2em; }
+
+.mr_holds_no_formats { 
+  padding: 5px;
+  margin-left: 25px;
+  font-size: 110%;
+  font-weight: bold;
+  color: [% css_colors.text_invert %]; 
+  background: [% css_colors.primary %];
+}
+.holds_item_row_separator td {
+  border-top: 2px dashed [% css_colors.accent_medium %];
+}
+
+.big-strong {font-weight: bold; font-size: [% css_fonts.size_bigger %]; }
+
+.results_header_btns, .results_header_sel {
+    float:left;
+}
+
+/*
+ * .various_containers a = shortcut to putting .opac-button on every 'a' with
+ *     the tradeoff of increased stylesheet complexity (TODO: rethink?)
+ */
+
+.opac-multiline-button > a,
+.opac-button, .results_header_btns a, #simple-detail-view-links a, .dash_account_buttons a {
+    color: [% css_colors.button_text %];
+    font-weight: bold; 
+    text-decoration: none;
+    cursor: pointer !important;
+    -moz-border-radius: 5px;
+    border-radius: 5px;
+    border: 1px solid [% css_colors.primary %];
+    background:  [% css_colors.primary_fade %];
+    margin: 0.5em;
+    padding: 0.3em;
+    display: inline-block;
+}
+
+.opac-multiline-button > a:hover,
+.opac-button:hover, .results_header_btns a:hover, #simple-detail-view-links a:hover, #dash_wrapper a.opac-button:hover {
+    background: [% css_colors.primary %];
+}
+
+.opac-button:disabled {
+    color: [% css_colors.accent_medium %];
+    cursor: pointer !important;
+    border: 1px solid [% css_colors.accent_light %];
+    background-color: [% css_colors.accent_lighter %];
+}
+
+/* Firefox adds its own special space to inputs; this gets us closer */
+button.opac-button::-moz-focus-inner, input.opac-button::-moz-focus-inner {
+    padding: 0;
+    border: 0;
+}
+
+.opac-button-header, #dash_wrapper .opac-button {
+    background: [% css_colors.control %];
+    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
+    font-size: [% css_fonts.size_base %];
+}
+a.opac-button-header:hover, #dash_wrapper a.opac-button:hover {
+    border-color: [% css_colors.control %];
+}
+
+.opac-multiline-button > a {
+    display: inline-block;
+}
+
+#myopac_checked_div {
+    padding: 0px;
+}
+.opac-distinctive {
+   background-color: [% css_colors.distinct_medium %];
+}
+.opac-distinctive:hover {
+    background: [% css_colors.distinct_dark %];
+}
+
+.rdetail-mfhd-head {
+    margin-top: 5px;
+    padding-top: 5px;
+    background-color: [% css_colors.table_heading %];
+}
+
+.rdetail-mfhd-type {
+    padding-left: 1em;
+}
+
+.rdetail-mfhd-bottom {
+    border-bottom: thin solid [% css_colors.border_dark %];
+    width: 100%;
+}
+
+#rdetail_record_details {
+    clear: both;
+    margin-top: 1em;
+}
+
+.rdetail_content {
+    margin-left: 1.5em;
+    padding-left: 1.5em;
+}
+
+.rdetail_content_type, .rdetail_subject_type {
+    vertical-align: top;
+    font-weight: bold;
+}
+
+.bookbag-item-row td { vertical-align: top; }
+
+.error { color: [% css_colors.text_alert %]; font-weight: bold; }
+.success {
+    color: [% css_colors.text_greatnews %];
+    font-weight: bold;
+}
+
+.rdetail_related_subjects {
+    margin-top: 1.5em;
+}
+
+.rdetail_related_series {
+    margin-top: 1.5em;
+}
+
+#rdetail_openurl {
+    margin-top: 1em;
+}
+
+.rdetail_openurl_entry {
+    margin-left: 1em;
+    padding-left: 1em;
+}
+.bookbag-controls-holder { width: 100%; }
+.bookbag-controls-holder:nth-child(odd) { background-color: [% css_colors.accent_lighter2 %]; }
+.bookbag-controls-holder:nth-child(even) { background-color: [% css_colors.accent_lightest %]; }
+.bookbag-controls-holder .most {
+    padding-left: 0;
+    margin-right: 5em;
+}
+h2.bookbag-name { margin-bottom: 0em; padding-bottom: 0em; }
+.bookbag-share .fixed { min-width: 4em; }
+.bookbag-specific { margin-left: 1em; }
+.bookbag-specific div.sort { float: left; width: 45%; text-align: left; }
+.bookbag-specific div.meta { float: right; width: 54%; text-align: right; }
+#bbag-name-desc-form tr th { vertical-align: middle; }
+#bbag-name-desc-form .saver { vertical-align: middle; text-align: center; }
+.bookbag-description {
+    padding-top: 0em;
+    font-style: italic;
+    max-width: 40em;
+}
+#bbag-edit-description { width: 20em; }
+#bbag-edit-name { width: 20em; }
+textarea { font-family: sans-serif; }
+table.bookbag-specific {
+    border-right: 1px solid [% css_colors.accent_dark %];
+    border-bottom: 1px solid [% css_colors.accent_medium %];
+    margin-bottom: 2ex;
+}
+.bookbag-share {
+    float: left;
+    padding: 5px 0;
+}
+.bookbag-controls {
+    float: left;
+    padding: 5px 0px 0px 10px;
+}
+
+.bookbag-specific td.list_checkbox {
+    padding-left: 10px !important;
+}
+.bookbag-specific td.list_entry {
+    min-width: 10em;
+    padding-left: 5px !important;
+}
+.bookbag-specific td.list_actions {
+    white-space: nowrap !important;
+}
+.bookbag-paginator-selected { color: [% css_colors.text_alert %]; }
+
+.list_is_empty {
+    padding: 8px 0px 6px 0px;
+    width: 100%;
+    border: 0;
+    font-size: [% css_fonts.size_bigger %];
+    text-align: center;
+    font-style: italic;
+}
+.save-notes { padding-bottom: 1.5ex; }
+
+.nonbreaking-wrapper {
+    display: inline-block;
+}
+
+/* Moved from semiauto.css */
+.adv_global_input_container {
+    border-bottom: none;
+    clear: both;
+}
+.opac-auto-013 {
+    border-bottom: none;
+    *height: 0px;
+}
+.adv_global_filter_sort {
+    border: none;
+    width: 100%;
+}
+.clear-both { clear: both; }
+.common-no-pad {
+    clear: both;
+    height: 0px;
+    margin: 0px;
+    padding: 0px;
+}
+.common-full-pad {
+    clear: both;
+    height: 15px;
+}
+.alert { color: [% css_colors.text_alert %]; }
+.float-left { float: left; }
+.float-right { float: right; }
+
+.saved-searches-header { width: 100%; font-weight: bold; font-size: [% css_fonts.size_bigger %]; }
+.saved-searches-header .button { float: right; width: 28px; }
+.saved-searches-header .text { float: left; padding-right: 1em; margin: 0.5ex 0;}
+.saved-searches-header {font-weight: bold; font-size: [% css_fonts.size_bigger %]; }
+.saved-searches { border-bottom: 1px solid [% css_colors.accent_medium %]; padding-right: 1em; }
+#staff-saved-search { /* wraps .saved-searches-header and .saved-searches on the record page */
+    border-right: 1px solid [% css_colors.accent_darker %];
+}
+.result_item_circulated {
+    padding-top: 4px;
+}
+
+.result_item_circulated span {
+    position: relative;
+    top:-3px;
+    left:3px;
+}
+
+#search-only-bookbag-container { margin: 2ex 0; font-weight: bold; }
+#result-bookbag-heading { text-align: center; margin: 2ex; }
+
+.result-bookbag-name { font-size: [% css_fonts.size_bigger %]; font-weight: bold; }
+.result-bookbag-description { font-size: [% css_fonts.size_bigger %]; font-style: italic; }
+.result-bookbag-item-note { font-style: italic; }
+.lowhits-bookbag-name { font-weight: bold; }
+.oils_AS { font-weight: bold; color: [% css_colors.text_match %]; }
+.oils_AS_match_term { text-align: left; color: [% css_colors.text %]; }
+.oils_AS_match_field {
+    font-size: [% css_fonts.size_smallest %]; padding: 0.65em 0;
+    text-align: right; color: [% css_colors.accent_medium %];
+}
+table.result_holdings_table {
+    margin-top: 1em;
+    margin-bottom: 1em;
+}
+table.result_holdings_table thead tr {
+    background: [% css_colors.table_heading %];
+}
+table.result_holdings_table thead tr th {
+    font-weight: bold;
+}
+span.preflib {
+    margin: 0 2em 0 2em;
+}
+a.preflib_change {
+  vertical-align: super;
+  font-size: [% css_fonts.size_smaller %];
+  line-height: normal;
+  text-decoration: none;
+}
+.rdetail-holding-group { margin-left: 1.5em; }
+.rdetail-holding-group span { margin-left: 1.5em; }
+.rdetail-holding-group .paging { margin-left: 1.5em; }
+#rdetail_deleted_exp {
+    font-weight: bold;
+    padding: 1em;
+    margin: 1em;
+    border: thick solid [% css_colors.border_alert %];
+}
+
+#ac_tab_wrapper { width : 100%; }
+.ac_tab { float: left; padding-right: 10px; font-size: [% css_fonts.size_big %]; padding: 5px; border: 1px solid [% css_colors.primary_offset %]; }
+.ac_tab_selected { background-color: [% css_colors.primary_offset %]; }
+.ac_tab_selected a { color: [% css_colors.text_invert %]; }
+#ac_content { clear: both; width: 100%; margin-top: 10px; }
+
+/* Popmenu styles used for making css menus. */
+.popmenu {
+    margin: 0;
+    padding: 0;
+}
+.popmenu li {
+    list-style: none;
+}
+.popmenu li a {
+    display: block;
+    padding: 3px 5px;
+}
+.popmenu li ul {
+    display: none; 
+    width: 10em; /* Width to help Opera out */
+    background-color: [% css_colors.primary %];
+}
+.popmenu li:hover ul {
+    display: block;
+    position: absolute;
+    margin: 0;
+    padding: 0;
+    border-color: [% css_colors.border_dark %];
+    border-width: 1px;
+    border-style: solid;
+}
+.popmenu li:hover li {
+    float: none;
+}
+.popmenu li:hover li a {
+    background-color: [% css_colors.primary %]; 
+    color: [% css_colors.accent_ultralight %];
+}
+.popmenu li li a:hover {
+    background-color: [% css_colors.accent_ultralight %]; 
+    color: [% css_colors.primary %];
+}
+/* Styles for the temporary list entry. */
+.popmenu li:hover li[class~="temporary"] a {
+    background-color: [% css_colors.primary %]; 
+    color: [% css_colors.accent_ultralight %];
+}
+.popmenu li li[class~="temporary"] a:hover {
+    background-color: [% css_colors.accent_ultralight %]; 
+    color: [% css_colors.primary %];
+}
+/* Styles for the default list entry. */
+.popmenu li:hover li[class~="default"] a {
+    background-color: [% css_colors.primary %]; 
+    color: [% css_colors.accent_ultralight %];
+}
+.popmenu li li[class~="default"] a:hover {
+    background-color: [% css_colors.accent_ultralight %]; 
+    color: [% css_colors.primary %];
+}
+/* Styles for the new list entry. */
+.popmenu li:hover li[class~="new"] a {
+    background-color: [% css_colors.primary %]; 
+    color: [% css_colors.accent_ultralight %];
+}
+.popmenu li li[class~="new"] a:hover {
+    background-color: [% css_colors.accent_ultralight %]; 
+    color: [% css_colors.primary %];
+}
+/* Style to add a divider on the menu. */
+.popmenu li li[class~="divider"] {
+    border-bottom-width: 1px;
+    border-bottom-color: [% css_colors.border_dark %];
+    border-bottom-style: solid;
+}
+    
+#locale_picker_form {
+    float: right;
+    padding: 0.5em;
+    margin-top: 2em;
+    border-right: thin [% css_colors.control %] solid;
+}
+
+#locale_picker_form * {
+    margin: 0;
+    padding: 0;
+    vertical-align: middle;
+}
+
+#patron_usr_barcode_not_found {
+    font-weight: bold; color: [% css_colors.text_alert %];
+}
+
+.record_title {
+    font-weight: bold;
+}
+
+.record_author {
+    font-style: italic;
+}
+
+.password_message {
+    padding-top: 1em;
+    padding-bottom: 0.5em;
+       font-style: italic;
+}
+
+#maintenance_message {
+    padding: 5px;
+    width: 100%;
+    background-color: [% css_colors.text_alert %];
+    color: [% css_colors.text_invert %];
+    text-align: center;
+}
+
+#search-box > span {
+    margin: 0 1em;
+}
+.browse-error {
+    font-weight: bold;
+    font-color: #c00;
+}
+.browse-result-sources, .browse-result-authority-bib-links {
+    margin-left: 1em;
+}
+.browse-result-best-match {
+    font-weight: bold;
+}
+.browse-pager {
+    margin: 2ex 0;
+}
+.browse-result-list {
+    padding-bottom: 0.5ex;
+}
+.browse-shortcuts {
+    font-size: [% css_fonts.size_bigger %];
+}
+.browse-result-authority-field-name {
+    font-style: italic;
+    margin-right: 1em;
+}
+.browse-leading-article-warning {
+    font-style: italic;
+    font-size: [% css_fonts.size_big %];
+}
+.browse-public-general-note {
+    font-size: [% css_fonts.size_big %];
+}
+.browse-public-general-note-label { }
+.browse-public-general-note-institution {
+    font-style: normal;
+    font-weight: bold;
+}
+.browse-public-general-note-body {
+    font-style: italic;
+}
+
+.bib_peer_type {
+    font-weight: bold;
+}
+
+#main-content-register {
+    margin-left: 40px;
+    font-size: [% css_fonts.size_bigger %];
+}
+
+#main-content-register table { 
+    padding: 20px; 
+    margin-top: 18px; 
+    border-collapse: collapse;
+}
+
+#main-content-register td {
+    text-align: left;
+}
+
+#main-content-register td:not(:first-child) {
+    padding-left: 20px;
+}
+
+.patron-reg-invalid {
+    font-weight: bold;
+    color: red;
+    padding-right: 10px;
+}
+
+.result_footer_nav1 {
+    clear: both;
+}
+
+.small_view_only, #refine_hits, #return_to_hits {
+    display: none;
+}
+
+.rdetail_authors_div {
+    margin-bottom: 1em;
+}
+
+#search_query_label, #search_qtype_label, #search_itype_label, #search_locg_label {
+    white-space: nowrap;
+    display: inline-block;
+}
+
+.result_table_title_cell {
+    padding-top: 4px;
+    padding-bottom: 4px;
+}
+
+.record_title {
+    font-size: [% css_fonts.size_bigger %];
+}
+
+/* styling for sms text call number */
+.sms_text pre {
+    font-family: Arial, Helvetica, sans-serif;
+    font-size: [% css_fonts.size_medium %];
+    background: [% css_colors.accent_lightest %];
+    padding: .5%;
+    /* Allow text to wrap */
+    white-space: pre-wrap;       /* css-3 */
+    white-space: -moz-pre-wrap;  /* Mozilla, since 1999 */
+    white-space: -pre-wrap;      /* Opera 4-6 */
+    white-space: -o-pre-wrap;    /* Opera 7 */
+    word-wrap: break-word;       /* Internet Explorer 5.5+ */
+}
+
+.mobile_view {
+   display:none;
+}
+
+/* patron message center */
+#myopac_message_tbody {
+    vertical-align: top;
+}
+.myopac_message_message {
+    white-space: pre-wrap;
+}
+
+@media only screen and (max-width: 800px) {
+    .facet_sidebar_hidden, .result_block_hidden {
+        display: none;
+    }
+    .facet_sidebar_visible, .result_block_visible {
+        display: inline ! important;
+    }
+    #acct_select, #acct_prefs_select {
+        display: inline-block;
+    }
+#acct_tabs, #acct_prefs_tabs {
+         display:none;
+     }
+}
+
+@media only screen and (max-width: 600px) {
+    input, select {
+        font-size: [% css_fonts.size_big %];
+    }
+    span .nav_arrow_fix {
+        display: none;
+    }
+    #header {
+        padding: 0px;
+        margin: 0px;
+    }
+    #homesearch_main_logo img {
+        width:75%;
+    }
+    #format_selector {
+        display:none;
+    }
+    #your-acct-login {
+        padding: 0px;
+        padding-top: 5px;
+    }
+    #your-acct-login a {
+        margin: 0px;
+        padding: 5px;
+    }
+    #topnav_logo {
+        margin: 0;
+    }
+    #topnav_logo img {
+        width: 200px;
+    }
+    #locale_picker_form {
+        display: none;
+    }
+    #gold-links-holder {
+        display: none;
+    }
+    #simple-detail-view-links {
+        display: none;
+    }
+    #acct_tabs a, #acct_fines_tabs a {
+       padding: 2px 4px 3px 4px;
+       -moz-border-radius: 6px 6px 0px 0px;
+       border-radius: 6px 6px 0px 0px;
+       font-size: [% css_fonts.size_base %];
+       margin: 0px 5px 0px 0px;
+    }
+
+    #dash_wrapper div {
+        background: transparent;
+        padding: 0px;
+    }
+    #dash_wrapper {
+        position: static;
+        top: auto;
+    }
+    #dash_wrapper .opac-button {
+        top: 0px;
+    }
+    .small_view_only {
+        display: inline !important;
+    }
+    #dash_identity a {
+        float:left;
+    }
+    #dashboard {
+        display: none;
+    }
+    #holds_box form blockquote {
+        margin-left: 10px;
+        margin-right: 2px;
+    }
+    #holds_box form blockquote select {
+        width: 100%;
+    }
+    #myopac_sum_fines_placehold {
+        display:none;
+    }
+    #myopac_sum_fines {
+        display: none;
+    }
+    .results_header_lbl {
+        display: none;
+    }
+    .results_header_nav1 span.h1 {
+        display: none;
+    }
+    .preflib {
+        display: none;
+    }
+    .start_end_links_span {
+        display: block;
+    }
+    .invisible {
+        display: none;
+    }
+    .result_table_pic_header {
+        padding-left: 0px !important;
+        padding-right: 5px;
+        width: 0px !important;
+        margin: 0px;
+    }
+    .result_table_pic {
+        width: 55px;
+        padding: 0px;
+        margin: 0px;
+    }
+    tr[name=results_isbn_tr], tr[name=results_phys_desc_tr], tr[name=results_pub_tr] strong, .result_count {
+         display: none;
+    }
+    tr.result_table_title_cell[name=bib_cn_list] .result_holdings_table th:nth-child(4),
+    tr.result_table_title_cell[name=bib_cn_list] .result_holdings_table td:nth-child(4) {
+        display:none;
+    }
+    .results_info_table td {
+        padding: 0px;
+    }
+    #results_header_bar {
+        background-color: inherit;
+    }
+    .results_header_btns a {
+        margin: 0.3em;
+    }
+    #main-content {
+        margin: 0 1px;
+    }
+    #rdetails_status thead {
+        display: none;
+    }
+    #rdetails_status tr {
+       display: block;
+       margin-top: 3px;
+    }
+    #rdetails_status td {
+       display: block;
+       padding: 1px;
+    }
+    .copy_details_row {
+       background-color: [% css_colors.accent_lightest %];
+    }
+    .copy_details_offers_row {
+       background-color: [% css_colors.accent_lightest %];
+    }
+    select#pickup_lib.search-wrapper-locg {
+        width: 100%;
+    }
+    #search-wrapper #search-box {
+        width: 85%;
+        padding-top: 5px;
+    }
+    #main-content-home {
+        padding: 0px;
+        margin: 0px;
+    }
+    /* Make use of full width in mobile mode */
+    .facet_box_wrapper .box_wrapper .box,
+    .facet_template .facet,
+    .facet_box_temp {
+        width: inherit;
+    }
+    .facet_template .count {
+        padding-left: 1em;
+    }
+    #facet_sidebar {
+        margin-top: 0.5em;
+    }
+    #adv_search_parent {
+        font-size: [% css_fonts.size_smaller %];
+    }
+    #adv_search_filters {                                                                                                                             
+        position: relative;                                                                                                                           
+        width: 300px;
+    }
+    #format_actions {
+        float: left;
+    }
+    .rdetail_aux_utils {
+        padding: 0px;
+        border: none;
+    }
+    .result_metadata {
+        width: inherit;
+    }
+    div#rdetail_actions_div {
+        float: none;
+    }
+    h2.rdetail_uris {
+        clear: both;
+    }
+    .search_catalog_lbl {
+       margin-left: 0;
+       white-space: nowrap;
+    }
+    .adv_search_catalog_lbl { 
+        margin-top: 0;
+       white-space: nowrap;
+    }
+    .browse_the_catalog_lbl {
+        white-space: nowrap;
+    }
+    .mobile_hide {
+       display: none;
+    } 
+    #dash_user {
+        display: block;
+        padding: 0.5em;
+    }
+    .dash_divider {
+       display: none;
+    }
+    .dash_account_buttons {
+        display: block;
+    } 
+    .searchbar { line-height: 1.5em; }
+    #browse-controls { line-height: 1.5em; }
+    #search_query_label, #search_qtype_label, #search_itype_label, #search_locg_label {
+        display: block;
+    }
+    .bookshelf td {
+       display: block;
+       width: 100%;
+    }
+    .bookshelf table thead tr {
+       display: block;
+    }
+    #lowhits_help { width: inherit; }
+    #adv_search_tabs a{                                                                                                                           
+        font-size: [% css_fonts.size_small %];
+        margin: 2px 2px 0px 2px;
+        padding: 2px 2px 5px 2px; 
+        -moz-border-radius: 10px 0px 0px 0px;
+        border-radius: 7px 7px 0px 0px;                                                                                                           
+    }
+    #adv_global_tbody td {
+        border-bottom: thin solid [% css_colors.accent_light %];
+    }
+    #adv_global_addrow td {
+        border-bottom: none;
+    }
+        /* Force table to not be like tables anymore */
+        table#acct_checked_main_header thead tr th {
+                display: block;
+        }
+        table#acct_checked_main_header tbody tr td {
+                display: block;
+        }
+
+        /* Hide table headers (but not display: none;, for accessibility) */
+        thead tr {
+                position: absolute;
+                top: -9999px;
+                left: -9999px;
+        }
+
+        table#acct_checked_main_header tr { border: 1px solid #ddd; }
+
+        table#acct_checked_main_header td {
+                /* Behave  like a "row" */
+                border: none;
+                border-bottom: 1px solid #eee;
+                position: relative;
+                padding-left: 40%;
+        }
+
+        table#acct_checked_main_header td:before {
+                /* Now like a table header */
+                position: absolute;
+                /* Top/left values mimic padding */
+                left: 2px;
+                width: 40%;
+                padding-right: 10px;
+                white-space: nowrap;
+        }
+
+        table#acct_checked_main_header td:nth-of-type(1) { border-top: 5px solid #aaa; padding-top: 15px; background-color: #fff;}
+        table#acct_checked_main_header td:nth-of-type(2):before { content: "[% l('Title / Author') %]";}
+        table#acct_checked_main_header td:nth-of-type(3):before { content: "[% l('Renewals Left') %]"; }
+        table#acct_checked_main_header td:nth-of-type(4):before { content: "[% l('Due Date') %]"; }
+        table#acct_checked_main_header td:nth-of-type(5):before { content: "[% l('Barcode') %]"; }
+        table#acct_checked_main_header td:nth-of-type(6):before { content: "[% l('Call number') %]"; }
+
+        table#acct_holds_main_header thead tr th {
+                display: block;
+        }
+        table#acct_holds_main_header tbody tr td {
+                display: block;
+        }
+
+        table#acct_holds_main_header td {
+                /* Behave  like a "row" */
+                border: none;
+                border-bottom: 1px solid #eee;
+                position: relative;
+                padding-left: 40%;
+        }
+
+
+        table#acct_holds_main_header td:before {
+                /* Now like a table header */
+                position: absolute;
+                /* Top/left values mimic padding */
+                left: 2px;
+                width: 40%;
+                padding-right: 10px;
+                white-space: nowrap;
+        }
+
+        table#acct_holds_main_header td:nth-of-type(1) { border-top: 5px solid #aaa; padding-top: 15px; background-color: #fff;}
+        table#acct_holds_main_header td:nth-of-type(2):before { content: "[% l('Title') %]";}
+        table#acct_holds_main_header td:nth-of-type(3):before { content: "[% l('Author') %]"; }
+        table#acct_holds_main_header td:nth-of-type(4):before { content: "[% l('Format') %]"; }
+        table#acct_holds_main_header td:nth-of-type(5):before { content: "[% l('Pickup Location') %]"; }
+        table#acct_holds_main_header td:nth-of-type(6):before { content: "[% l('Activate') %]"; }
+        table#acct_holds_main_header td:nth-of-type(7):before { content: "[% l('Cancel on') %]"; }
+        table#acct_holds_main_header td:nth-of-type(8):before { content: "[% l('Active') %]"; }
+        table#acct_holds_main_header td:nth-of-type(9):before { content: "[% l('Status') %]"; }
+        table#acct_holds_main_header td.hold_notes:before { content: "[% l('Notes') %]"; }
+
+       /*Want to see these in mobile ONLY */
+       .mobile_view{
+          display:block;
+       }
+
+       .mobile_search_lbl_clr{
+          color:[% css_colors.mobile_header_text %];
+       }
+}
+
+
+/* 
+For text which is visible only to screen readers.
+Borrowed from http://getbootstrap.com/css/#helper-classes-screen-readers 
+See also http://webaim.org/techniques/css/invisiblecontent/
+*/
+.sr-only {                                                                     
+    position: absolute;                                                          
+    width: 1px;                                                                  
+    height: 1px;                                                                 
+    padding: 0;                                                                  
+    margin: -1px;                                                                
+    overflow: hidden;                                                            
+    clip: rect(0, 0, 0, 0);                                                      
+    border: 0;                                                                   
+}
+
+/* 
+jfk added style for inline tooltip
+*/
+
+a.tooltips {
+  position: relative;
+  display: inline;
+  outline: none;
+}
+a.tooltips strong {line-height: 30px;}
+a.tooltips hover {text-decoration: none;}
+
+a.tooltips span {
+  z-index:10;display:none; padding: 14px 20px;
+  margin-top: -30px; margin-left:28px;
+  width:300px; line-height:16px;
+}
+
+a.tooltips:hover span {
+  display:inline; position:absolute; color:#111;
+  border:1px solid #DCA; background:#FFFAF0;
+} 
+.callout {z-index:20; position:absolute; top:30px;border:0;left:-12px;}
diff --git a/Open-ILS/src/cwopac_templates/opac/myopac/holds.tt2 b/Open-ILS/src/cwopac_templates/opac/myopac/holds.tt2
new file mode 100644 (file)
index 0000000..9db6fb7
--- /dev/null
@@ -0,0 +1,228 @@
+[%  PROCESS "opac/parts/header.tt2";
+    PROCESS "opac/parts/misc_util.tt2";
+    PROCESS "opac/parts/hold_status.tt2";
+    WRAPPER "opac/parts/myopac/base.tt2";
+    myopac_page = "holds";
+    limit = (ctx.holds_limit.defined) ? ctx.holds_limit : 0;
+    offset = (ctx.holds_offset.defined) ? ctx.holds_offset : 0;
+    count = (ctx.holds_ids.size.defined) ? ctx.holds_ids.size : 0;
+%]
+<h3 class="sr-only">[% l('My Holds') %]</h3>
+<div id='myopac_holds_div'>
+
+    <div id="acct_holds_tabs">
+        <div class="align selected">
+            <a href='#'>[% l("Items on Hold") %]</a>
+        </div>
+        <div class="align">
+            <a href='[% mkurl('hold_history', {}, ['limit','offset','available']) %]'>[% l("Holds History") %]</a>
+        </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 class='float-left' style='padding-left: 10px;'>
+            <a href='[% mkurl('holds', {limit => limit,offset => (offset - limit)}) %]'
+                [% IF offset <= 0 %] class='invisible' [% END %]><span class="nav_arrow_fix">&#9668;</span>[% l('Previous') %]</a>
+            [% IF offset > 0 || count > limit;
+                curpage = 0;
+                WHILE curpage * limit < count;
+                    IF curpage * limit == offset;
+            %]
+            [% curpage + 1 %]
+                    [%- ELSE %]
+            <a href='[% mkurl('holds', {limit => limit, offset => (curpage * limit)}) %]'>[% curpage + 1 %]</a>
+                    [%- END;
+                    curpage = curpage + 1;
+                END;
+            END %]
+            <a href='[% mkurl('holds', {limit => limit, offset => (offset + limit)}) %]'
+               [% IF count <= limit + offset %] class='invisible' [% END %] >[% l('Next') %]<span class="nav_arrow_fix">&#9658;</span></a>
+        </span>
+
+        <span style="float:right;">
+            <a class="hide_me" href="#">[% l('Export List') %]</a>
+        </span>
+    </div>
+    <div class="clear-both"></div>
+    <div id='holds_main'>
+        <form method="post">
+        <table class="table_no_border_space table_no_cell_pad opac-auto-097"
+            title="[% l('Actions for Items on Hold') %]">
+            <tr>
+                <td>
+                    <select name="action" id="acct_holds_actions" 
+                      title="[% l('Select your action for the selected holds') %]">
+                        <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 style="padding-left:9px;">
+                    <input type="submit" value="[% l('Go') %]"
+                        title="[% l('Go') %]" class="opac-button" />
+                </td>
+                <td width="1" style="padding-left:5px;">
+<!--
+                    <a href="#"><img
+                        alt="[% l('Holds Help') %]"
+                        title="[% l('Actions for selected holds') %]"
+                        src="[% ctx.media_prefix %]/images/question-mark.png" /></a>
+-->
+                </td>
+                <td style="padding-left:5px;" class='error'>
+                    [%  IF ctx.hold_suspend_post_capture;
+                            l('One or more holds could not be suspended because the item is at (or en route to) the pickup library.');
+                        END;
+                    %]
+                </td>
+                <td align="right">
+                    [% IF CGI.param("available") -%]
+                    <a href="[% mkurl('holds', {}, ['limit','offset','available']) %]">[% l('Show all holds') %]</a> |
+                    <strong>[% l("Show only available holds") %]</strong>
+                    [% ELSE -%]
+                    <strong>[% l("Show all holds") %]</strong> |
+                    <a href="[% mkurl('holds',{available => 1},['limit','offset']) %]">[% l("Show only available holds") %]</a>
+                    [% END -%]
+                    <select class="hide_me" id="holds_sort">
+                        <option value="">[% l('-- Sort By --') %]</option>
+                        <option value="title">[% l('Title') %]</option>
+                        <option value="pickup">[% l('Pickup Location') %]</option>
+                        <option value="status">[% l('Status') %]</option>
+                    </select>
+                </td>
+            </tr>
+        </table>
+        [% IF ctx.holds.size && ctx.holds.size < 1 %]
+        <div class="warning_box">[% l('No holds found.') %]</div>
+        [% ELSE %]
+        <div class="hide_me">
+            <select id="hold_pickup_lib_temp" name="hold_pickup_lib_sel" class="hide_me"></select>
+        </div>
+        <table id="acct_holds_main_header" cellpadding='0' cellspacing='0' border='0'>
+            <thead>
+            <tr>
+                <th align="center">
+                    <input type="checkbox" title="[% l('Select All Holds') %]"
+                      onclick="var inputs=document.getElementsByTagName('input'); for (i = 0; i < inputs.length; i++) { if (inputs[i].name == 'hold_id' &amp;&amp; !inputs[i].disabled) inputs[i].checked = this.checked;}"/>
+                </th>
+                <th>[% l('Title') %]</th>
+                <th>[% l('Author') %]</th>
+                <th>[% l('Format') %]</th>
+                <th>[% l('Pickup Location') %]</th>
+                <th>[% l('Activate') %]</th>
+                <th>[% l('Cancel if not filled by') %]</th>
+                <th>[% l('Active') %]</th>
+                <th>[% l('Status') %]</th>
+                <th>[% l('Notes') %]</th>
+            </tr>
+            </thead>
+            <tbody id="holds_temp_parent">
+                [% FOR hold IN ctx.holds;
+                    attrs = {marc_xml => hold.marc_xml};
+                    PROCESS get_marc_attrs args=attrs;
+                    ahr = hold.hold.hold %]
+                <tr name="acct_holds_temp"
+                    class="acct_holds_temp[% ahr.frozen == 't' ? ' inactive-hold' : '' %]">
+                    <td align="center" style="text-align:center;">
+                        <input type="checkbox" name="hold_id" value="[% ahr.id %]" 
+                            [% html_text_attr('title', l('Select hold [_1]', attrs.title)) %]/>
+                    </td>
+                    <td>
+                        <div>
+                            [% 
+                                title = attrs.title;
+                                IF ahr.hold_type == 'P';
+                                    title = l('[_1] ([_2])', title, hold.hold.part.label);
+                                END;
+                            %]
+                            <a href="[% mkurl(ctx.opac_root _ '/record/' _ hold.hold.bre_id) %]">[% title | html %]</a>
+                        </div>
+                    </td>
+                    <td>
+                        <div>
+                            <a href="[% mkurl(ctx.opac_root _ '/results',
+                                {qtype => 'author', query => attrs.author.replace('[,\.:;]', '')}
+                            ) %]">[% attrs.author | html %]</a>
+                        </div>
+                    </td>
+                    <td>
+                        <div class="format_icon">
+                          [% 
+                            formats = attrs.all_formats;
+                            IF ahr.hold_type == 'M';
+                              # only show selected formats for metarecords
+                              formats = [];
+                              FOR ccvm IN hold.metarecord_selected_filters.icons;
+                                NEXT IF ccvm.opac_visible == 'f';
+                                format = {};
+                                format.label = ccvm.search_label || ccvm.value;
+                                format.icon = PROCESS get_ccvm_icon ccvm=ccvm;
+                                formats.push(format);
+                              END;
+                            END;
+                            FOR format IN formats 
+                          %]
+                            <img title="[% format.label | html %]" 
+                              alt="[% format.label | html %]" src="[% format.icon %]" />
+                            [% END %]
+                        </div>
+                    </td>
+                    <td>
+                        [% ctx.get_aou(ahr.pickup_lib).name | html %]
+                    </td>
+                    <td>
+                        [% IF ahr.frozen == 't' AND ahr.thaw_date;
+                            date.format(ctx.parse_datetime(ahr.thaw_date), DATE_FORMAT);
+                        END %]
+                    </td>
+                    <td>
+                        [% IF ahr.expire_time;
+                            date.format(ctx.parse_datetime(ahr.expire_time), DATE_FORMAT);
+                        END %]
+                    </td>
+                    <td>
+                        [% l(ahr.frozen == 'f' ? 'Active' : 'Suspended') %]
+                    </td>
+                    <td>
+                        <div name="acct_holds_status">
+                            [% PROCESS get_hold_status hold=hold; %]
+                        </div>
+                    </td>
+                    <td class="hold_notes">
+                    [%- FOREACH pubnote IN ahr.notes;
+                        IF pubnote.pub == 't';
+                    %]
+                        <div class="hold_note">
+                            <span class="hold_note_title">[% pubnote.title | html %]</span>
+                            <br />
+                            <span class="hold_note_body">[% pubnote.body | html %]</span>
+                        </div>
+                    [%- END; END; %]
+                    </td>
+                    <td class="opac-auto-161">
+                        <a href="[% mkurl(ctx.opac_root _ '/myopac/holds/edit', {id => ahr.id}) %]"
+                            [% html_text_attr('title', l('Edit hold for item [_1]', attrs.title)) %]>
+                            [% l('Edit') %]
+                        </a>
+                    </td>
+                </tr>
+                [% END %]
+            </tbody>
+        </table>
+        [% END %]
+        </form>
+    </div>
+</div>
+[% END %]
diff --git a/Open-ILS/src/cwopac_templates/opac/myopac/lists.tt2 b/Open-ILS/src/cwopac_templates/opac/myopac/lists.tt2
new file mode 100644 (file)
index 0000000..3fba830
--- /dev/null
@@ -0,0 +1,471 @@
+[%  PROCESS "opac/parts/header.tt2";
+    PROCESS "opac/parts/misc_util.tt2";
+    WRAPPER "opac/parts/myopac/base.tt2";
+    myopac_page = "lists"  
+    limit = ctx.bookbags_limit;
+    offset = ctx.bookbags_offset;
+    item_page = ctx.bookbags_item_page;
+    bb_publish_text = l(
+"Sharing a list means that the contents " _
+"of the list will be visible to others. " _
+"To see the public view of a shared list, " _
+"click on the HTML View link in the Saved Lists section.");
+%]
+<h3 class="sr-only">[% l('My Lists') %]</h3>
+<div id='myopac_bookbag_div' style="padding:5px;">
+
+    <!-- new list creation -->
+    <form action="[% mkurl(ctx.opac_root _ '/myopac/list/update') %]" method="post" id="create_form">
+        <h1>[% l('Create New List') %]</h1><a name="createnewlist"></a>
+        <table class="table_no_cell_pad" id="list_create_table">
+            <tr>
+                <td>
+                    <label for="list_create_name">[% l('Enter the name of the new list:') %]</label>
+                </td>
+                <td>
+                    [%- INCLUDE "opac/parts/preserve_params.tt2"; %]
+                    <input id="list_create_name" type="text" name="name" />
+                    <input type="hidden" name="action" value="create" />
+                    [% IF ctx.add_rec %]
+                    <input type="hidden" name="add_rec" value="[% ctx.add_rec %]" />
+                    [% END %]
+                    [% IF ctx.where_from %]
+                    <input type="hidden" name="where_from" value="[% ctx.where_from %]" />
+                    [% END %]
+                </td>
+                <td>
+                    <label for="list_create_shared">[% l('Share this list?') %]</label>
+                    <select name="shared" id="list_create_shared">
+                        <option value="0">[% l('No') %]
+                        <option value="1">[% l('Yes') %]
+                    </select>
+                    <a href="javascript:void(0);" 
+                        onclick="alert('[% bb_publish_text %]')">
+                        <img alt="[% l('Sharing Help') %]"
+                            [% html_text_attr('title', bb_publish_text) %]
+                            src="[% ctx.media_prefix %]/images/question-mark.png" />
+                    </a>
+                </td>
+                <td class="list-create-table-buttons">
+                    <input type="submit"
+                        value="[% l('Submit') %]"
+                        alt="[% l('Submit') %]"
+                        class="opac-button"/>
+                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+                    <input type="reset"
+                        value="[% l('Cancel') %]"
+                        alt="[% l('Cancel') %]"
+                        class="opac-button" />
+                </td>
+            </tr>
+            <tr>
+                <td class="text-right-top">
+                    <label for="list_description">[% l("List description (optional):") %]</label>
+                </td>
+                <td colspan="3">
+                    <textarea cols="40" rows="3" name="description"
+                        id="list_description"></textarea>
+                </td>
+        </table>
+    </form>
+
+    <h1>[% l("My Existing Lists") %]</h1>
+    [% INCLUDE "opac/parts/anon_list.tt2" %]
+    [% IF ctx.bookbags.size %]
+    <div class="header_middle">
+        <span class="float-left">[% l('Saved Lists') %]</span>
+        [% IF limit < ctx.bookbag_count; %]
+        <span class='float-left' style='padding-left: 10px;'>
+            [%- IF offset > 0 -%]
+                <a href='[% mkurl(ctx.opac_root _ '/myopac/lists', {
+                    offset => (offset - limit)
+                }) %]'><span class="nav_arrow_fix">&#9668;</span>[% l('Previous') %]</a>
+            [%- END; -%]
+            [%- IF (offset - (limit * 3)) >= 0 -%]
+                <a href='[% mkurl(ctx.opac_root _ '/myopac/lists', {
+                    offset => (offset - (limit * 3))
+                }) %]'>[% ((offset - (limit * 3)) / limit) + 1 %]</a>
+            [%- END; -%]
+            [%- IF (offset - (limit * 2)) >= 0 -%]
+                <a href='[% mkurl(ctx.opac_root _ '/myopac/lists', {
+                    offset => (offset - (limit * 2))
+                }) %]'>[% ((offset - (limit * 2)) / limit) + 1 %]</a>
+            [%- END; -%]
+            [%- IF (offset - limit) >= 0 -%]
+                <a href='[% mkurl(ctx.opac_root _ '/myopac/lists', {
+                    offset => (offset - limit)
+                }) %]'>[% ((offset - limit) / limit) + 1 %]</a>
+            [%- END; -%]
+            <span class="bookbag-paginator-selected" >[% (offset / limit) + 1 %]</span>
+            [%- IF (offset + limit) < ctx.bookbag_count -%]
+                <a href='[% mkurl(ctx.opac_root _ '/myopac/lists', {
+                    offset => (offset + limit)
+                }) %]'>[% ((offset + limit) / limit) + 1 %]</a>
+            [%- END; -%]
+            [%- IF (offset + (limit * 2)) < ctx.bookbag_count -%]
+                <a href='[% mkurl(ctx.opac_root _ '/myopac/lists', {
+                    offset => (offset + (limit * 2))
+                }) %]'>[% ((offset + (limit * 2)) / limit) + 1 %]</a>
+            [%- END; -%]
+            [%- IF (offset + (limit * 3)) < ctx.bookbag_count -%]
+                <a href='[% mkurl(ctx.opac_root _ '/myopac/lists', {
+                    offset => (offset + (limit * 3))
+                }) %]'>[% ((offset + (limit * 3)) / limit) + 1 %]</a>
+            [%- END; -%]
+            [%- IF (ctx.bookbag_count - offset) > limit; -%] 
+                <a href='[% mkurl(ctx.opac_root _ '/myopac/lists', {
+                    offset => (offset + limit)
+                }) %]'>[% l('Next') %]<span class="nav_arrow_fix">&#9658;</span></a>
+            </span>
+            [%- END; -%]
+        [% END %]
+    </div>
+    <div class="clear-both"></div>
+
+    <div id='acct_lists_prime'>
+        [% FOR bbag IN ctx.bookbags %]
+        <div class="bookbag-controls-holder">
+            <div class="bookbag-controls most">
+                [% baseurl = ctx.opac_root _ '/myopac/lists';
+                IF bbag.id != CGI.param("bbid");
+                    url = mkurl(baseurl,{bbid => bbag.id, item_page => 1},['edit_notes','sort']);
+                    ltitle = l("Show items in list");
+                ELSE;
+                    url = mkurl(baseurl, {}, ['bbid', 'edit_notes', 'sort']);
+                    ltitle = l("Hide items in list");
+                END %]
+                <h2 class="bookbag-name"><a title="[% ltitle %]" href="[% url %]">[% bbag.name | html %]</a></h2>
+                [% IF bbag.description %]<div class="bookbag-description">[% bbag.description | html %]</div>[% END %]
+            </div>
+            [% IF ctx.add_rec %]
+            <form action="[% mkurl(ctx.opac_root _ '/myopac/list/update', {}, 1) %]" method="post">
+                <div class="bookbag-controls">
+                    <input type="hidden" name="action" value="add_rec" />
+                    <input type="hidden" name="list" value="[% bbag.id %]" />
+                    <input type="hidden" name="add_rec" value="[% ctx.add_rec %]" />
+                    [% IF ctx.where_from %]
+                    <input type="hidden" name="where_from" value="[% ctx.where_from %]" />
+                    [% END %]
+                    <input class="fixed" type="submit" value="[% l('Add to this list') %]" />
+                </div>
+            </form>
+            [% END %]
+            <form action="[% mkurl(ctx.opac_root _ '/myopac/list/update') %]" method="post">
+                <div class="bookbag-share">
+                    <input type="hidden" name="list" value="[% bbag.id %]" />
+                    [%- INCLUDE "opac/parts/preserve_params.tt2"; %]
+                    [% IF bbag.pub != 't' %]
+                    <input type="hidden" name="action" value="show" />
+                    <input class="fixed" type="submit" value="[% l('Share') %]" />
+                    [% ELSE %]
+                    <input type="hidden" name="action" value="hide" />
+                    <input class="fixed" type="submit" value="[% l('Hide') %]" />
+                    [% END %]
+                </div>
+            </form>
+            <form action="[% mkurl(ctx.opac_root _ '/myopac/list/update') %]" method="post" onsubmit="return confirm('[% l('Do you really want to delete this list?') %]')">
+                <div class="bookbag-controls">
+                    <input type="hidden" name="list" value="[% bbag.id %]" />
+                    <input type="hidden" name="action" value="delete" />
+                    [%- INCLUDE "opac/parts/preserve_params.tt2"; %]
+                    <input type="submit" value="[% l('Delete List') %]" />
+                </div>
+            </form>
+            <form action="[% mkurl(ctx.opac_root _ '/myopac/list/print') %]" method="post">
+                <div class="bookbag-controls">
+                    <input type="hidden" name="list" value="[% bbag.id %]" />
+                    <input type="hidden" name="sort" value="[% CGI.param('sort') | html %]" />
+                    [%- INCLUDE "opac/parts/preserve_params.tt2"; %]
+                    <input type="submit" value="[% l('Download CSV') %]" />
+                </div>
+            </form>
+            [% setting = 'opac.default_list'; %]
+            <form action="[% mkurl(ctx.opac_root _ '/myopac/list/update') %]" method="post">
+                <div class="bookbag-controls">
+                    <input type="hidden" name="list" value="[% bbag.id %]" />
+                    [%- INCLUDE "opac/parts/preserve_params.tt2"; %]
+                    [% IF ctx.user_setting_map.$setting == bbag.id %]
+                    <input type="hidden" name="action" value="remove_default" />
+                    <input type="submit" value="[% l('Remove Default List') %]" />
+                    [% ELSE %]
+                    <input type="hidden" name="action" value="make_default" />
+                    <input type="submit" value="[% l('Make Default List') %]" />
+                    [% END %]
+                </div>
+            </form>
+            [% IF ctx.is_staff %]
+            <div class="bookbag-controls">
+                <input 
+                    type="submit" 
+                    onclick='
+                       var path = 
+                          "oils://remote/xul/server/cat/bucketz39_dialog.xul";
+                        window.openDialog(
+                            xulG.url_prefix(path),
+                            "bucketz39_dialog",
+                            "width=800,height=500",
+                            "[% ctx.user.id %]",
+                            "[% ctx.authtoken %]",
+                            "[% ctx.user.ws_ou %]",
+                            "[% bbag.id %]",
+                            xulG
+                        )'
+                    value="[% l('Locate Z39.50 Matches') %]" 
+                />
+            </div>
+            [% END %]
+            <div class="bookbag-controls">
+                [% IF bbag.pub == 't'; %]
+                <a target='_blank' href='/opac/extras/feed/bookbag/rss2-full/[% bbag.id %]'><img
+                    alt="[% l('RSS Feed') %]" border="0"
+                    src="[% ctx.media_prefix %]/images/small-rss.png"/></a>
+                [% END %]
+            </div>
+            <div class="bookbag-controls">
+                [% IF bbag.pub == 't'; %]
+                <a href='[%-
+                    mkurl(
+                        ctx.opac_root _ '/results',
+                        {page => '0', bookbag => bbag.id, depth => 0, locg => ctx.search_ou},
+                        1
+                    )
+                -%]'>[% l('HTML View') %]</a>
+                [% END %]
+            </div>
+            <div class="clear-both pad-bottom-five"></div>
+        </div>
+        [% IF CGI.param("bbid") == bbag.id %]
+        <div class="bookbag-specific">
+            <div class="sort">
+                <form method="get">
+                    <label for="opac.result.sort">[% l("Sort list items by: ") %]</label>
+                    [%- INCLUDE "opac/parts/preserve_params.tt2" params=['loc', 'query', 'qtype']; %]
+                    [% INCLUDE "opac/parts/filtersort.tt2"
+                        value=CGI.param('sort') mode='bookbag' %]
+                    <input type="hidden" name="bbid"
+                        value="[% CGI.param('bbid') | html %]" />
+                    <input type="submit" value="[% l('Sort') %]" />
+                </form>
+            </div>
+            <div class="meta">
+                <form method="post">
+                    <input type="hidden" name="bbid" value="[% bbag.id %]" />
+                    <input type="hidden" name="action" value="editmeta" />
+                    <input type="hidden" name="limit" value="[% limit %]" />
+                    <input type="hidden" name="offset" value="[% offset %]" />
+                    [%- INCLUDE "opac/parts/preserve_params.tt2"; %]
+                    <table id="bbag-name-desc-form">
+                        <tr>
+                            <th>
+                                <label for="bbag-edit-name">[% l('Name:') %]</label>
+                            </th>
+                            <td>
+                                <input name="name" type="text"
+                                    value="[% bbag.name | html %]"
+                                    id="bbag-edit-name" />
+                            </td>
+                            <td rowspan="2" class="saver">
+                                [% l("Save changes to name or description?") %]<br />
+                                <input type="submit" value="[% l('Save') %]" />
+                            </td>
+                        </tr>
+                        <tr>
+                            <th><label for="bbag-edit-description">[% l('Description:') %]</label></th>
+                            <td>
+                                <textarea name="description"
+                                    id="bbag-edit-description">[% bbag.description | html %]</textarea>
+                            </td>
+                        </tr>
+                    </table>
+                </form>
+            </div>
+        </div>
+        <br class="clear-both" />
+        <form action="[% mkurl(ctx.opac_root _ '/myopac/list/update') %]" method="post">
+        <input type="hidden" name="list" value="[% bbag.id %]" />
+        <input type="hidden" name="sort" value="[% CGI.param('sort') | uri %]" />
+        <table class="bookbag-specific table_no_cell_pad table_no_border_space table_no_border">
+            <thead id="acct_list_header">
+                <tr>
+                    <td class="list_checkbox">
+                    <input type="checkbox" 
+                      onclick="var inputs=document.getElementsByTagName('input'); 
+                        for (i = 0; i < inputs.length; i++) { 
+                            if (inputs[i].name == 'selected_item' &amp;&amp; !inputs[i].disabled &amp;&amp; inputs[i].getAttribute('bbag') == [% bbag.id %]) 
+                                inputs[i].checked = this.checked;}"/>
+
+                    </td>
+                    <td class="list_entry">
+                        <a href="[% mkurl(ctx.opac_root _ '/myopac/lists', {sort=> (CGI.param('sort') == 'titlesort' ? 'titlesort.descending' : 'titlesort')}) %]">[% l('Title') %]</a>
+                    </td>
+                    <td class="list_entry">
+                        <a href="[% mkurl(ctx.opac_root _ '/myopac/lists', {sort=>(CGI.param('sort') == 'authorsort' ? 'authorsort.descending' : 'authorsort')}) %]">[% l('Author(s)') %]</a>
+                    </td>
+                    <td class='list_entry'>
+                        [% l('Local Call Number') %]
+                    </td>
+                    <td class="list_entry">
+                        <a href="[% mkurl(ctx.opac_root _ '/myopac/lists', {sort=>(CGI.param('sort') == 'pubdate' ? 'pubdate.descending' : 'pubdate')}) %]">[% l('Publication Date') %]</a>
+                    </td>
+                    <td class="list_entry">
+                         [% l('Format') %]
+                    </td>
+                    <td class="list_entry">
+                        [% l('Notes') %]
+                        [% IF CGI.param("edit_notes") != bbag.id %]
+                        | <a href="[% mkurl(ctx.opac_root _ '/myopac/lists', {edit_notes=> bbag.id}) %]">[% l('Edit') %]</a>
+                        [% END %]
+                    </td>
+                    <td class="list_actions">
+                        <select name="action">
+                            <option disabled="disabled">[% l('-- Actions for these items --') %]</option>
+                            <option value="place_hold">[% l('Place hold') %]</option>
+                            <option value="del_item">[% l('Remove from list') %]</option>
+                        </select>
+                        [%- INCLUDE "opac/parts/preserve_params.tt2"; %]
+                        <input type="submit" value="[% l('Go') %]" />
+                    </td>
+                </tr>
+            </thead>
+            <tbody>
+                [% UNLESS bbag.items.size %]
+                <tr><td colspan="6" class="list_is_empty">
+                    [% l("This list contains no items.") %]
+                </td></tr>
+                [% END %]
+                [% FOR item IN bbag.items;
+                    rec_id = item.target_biblio_record_entry.id;
+                    attrs = {marc_xml => ctx.bookbags_marc_xml.$rec_id};
+                    PROCESS get_marc_attrs args=attrs %]
+                <tr class="bookbag-item-row">
+                    <td class="list_checkbox">
+                        <input type="checkbox" name="selected_item" value="[% item.id %]" bbag='[% bbag.id %]'/>
+                    </td>
+                    <td class="list_entry">
+                        <a href="[% mkurl(ctx.opac_root _ '/record/' _ rec_id, {}, ['edit_notes', 'bbid']) %]">[% attrs.title | html %]</a>
+                    </td>
+                    <td class="list_entry">
+                        <a href="[%- 
+                            authorquery = attrs.author | replace('[,\.:;]', '');
+                            mkurl(ctx.opac_root _ '/results', {qtype => 'author', query => authorquery}, ['page', 'bbid', 'edit_notes'])
+                            -%]">[% attrs.author | html %]</a>
+                    </td>
+                    <td class="list_entry">
+                        [% 
+                            copy = attrs.holdings.0;
+                            IF copy;
+                                # only show a relevant call number
+                                copy_org = ctx.get_aou_by_shortname(copy.owner);
+                                FOR ctx_org IN [ctx.pref_ou, ctx.search_ou, ctx.home_ou, ctx.physical_loc];
+                                    NEXT UNLESS ctx_org;
+                                    ctx_org = ctx.get_aou(ctx_org);
+                                    IF ctx.org_within_scope(ctx_org, copy_org, ctx_org.ou_type.depth);
+                                        l('[_1] ([_2])', copy.label, copy_org.name) | html;
+                                        LAST;
+                                    END;
+                                END;
+                            END;
+                        %]
+                    </td>
+                    <td class="list_entry">
+                          [% attrs.pubdate | html %]
+                    </td>
+                    <td class="list_entry">
+                          [% attrs.format_label | html %]
+                    </td>
+                    [% IF CGI.param("edit_notes") == bbag.id %]
+                    <td class="list_entry">
+                        [% FOR note IN item.notes %]
+                        <input type="text" name="note-[% note.id %]" value="[% note.note | html %]" />
+                        [% END %]
+                        <input type="text" name="item-[% item.id %]" />
+                    </td>
+                    [% ELSE %]
+                    <td class="list_entry">
+                        [% FOR note IN item.notes %]
+                        <div>[% note.note | html %]</div>
+                        [% END %]
+                    </td>
+                    [% END %]
+                </tr>
+                [% END %]
+                [% IF CGI.param("edit_notes") == bbag.id %]
+                <tr>
+                    <td colspan="3"><!-- All space left of notes column --></td>
+                    <td class="save-notes">
+                        [%- INCLUDE "opac/parts/preserve_params.tt2"; %]
+                        <input type="hidden" name="bbid" value="[% CGI.param('bbid') | html %]" />
+                        <input type="submit" name="save_notes" value="[% l('Save Notes') %]" />
+                    </td>
+                </tr>
+                [% END %]
+            </tbody>
+        </table>
+
+        [% IF ctx.bb_page_count > 1; %]
+            <div class="header_middle" style="padding-top:7px;">
+                <span class="float-left" style="padding-left:34px;">[% l('Navigate Selected List ') %]</span>
+                <span class='float-left' style='padding-left: 10px;'>
+                    [%- IF item_page > 1 -%]
+                        <a href='[% mkurl(ctx.opac_root _ '/myopac/lists', {
+                            item_page => item_page - 1
+                        }) %]'><span class="nav_arrow_fix">&#9668;</span>[% l('Previous') %]</a>
+                    [%- END; -%]
+
+                    [%- IF (item_page - 3) >= 1 -%]
+                        <a href='[% mkurl(ctx.opac_root _ '/myopac/lists', {
+                            item_page => item_page - 3
+                        }) %]'>[% item_page - 3 %]</a>
+                    [%- END; -%]
+                    [%- IF (item_page - 2) >= 1 -%]
+                        <a href='[% mkurl(ctx.opac_root _ '/myopac/lists', {
+                            item_page => item_page - 2
+                        }) %]'>[% item_page - 2 %]</a>
+                    [%- END; -%]
+                    [%- IF (item_page - 1) >= 1 -%]
+                        <a href='[% mkurl(ctx.opac_root _ '/myopac/lists', {
+                            item_page => item_page - 1
+                        }) %]'>[% item_page - 1%]</a>
+                    [%- END; -%]
+                    <span class="bookbag-paginator-selected" >[% item_page %]</span>
+                    [%- IF (item_page + 1) <= ctx.bb_page_count -%]
+                        <a href='[% mkurl(ctx.opac_root _ '/myopac/lists', {
+                            item_page => item_page + 1
+                        }) %]'>[% item_page + 1 %]</a>
+                    [%- END; -%]
+                    [%- IF (item_page + 2) <= ctx.bb_page_count -%]
+                        <a href='[% mkurl(ctx.opac_root _ '/myopac/lists', {
+                            item_page => item_page + 2
+                        }) %]'>[% item_page + 2 %]</a>
+                    [%- END; -%]
+                    [%- IF (item_page + 3) <= ctx.bb_page_count -%]
+                        <a href='[% mkurl(ctx.opac_root _ '/myopac/lists', {
+                            item_page => item_page + 3
+                        }) %]'>[% item_page + 3 %]</a>
+                    [%- END; -%]
+
+                    [%- IF (item_page + 1) <= ctx.bb_page_count; -%]
+                        <a href='[% mkurl(ctx.opac_root _ '/myopac/lists', {
+                            item_page => item_page + 1
+                        }) %]'>[% l('Next') %]<span class="nav_arrow_fix">&#9658;</span></a>
+                    [%- END; -%]
+                 </span>
+            </div>
+            <div class="clear-both"></div>
+        [% END %]
+        <br/>
+
+        </form>
+        [% END %]
+        [% END %]
+    </div>
+    [% END %]
+
+    <span id='bb_publish_text' class='hide_me'>
+[% l("Sharing a list means that the contents " _
+"of the list will be visible to others. " _
+"To see the public view of a shared list, " _
+"click on the list's name in your Saved Lists.") %]
+    </span>
+</div>
+[% END %]
diff --git a/Open-ILS/src/cwopac_templates/opac/myopac/main.tt2 b/Open-ILS/src/cwopac_templates/opac/myopac/main.tt2
new file mode 100644 (file)
index 0000000..37fa26c
--- /dev/null
@@ -0,0 +1,193 @@
+[%  PROCESS "opac/parts/header.tt2";
+    PROCESS "opac/parts/misc_util.tt2";
+    WRAPPER "opac/parts/myopac/main_base.tt2";
+    myopac_page = "main";
+    myopac_main_page = "main";
+    myopac_cc_allowed = 0;
+    IF (ctx.fines.grocery.size OR ctx.fines.circulation.size) AND ctx.get_org_setting(ctx.user.home_ou, 'credit.payments.allow') == 1;
+        myopac_cc_allowed = 1;
+    END
+%]
+<h3 class="sr-only">[% l('My Account Summary') %]</h3>
+[%  IF myopac_cc_allowed;
+    # http://www.w3.org/TR/WCAG20-TECHS/H32.html
+    # avoid forms w/ no submit action %]
+<form action="[% ctx.opac_root %]/myopac/main_payment_form" method="get">
+[% END %]
+
+    [% IF ctx.fines.circulation.size > 0 %]
+    <div id='myopac_circ_trans_div'>
+        <table width='100%' class='data_grid' title="[% l('Items Checked Out') %]">
+            <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("Returned/Renewed") %]</td>
+                    <td>[% l("Balance Owed") %]</td>
+                    [% IF myopac_cc_allowed %]
+                    <td nowrap="nowrap" style="white-space:nowrap;">
+                        <input id="pay_fines_box1" checked="checked"
+                            type="checkbox" onclick="select_all_checkboxes('xact', this.checked)"
+                            title="[% l('Click to (un)select all fines') %]" />
+                        <label for="pay_fines_box1">[% l('Pay Fines') %]</label>
+                    </td>
+                    [% END %]
+                </tr>
+            </thead>
+            <tbody id='myopac_circ_trans_tbody'>
+                [% FOR f IN ctx.fines.circulation;
+                    attrs = {marc_xml => f.marc_xml};
+                    IF f.marc_xml;
+                        PROCESS get_marc_attrs args=attrs;
+                    ELSIF f.xact.reservation;
+                        attrs.title = f.xact.reservation.target_resource_type.name;
+                    END %]
+                <tr id='myopac_circ_trans_row'>
+                    <td>
+                        [% recid = f.xact.circulation.target_copy.call_number.record.id || f.xact.reservation.target_resource_type.record.id;
+                        IF recid; %]
+                        <a href="[% mkurl(ctx.opac_root _ '/record/' _ recid,
+                            {loc => ctx.search_ou}) %]">[% attrs.title | html %]</a>
+                        [% ELSE %]
+                        [% attrs.title | html %]
+                        [% END %]
+                    </td>
+                    <td>[%- author_query = attrs.author.replace('[,\.:;]', ''); %]
+                        <a href="[% mkurl(ctx.opac_root _ '/results',
+                            {qtype => 'author', query => author_query,
+                            loc => ctx.search_ou}) %]">[% attrs.author | html %]</a>
+                    </td>
+                    <td name='myopac_circ_trans_start'>
+                        [% ts = f.xact.circulation.xact_start || f.xact.reservation.start_time || 0;
+                        IF ts;
+                            date.format(ctx.parse_datetime(ts), DATE_FORMAT);
+                        END %]
+                    </td>
+                    <td name='myopac_circ_trans_due'>
+                        [% ts = f.xact.circulation.due_date || f.xact.reservation.end_time || 0;
+                        IF ts;
+                            date.format(ctx.parse_datetime(ts), DATE_FORMAT);
+                        END %]
+                    </td>
+                    <td name='myopac_circ_trans_finished'>
+                        [%  ts = f.xact.circulation.checkin_time || f.xact.reservation.return_time || 0;
+                            IF ts;
+                                date.format(ctx.parse_datetime(ts), DATE_FORMAT);
+                            ELSE %]
+                            <!-- XXX TODO fines aren't really accruing
+                                if circ has hit maxfines. more clarity
+                                here? -->
+                            <span class="alert">[% l('(fines accruing)') %]</span>
+                        [%  END %]
+                    </td>
+                    <td>
+                        <strong class="alert">
+                            [% money(f.xact.balance_owed) %]
+                        </strong>
+                    </td>
+                    [% IF myopac_cc_allowed %]
+                    <td>
+                        <input type="checkbox" checked="checked" 
+                            title="[% l('Pay this fine') %]" name="xact"
+                            value="[% f.xact.id %]" />
+                    </td>
+                    [% END %]
+                </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' title="[% l('Other Fines and Fees') %]">
+            <thead>
+                <tr>
+                    <td colspan='8' style='padding: 6px'>
+                        <span class="bold">[% l("Other Fees") %]</span>
+                    </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>
+                    [% IF myopac_cc_allowed %]
+                    <td width='4%' align="center" nowrap="nowrap"
+                        style="white-space:nowrap;">
+                        <input id="pay_fines_box2" checked="checked"
+                            type="checkbox" onclick="select_all_checkboxes('xact_misc', this.checked)"
+                            title="[% l('Click to (un)select all fines') %]" />
+                        <label for="pay_fines_box2">[% l("Pay Fines") %]</label>
+                    </td>
+                    [% END %]
+                </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="alert">
+                        <strong>
+                            [% money(f.xact.balance_owed) %]
+                        </strong>
+                    </td>
+                    <td>[% f.xact.last_billing_type %]</td>
+                    [% IF myopac_cc_allowed %]
+                    <td>
+                        <input type="checkbox" title='[% l("Pay this fine") %]'
+                            name="xact_misc" value="[% f.xact.id %]"
+                            checked="checked" />
+                    </td>
+                    [% END %]
+                </tr>
+                [% END %]
+            </tbody>
+        </table>
+    </div>
+    [% END %]
+    [% UNLESS ctx.fines.grocery.size OR ctx.fines.circulation.size %]
+    <div>[% l('You have no current fines.') %]</div>
+    [% ELSIF myopac_cc_allowed %]
+    <div class="text-right pad-top-ten">
+        <input type="submit"
+            value="[% l('Pay selected fines') %]"
+            alt="[% l('Pay selected fines') %]"
+            title="[% l('Pay selected fines') %]"
+            class="opac-button" />
+    </div>
+    [% END %]
+[% IF myopac_cc_allowed %]
+</form>
+[% END %]
+
+[% END %]
diff --git a/Open-ILS/src/cwopac_templates/opac/myopac/prefs_settings.tt2 b/Open-ILS/src/cwopac_templates/opac/myopac/prefs_settings.tt2
new file mode 100644 (file)
index 0000000..5d82d8f
--- /dev/null
@@ -0,0 +1,129 @@
+[%  PROCESS "opac/parts/header.tt2";
+    PROCESS "opac/parts/org_selector.tt2";
+    WRAPPER "opac/parts/myopac/prefs_base.tt2";
+    myopac_page = "prefs";
+    prefs_page = 'prefs_settings' %]
+
+    <h3 class="sr-only">[% l('Search and History Preferences') %]</h3>
+
+    <form method='post'>
+
+       <table class="full-width data_grid" id="acct_search_main"
+            title="[% l('Search and History Preferences') %]">
+            <tbody>
+
+                [% IF ctx.updated_user_settings %]
+                <tr><td colspan='2'>
+                    <div class='renew-summary'>
+                        [% l('Account Successfully Updated') %]
+                    </div>
+                </td></tr>
+                [% END %]
+
+                [%- setting = 'opac.hits_per_page' -%]
+                <tr >
+                    <td width='20%'><label for='[% setting %]'>[% l("Search hits per page") %]</label></td>
+                    <td>
+                        <select id='[% setting %]' name='[% setting %]'>
+                            [%  UNLESS ctx.user_setting_map.$setting;
+                                    ctx.user_setting_map.$setting = 10;
+                                END;
+                                FOR val IN [5, 8, 10, 15, 20, 25, 50] %]
+                                <option value='[% val | uri %]' 
+                                    [% IF ctx.user_setting_map.$setting == val %]
+                                        selected='selected'[% END %]>[% val | html %]</option>
+                            [% END %]
+                        </select>
+<!--
+                        <a href="#"><img alt="[% l('Search Hits Help') %]" 
+                            src="[% ctx.media_prefix %]/images/question-mark.png"
+                        /></a>
+--> 
+                   </td>
+                </tr>
+                [%- setting = 'opac.default_search_location'; -%]
+                <tr >
+                    <td width='20%'><label for='[% setting %]'>[% l("Preferred search location") %]</label></td>
+                    <td>
+                        [%- thang = ctx.user.home_ou.id;
+                            IF ctx.user_setting_map.$setting;
+                                thang = ctx.user_setting_map.$setting;
+                            END;
+                            id = setting;
+                            INCLUDE build_org_selector name=setting value=thang;
+                        %]
+                    </td>
+                </tr>
+                [%- setting = 'opac.default_pickup_location'; -%]
+                <tr>
+                    <td width='20%'><label for='[% setting %]'>[% l("Preferred pickup location") %]</label></td>
+                    <td>
+                        [%- thang = ctx.user.home_ou.id;
+                            IF ctx.user_setting_map.$setting;
+                                thang = ctx.user_setting_map.$setting;
+                            END;
+                            id = setting;
+                            INCLUDE build_org_selector name=setting value=thang can_have_vols_only=1;
+                        %]
+                    </td>
+                </tr>
+                [%- setting = 'history.circ.retention_start' -%]
+                <tr>
+                    [% circ_name = l('Keep history of checked out items?') %]
+                    <td><label for='[% setting %]'>[% circ_name%]</label></td>
+                    <td>
+                        <input id='[% setting %]' name='[% setting %]' 
+                            type="checkbox" title="[% circ_name %]"
+                            [% IF ctx.user_setting_map.$setting; %] checked='checked' [% END %]/>
+                    </td>
+                </tr>
+                [%- setting = 'history.hold.retention_start' -%]
+                <tr>
+                    [% hold_name =  l('Keep history of holds?') %]
+                    <td><label for='[% setting %]'>[% hold_name %]</label></td>
+                    <td>
+                        <input id='[% setting %]' name='[% setting %]' 
+                            type="checkbox" title="[% hold_name %]"
+                            [% IF ctx.user_setting_map.$setting; %] checked='checked' [% END %]/>
+                    </td>
+                </tr>
+                [%- setting = 'opac.temporary_list_no_warn' -%]
+                <tr>
+                    [% skip_warn =  l('Skip warning when adding to temporary book list?') %]
+                    <td><label for='[% setting %]'>[% skip_warn %]</label></td>
+                    <td>
+                        <input id='[% setting %]' name='[% setting %]' 
+                            type="checkbox" title="[% skip_warn %]"
+                            [% IF ctx.user_setting_map.$setting %] checked='checked' [% END %]/>
+                    </td>
+                </tr>
+                [%- setting = 'circ.holds_behind_desk'; IF ctx.behind_desk_supported -%]
+                <tr>
+                    [% behind_desk = l('Pickup holds from behind the desk when possible?') %]
+                    <td><label for='[% setting %]'>[% behind_desk %]</label></td>
+                    <td>
+                        <input id='[% setting %]' name='[% setting %]' 
+                            type="checkbox" title="[% behind_desk %]"
+                            [% IF ctx.user_setting_map.$setting %] checked='checked' [% END %]/>
+                    </td>
+                </tr>
+                [% END %]
+
+                <!--
+                <tr>
+                    <td><label for='prefs_def_font'>[% l("Default Font Size") %]</label></td>
+                    <td>
+                        <select id='prefs_def_font'>
+                            <option value='regular'>[% l("Regular Font") %]</option>
+                            <option value='large'>[% l("Large Font") %]</option>
+                        </select>
+                    </td>
+                </tr>
+                -->
+
+            </tbody>
+        </table>
+        <input type="submit" value="[% l('Save') %]" class="opac-button"/>
+    </form>
+    [% INCLUDE "opac/parts/myopac/prefs_hints.tt2" %]
+[% END %]
diff --git a/Open-ILS/src/cwopac_templates/opac/myopac/update_username.tt2 b/Open-ILS/src/cwopac_templates/opac/myopac/update_username.tt2
new file mode 100644 (file)
index 0000000..62fe179
--- /dev/null
@@ -0,0 +1,39 @@
+[%  PROCESS "opac/parts/header.tt2";
+    PROCESS "opac/parts/misc_util.tt2";
+    WRAPPER "opac/parts/myopac/base.tt2";
+    myopac_page = "prefs"  %]
+<h3 class="sr-only">[% l('Update Username') %]</h3>
+<div id='myopac_summary_div' style="padding:0px;">
+
+    <div class="header_middle">
+        <span class="float-left">[% l('Update Username') %]</span>
+    </div>
+       
+[% IF ctx.invalid_username %]
+    <div id='account-update-email-error'> <!-- borrow css from update-email page -->
+        [% bad_user = ctx.invalid_username | html %]
+        [% l('"[_1]" is not a valid username.  Usernames cannot have any spaces, cannot begin with a number, or look like a barcode, and may be restricted by policy.  Please try a different username.', '<b>' _ bad_user _ '</b>') %]
+    </div>
+
+[% ELSIF ctx.username_exists %]
+    <div id='account-update-email-error'>
+        [% l('The username "[_1]" is taken.  Please try a different username.', '<b>' _ bad_user _ '</b>') %]
+    </div>
+
+[% ELSIF ctx.password_incorrect %]
+    <div id='account-update-email-error'>
+        [% |l %]Your current password was not correct.[% END %]
+    </div>
+
+[% END %]
+
+<form method='post' id='account-update-email' autocomplete='off'> 
+    <table> 
+        <tr><td>[% l('Current Username') %]</td><td>[% ctx.user.usrname | html %]</td></tr>
+        <tr><td>[% l('Current Password') %]</td><td><input type='password' name='current_pw'/></td></tr>
+        <tr><td>[% l('New Username') %]</td><td><input type='text' name='username' value='[% ctx.invalid_username | html %]'/></td></tr>
+        <tr><td colspan='2' align='center'><input value="[% l('Submit') %]" type='submit'/></td></tr>
+    </table>
+</form>
+
+[% END %]
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/acjs.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/acjs.tt2
new file mode 100644 (file)
index 0000000..60e4626
--- /dev/null
@@ -0,0 +1,79 @@
+[%# The only customization in this file is to change the Novelist timeout to 500 %]
+<script type="text/javascript">
+
+    /* Checks to see if a given type of added content has data to show.
+     * The first arg to callback() is boolean indicating the presence of data */
+    function acIsAvailable(bre_id, type, callback) {
+        var url = '/opac/extras/ac/' + type + '/html/r/' + bre_id;
+        dojo.xhr('HEAD', {
+            url : url,
+            failOk : true, // http://bugs.dojotoolkit.org/ticket/11568
+            error : function(err) { callback(false, bre_id, type); },
+            load : function(result) { callback(true, bre_id, type); }
+        });
+    }
+
+    [%-
+        FOR type IN ctx.added_content.keys;
+            IF ctx.added_content.$type.status == '3' # status unknown %]
+
+                dojo.addOnLoad(function() {
+                    var bre_id = '[% ctx.bre_id %]';
+                    var type = '[% type %]';
+
+                    acIsAvailable(bre_id, type, function(avail, bre_id, type) {
+                        if (avail) {
+
+                            [% IF CGI.param('expand') == 'addedcontent' %]
+
+                                // if the content is available, un-hide the tab
+                                dojo.removeClass(dojo.byId('ac:' + type), 'hidden');
+
+                            [% ELSE %]
+                                // if no default type is selected on the main tab link
+                                // set one here, since we have available content
+
+                                var link = dojo.query('[name=addedcontent]')[0];
+                                var href = link.getAttribute('href');
+                                if (!href.match('[\&;]ac=')) {
+                                    href = href.replace('#addedcontent', ';ac=' + type + '#addedcontent');
+                                    dojo.attr(link, 'href', href);
+                                    dojo.attr(dojo.query('[name=addedcontent_lbl]')[0], 'href', href);
+                                }
+
+                            [% END %]
+                        }
+                    });
+                });
+            [% END; # IF status unknown
+        END; # FOR type
+
+        ident = ctx.record_attrs.isbn_clean || ctx.record_attrs.upc;
+        IF ident;
+    -%]
+
+[%- IF ENV.OILS_NOVELIST_URL -%]
+            /* Load novelist content */
+        /* Suggestion from Novelist */
+        setTimeout(function() {
+            novSelect.loadContentForQuery(
+                {
+                    ClientIdentifier : '[% ident %]',
+                    ISBN : '[% ident %]',
+                    version : '2.1'
+                },
+                '[% ENV.OILS_NOVELIST_PROFILE %]',
+                '[% ENV.OILS_NOVELIST_PASSWORD %]',
+                function(d){
+                    // note if d.length == 0, there is no content to display
+                    // hide the Loading... text
+                    dojo.byId('novelist-loading').innerHTML = '';
+                }
+            );
+       /* Suggestion from Novelist */
+       }, 500);
+[%- END; # Novelist -%]
+
+        [% END; # IF ident
+    %]
+</script>
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/adv_qtype_selector.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/adv_qtype_selector.tt2
new file mode 100644 (file)
index 0000000..008eb21
--- /dev/null
@@ -0,0 +1,24 @@
+[%  query_types = [
+    {value => "keyword", label => l("Keyword")},
+    {value => "title", label => l("Title"), plural_label => l("Titles"), browse => 1},
+    {value => "jtitle", label => l("Journal Title")},
+    {value => "title|uniform", label => l("Uniform Title")},
+    {value => "author", label => l("Author"), plural_label => l("Authors"), browse => 1},
+    {value => "identifier|publisher", label => l("Publisher")},
+    {value => "subject", label => l("Subject"), plural_label => l("Subjects"), browse => 1},
+    {value => "series", label => l("Series"), plural_label => l("Series"), browse => 1}
+] %]
+<select name="[% name || 'qtype' %]"[% IF id; ' id="'; id ; '"' ; END -%]
+    title="[% l('Select query type:') %]">
+    [%  query_type = query_type || CGI.param('qtype') || search.default_qtypes.0;
+      FOR qt IN query_types;
+        NEXT IF browse_only AND NOT qt.browse -%]
+    <option value='[% qt.value | html %]'[%
+        query_type == qt.value ? ' selected="selected"' : ''
+    %]>[% IF plural AND qt.plural_label;
+        qt.plural_label | html;
+    ELSE;
+        qt.label | html;
+    END %]</option>
+    [% END -%]
+</select>
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/browse_qtype_selector.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/browse_qtype_selector.tt2
new file mode 100644 (file)
index 0000000..8c38daa
--- /dev/null
@@ -0,0 +1,20 @@
+[%  query_types = [
+    {value => "subject", label => l("Subject"), plural_lbel => l("Subjects"), browse => 1},
+    {value => "title", label => l("Title"), plural_label => l("Titles"), browse => 1},
+    {value => "author", label => l("Author"), plural_label => l("Authors"), browse => 1},
+    {value => "series", label => l("Series"), plural_label => l("Series"), browse => 1}
+] %]
+<select name="[% name || 'qtype' %]"[% IF id; ' id="'; id ; '"' ; END -%]
+    aria-label="[% l('Select query type:') %]">
+    [%  query_type = query_type || CGI.param('qtype') || search.default_qtypes.0;
+      FOR qt IN query_types;
+        NEXT IF browse_only AND NOT qt.browse -%]
+    <option value='[% qt.value | html %]'[%
+        query_type == qt.value ? ' selected="selected"' : ''
+    %]>[% IF plural AND qt.plural_label;
+        qt.plural_label | html;
+    ELSE;
+        qt.label | html;
+    END %]</option>
+    [% END -%]
+</select>
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/config.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/config.tt2
new file mode 100644 (file)
index 0000000..d5c9a4e
--- /dev/null
@@ -0,0 +1,195 @@
+[% 
+
+##############################################################################
+# This file contains skin-level configuration settings.
+# Many of these settings will probably migrate into actor.org_unit_settings.
+##############################################################################
+
+##############################################################################
+# Holds blocking
+##############################################################################
+# Prevent the "Place hold" link from being displayed if a copy is available.
+# This is not perfect, given the umpteen different types of holds that are
+# possible, but addresses the major use case for libraries that don't want
+# to fetch copies from the shelves.
+ctx.holds_block.enabled = 'false';
+
+##############################################################################
+# RefWorks configuration
+##############################################################################
+# RefWorks is a Web-based citation manager
+ctx.refworks.enabled = 'false';
+
+# Base URL for RefWorks
+ctx.refworks.url = 'http://www.refworks.com';
+
+# Some sites have a hosted RefWorks instance at a different URL;
+# in addition, you might want to proxy access to RefWorks - for example:
+# ctx.refworks.url = 'http://librweb.laurentian.ca/login?url=http://refworks.scholarsportal.info';
+
+##############################################################################
+# OpenURL resolution
+##############################################################################
+# Evergreen provides the ability to point at an OpenURL resolver to find
+# electronic resources for a given ISSN or ISBN. Currently, only the SFX
+# resolver is supported.
+#
+# You must enable the open-ils.resolver instance in opensrf.xml to use
+# this feature.
+##############################################################################
+
+openurl.enabled = 'false';
+openurl.baseurl = 'http://sfx.example.com/instance';
+
+##############################################################################
+# Google Analytics support
+##############################################################################
+# You can enable Google Analytics support in Evergreen by entering a
+# valid Google Analytics code and changing 'false' to 'true'
+##############################################################################
+google_analytics.enabled = 'false';
+google_analytics.code = 'UA-9999999-99';
+
+##############################################################################
+# Enable "Forgot your password?" prompt at login
+##############################################################################
+reset_password = 'true';
+
+##############################################################################
+# Hide various options from user preferences that you might not want to expose
+# if you rely on centralized authentication via open-ils.auth_proxy, like LDAP
+#
+# Username changes can be disabled by the opac.lock_usernames OU setting.
+##############################################################################
+disable_password_change = 'false';
+disable_email_change = 'false';
+
+##############################################################################
+# Some libraries do not do notifications by phone; if not true, then this
+# hides the user preference for phone notifications as well as the phone
+# notification portion of the hold dialogue
+##############################################################################
+allow_phone_notifications = 'true';
+
+##############################################################################
+# Misc. UI Settings
+##############################################################################
+# Option for full details as a default, esp. impt. for e-content
+# that uses resolver plumbing. Valid values are 'true', 'false' and 'hide'.
+# Setting this to 'true' shows full details by default but allows the link
+# to appear for 'Show Fewer Details'. The 'hide' option shows full details
+# and also suppresses the link from displaying at all.
+show_more_details.default = 'false';
+
+##############################################################################
+# Size of the jacket image to display on the record detail summary.
+# Sizes vary depending on added content provider.
+# Options are "small", "medium", and "large"
+record.summary.jacket_size = 'medium';
+
+##############################################################################
+# Define the order in which facets are displayed.  Only facets listed here 
+# will be displayed.  To show all facets sorted by name, comment out this 
+# setting.  
+# facet.display = [] # show no facets
+facet.display = [
+    {facet_class => 'author',  facet_order => ['personal', 'corporate']},
+    {facet_class => 'subject', facet_order => ['topic']},
+    {facet_class => 'series',  facet_order => ['seriestitle']},
+    {facet_class => 'subject', facet_order => ['name', 'geographic']}
+];
+facet.default_display_count = 5;
+
+##############################################################################
+# Define the advanced search limiters and labels.
+# Each entry is put into a table cell.
+# adv_label is the (translated) label for the limiter
+# adv_attr is an array of possible limiters, the first one that has any
+#   values will be used
+# adv_filter is the same as adv_attr, but for search filter groups
+# adv_size lets you set the height of the adv_attr or adv_filter select box.
+# if adv_size < 1, the box height is set to the number of options in it.
+# adv_break will end the current row. If specified with a label/attr it
+#   will do so *after* that limiter.
+# adv_special will drop in a special entry:
+#   lib_selector will put the search library box (with limit to available)
+#   pub_year will put the publication year box
+#   sort_selector will put the sort results selector
+# id DOM id used for linking labels to form controls.  They are pinned 
+#   here instead of auto-generated (from the attr type, for example) 
+#   for consistency.
+
+search.adv_config = [
+    {adv_label => l("Format"), adv_attr => [ctx.get_cgf('opac.format_selector.attr').value], id => 'adv_selector_format', adv_size => 6},
+#    {adv_label => l("Item Type"), adv_attr => ["mattype", "item_type"], id => 'adv_selector_item_type'},
+#    {adv_label => l("Item Form"), adv_attr => "item_form", id => 'adv_selector_item_form'},
+    {adv_label => l("Language"),  adv_attr => "item_lang", id => 'adv_selector_item_lang', adv_size => 6},
+    {adv_label => l("Audience"),  adv_attr => ["audience_group", "audience"], id => 'adv_selector_audience', adv_size => 6},
+#    {adv_label => l("Video Format"), adv_attr => "vr_format", id => 'adv_selector_video_format'},
+
+#    {adv_label => l("Bib Level"), adv_attr => "bib_level", id => 'adv_selector_bib_level'},
+#    {adv_label => l("Literary Form"), adv_attr => "lit_form", id => 'adv_selector_lit_form'},
+
+    {adv_label => l("Shelving Location"), adv_special => "copy_location", id => 'adv_copy_location_selector', js_only => 1, adv_break => 1},
+    {adv_label => l("Search Library"), adv_special => "lib_selector", id => 'adv_org_selector'},
+    {adv_label => l("Publication Year"), adv_special => "pub_year", id => 'adv_selector_pub_year'},
+    {adv_label => l("Sort Results"), adv_special => "sort_selector", id => 'adv_selector_sort_results'},
+];
+
+# Set the default height of the select boxes. Defaults to 4.
+#search.default_adv_select_height = 4;
+
+##############################################################################
+# For each search box the default "query type" value can be specified here
+# This is the actual backend value, not the label
+# Also note that including more than the row count entries won't add rows
+# The first entry should be used as a default for "basic" search as well
+
+search.default_qtypes = ['keyword','title','author'];
+
+##############################################################################
+# Basic Search Box definition
+# This allows selection of what, exactly, basic search uses for a selection
+# box. Previously it was hardcoded to use an attr box of mattype or item_type.
+#
+# type can be "attr" or "filter"
+# group is the attr or filter entries you want to check for
+# none_label is the label for the default nothing selected entry.
+
+search.basic_config = {
+    type => 'attr',
+    group => [ctx.get_cgf('opac.format_selector.attr').value, 'item_type'],
+    none_label => l("All Formats"),
+};
+
+##############################################################################
+# Show Google Book Previews
+# Set to 1 or 'true' to enable
+ctx.google_books_preview = 0;
+
+##############################################################################
+
+# Set a maintenance message to display in the catalogue
+#
+# ctx.maintenance_message = "The system will not be available February 29, 2104.";
+
+
+##############################################################################
+# Metarecords configuration
+# metarecords.disabled = 1; # disable all metarecord access points
+##############################################################################
+
+##############################################################################
+# Local date format (uses POSIX strftime() formatting)
+# See http://www.template-toolkit.org/docs/modules/Template/Plugin/Date.html
+# DATE_FORMAT = '%Y-%m-%d'; # for 2014-06-31 format
+##############################################################################
+
+##############################################################################
+# Local time format (uses POSIX strftime() formatting)
+# See http://www.template-toolkit.org/docs/modules/Template/Plugin/Date.html
+# TIME_FORMAT = '%H:%M:%S'; # for 16:32:32 (24 hour) format
+# TIME_FORMAT = '%H:%M'; # for 16:32 (24 hour) format
+##############################################################################
+
+%]
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/cw-place_hold.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/cw-place_hold.tt2
new file mode 100644 (file)
index 0000000..497688b
--- /dev/null
@@ -0,0 +1,191 @@
+[%  PROCESS "opac/parts/misc_util.tt2";
+    PROCESS "opac/parts/hold_error_messages.tt2";
+    PROCESS "opac/parts/metarecord_hold_filters.tt2";
+%]
+
+<div id='holds_box' class='canvas' style='margin-top: 6px;'>
+    <h1>[% l('Place Hold') %]</h1>
+
+    [% some_holds_allowed = -1 %]
+      
+    <form method="post">
+        <input type="hidden" name="hold_type" value="[% CGI.param('hold_type') | html %]" />
+        [%  
+            redirect = CGI.param('hold_source_page') || CGI.param('redirect_to') || CGI.referer;
+            # since we have to be logged in to get this far, return to a secure page
+            redirect = redirect.replace('^http:', 'https:') 
+        %]
+        <input type="hidden" name="redirect_to" value="[% redirect | html %]" />
+        <input type="hidden" name="hold_source_page" value="[% CGI.param('hold_source_page') | html %]" />
+
+        [% IF ctx.is_staff %]
+        <p class="staff-hold">
+            <input type="radio" id="hold_usr_is_requestor_not"
+                onchange="staff_hold_usr_input_disabler(this);"
+                name="hold_usr_is_requestor" value="0"
+                />
+            <label for="hold_usr_is_requestor_not">
+                [% l("Place hold for patron by barcode:") %]
+            </label>
+            <input type="text" name="hold_usr" id="hold_usr_input" 
+              value="[% CGI.param('usr_barcode') | html %]"
+              onchange="staff_hold_usr_barcode_changed();" 
+              onpaste="setTimeout(staff_hold_usr_barcode_changed,1);" 
+              onkeypress="return no_hold_submit(event)" autofocus /> 
+            <span id="patron_name"></span>
+            <span id="patron_usr_barcode_not_found" style="display: none">
+              [% l('Patron barcode was not found') %]
+            </span><br />
+            <input type="hidden" id="staff_barcode" 
+              value="[% ctx.staff_recipient.card.barcode | html %]"/>
+            <span>
+                <input type="radio" id="hold_usr_is_requestor"
+                    onchange="staff_hold_usr_input_disabler(this);"
+                    name="hold_usr_is_requestor" value="1" />
+                <label for="hold_usr_is_requestor">
+                    [% l("Place this hold for me ([_1] [_2])", ctx.user.first_given_name, ctx.user.family_name) | html %]
+                </label>
+            </span>
+        </p>
+        [% END %]
+
+        <!-- loop through the holds and display status of request where appropriate -->
+        <table id='hold-items-list'>
+        [% FOR hdata IN ctx.hold_data;
+            attrs = {marc_xml => hdata.marc_xml};
+            PROCESS get_marc_attrs args=attrs;
+            this_hold_disallowed = 0;
+
+            IF CGI.param('hold_type') == 'M';
+              IF hdata.metarecord_filters.formats.size == 0;
+                this_hold_disallowed = 1;
+                # if this is the first hold and it's disallowed, 
+                # assume all holds are, until we proven otherwise
+                SET some_holds_allowed = 0 IF some_holds_allowed == -1;
+              ELSE; some_holds_allowed = 1; END;
+            END %]
+
+            <tr>
+                <td>
+                    [% IF !this_hold_disallowed %]
+                    <input type="hidden" name="hold_target" value="[% hdata.target.id | html %]" />
+                    [% END %]
+                    <div class='hold-items-list-title'>[% attrs.title_extended | html %]</div>
+                    [% IF hdata.parts AND !this_hold_disallowed %]
+                        [% IF hdata.parts.size > 0 %]
+                        <div style='padding-left: 10px; font-weight: bold;'><!-- Added more weight to font - NOBLE -->
+                            <span><label for='select_hold_part'>[%
+                                hdata.part_required ? l('Select a Part:') : l('Get a Complete Set (default) or Select a Part:') #changed wording - NOBLE
+                            %]</label></span>
+                            <select id='select_hold_part' name='part'>
+                                [% IF !hdata.part_required %]
+                                <option selected='selected' value=''>[% l('- Complete Set -') %]</option><!-- Changed wording from "All Parts" - NOBLE -->
+                                [% END %]
+                                [% FOR part IN hdata.parts %]
+                                <option value='[% part.id %]'>[% part.label | html %]</option>
+                                [% END %]
+                            </select>
+                        </div>
+                        [% ELSE %]
+                        <input type='hidden' name='part' value=''/>
+                        [% END %]
+                    [% END %]
+                    [% IF NOT metarecords.disabled %]
+                        [% IF CGI.param('hold_type') == 'T' AND hdata.record.metarecord %]
+                        <!-- Grab the bre_id so that we can restore it if user accidentally clicks advanced options -->
+                           [% bre_id = hdata.target.id %]
+                            <a  id='advanced_hold_link'
+                                href="[% mkurl('', {hold_type => 'M', hold_target => hdata.record.metarecord.id, bre_id => bre_id}) %]">
+                                [% l('Advanced Hold Options') %]</a>
+                        [% END %]
+                        [% IF CGI.param('hold_type') == 'M' AND CGI.param('bre_id') %]
+                            <input type="hidden" name="bre_id" value="[% CGI.param('bre_id') %]" />
+                            <a id='basic_hold_link'
+                               href="[% mkurl('', {hold_target => CGI.param('bre_id'), hold_type => 'T'}) %]">
+                                [% l('Basic Hold Options') %]</a>
+                        [% END %]
+                        [% IF hdata.metarecord_filters.formats.size OR # should this be size > 1
+                            (hdata.metarecord_filters.langs.size && hdata.metarecord_filters.langs.size > 1);
+                            PROCESS metarecord_hold_filters_selector hold_data=hdata;
+                        END;
+                    END %]
+                </td>
+            </tr>
+
+            [% IF this_hold_disallowed %]
+              <tr><td>
+                <div class="mr_holds_no_formats">
+                [% l('This item does not have any formats available for holds placement') %]
+                </div>
+              </td></tr>
+            [% END %]
+
+            [%  IF !loop.last AND ctx.hold_data.size > 1 %]
+            <tr class="holds_item_row_separator"><td> </td></tr>
+            [% END %]
+
+        [% END %]
+        </table>
+
+        [% IF some_holds_allowed %]
+
+        <p>
+            [%- org_select_id = 'pickup_lib'; -%]
+            <label for="[% org_select_id %]">[%l('Pickup location:') %]</label>
+            [% PROCESS "opac/parts/org_selector.tt2";
+                INCLUDE build_org_selector name='pickup_lib' 
+                    value=ctx.default_pickup_lib id=org_select_id 
+                    can_have_vols_only=1 hold_pickup_lib=1 %]
+        </p>
+        <p>
+            [% l('Notify when hold is ready for pickup?') %]
+            <blockquote>
+                <input type="checkbox" id="email_notify" name="email_notify" value="t"
+                    [% IF !ctx.user.email %]disabled="true"[% ELSIF ctx.default_email_notify %]checked="checked"[% END %]/>
+                    <label for="email_notify">[% l('Yes, by Email') %]</label><br/>
+                <blockquote>
+                    [% IF !ctx.user.email and !ctx.is_staff; l('No configured Email address. See "My Account" for setting your Email address.');
+                     ELSE; l('Email Address:') %] <span name="email_address">[% ctx.user.email %]</span>[% END %]
+                </blockquote>
+                [%- IF allow_phone_notifications == 'true' and !ctx.is_staff %]
+                <div class="suppress"><input type="checkbox" id="phone_notify_checkbox" name="phone_notify_checkbox"
+                    [% IF ctx.default_phone_notify %]checked="checked"[% END %]/>
+                    <label for="phone_notify_checkbox">[% l('Yes, by Phone') %]</label><br/>
+                <blockquote>
+                    <label>[% l('Phone Number:') %]<input type="text" name="phone_notify" [% setting = 'opac.default_phone';
+                    IF ctx.user_setting_map.$setting; %] value='[% ctx.user_setting_map.$setting | html %]'
+                    [%- ELSIF ctx.user.day_phone; %] value='[% ctx.user.day_phone | html %]' [% END %]/></label>
+                </blockquote></div><!-- End Suppress. NOBLE -->
+<!-- JFK code begin - remove suppress for staff client -->
+                [%- ELSIF allow_phone_notifications == 'true' and ctx.is_staff %]
+                <div><input type="checkbox" id="phone_notify_checkbox" name="phone_notify_checkbox"
+                    [% IF ctx.default_phone_notify %]checked="checked"[% END %]/>
+                    <label for="phone_notify_checkbox">[% l('Yes, by Phone') %]</label><br/>
+                <blockquote>
+                    <label>[% l('Phone Number:') %]<input type="text" name="phone_notify" [% setting = 'opac.default_phone';
+                    IF ctx.user_setting_map.$setting; %] value='[% ctx.user_setting_map.$setting | html %]'
+                    [%- ELSIF ctx.user.day_phone; %] value='[% ctx.user.day_phone | html %]' [% END %]/></label>]
+                </blockquote></div>
+<!-- JFK code end -->
+                [% END %]
+                [% IF ctx.get_org_setting(ctx.search_ou, 'sms.enable') == 1 %]
+                <input type="checkbox" id="sms_notify_checkbox" name="sms_notify_checkbox"
+                    [% IF ctx.default_sms_notify %]checked="checked"[% END %]/>
+                    <label for="sms_notify_checkbox">[% l('Yes, by Text Messaging') %]</label><br/>
+                <blockquote>
+<!-- Added bottom padding to separate boxes - NOBLE -->
+                    <div style="padding-bottom:5px;">[% INCLUDE "opac/parts/sms_carrier_selector.tt2" %]</div>
+                    [% INCLUDE "opac/parts/sms_number_textbox.tt2" %]<br/>
+                </blockquote>
+                [% END %]
+            </blockquote>
+        </p>
+<!-- Added style to push buttons over - NOBLE -->
+        <input id="place_hold_submit" type="submit" name="submit" 
+            value="[% l('Submit') %]" title="[% l('Submit') %]"
+            alt="[% l('Submit') %]" class="opac-button" />
+        [% END # some_holds_allowed %]
+        <input type="reset" name="cancel" onclick="window.location='[% redirect | html %]'" value="[% l('Cancel') %]" id="holds_cancel" class="opac-button" />
+    </form>
+</div>
+
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/footer.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/footer.tt2
new file mode 100644 (file)
index 0000000..a22ccf2
--- /dev/null
@@ -0,0 +1,31 @@
+<div id="footer-wrap">
+<div id="footer">
+    <a href="http://digitalbooks.cwmars.org" target="_blank">[% l('OverDrive Digital Catalog') %]</a> &nbsp;|&nbsp;
+    <a href="http://digitalbooks.cwmars.org/KIDS" target="_blank">[% l('Kids Digital Books Catalog') %]</a> &nbsp;|&nbsp;
+    <a href="http://www.cwmars.org/content/commonwealth-catalog" target="_blank">[% l('Commonwealth Catalog') %]</a> &nbsp;|&nbsp;
+    <a href="http://www.cwmars.org" target="_blank">[% l('C/W MARS Home') %]</a> &nbsp;|&nbsp;
+    <a href="http://ebooks.masslibsystem.org" target="_blank">[% l('Commonwealth eBook Collections') %]</a> &nbsp; | &nbsp;
+    <a href="http://www.cwmars.org/content/using-online-catalog" target="_blank">[% l('Help') %]</a>
+    [% IF ctx.timing %]
+    <div id="timing">
+        [% FOR event IN ctx.timing %]
+        At <span class="timing-time">[% event.0 | format("%0.4f") %]</span>:
+        <span class="timing-event">[% event.1 %]</span><br />
+        [% END %]
+    </div>
+    [% END %]
+    <div id="copyright_text" style="margin-top: 2em;">
+        [% l('Copyright &copy; 2006-[_1] Georgia Public Library Service, and others', date.format(date.now, '%Y')) %]
+    </div>
+    <div id="footer_logo">
+        [% l('V - Powered by') %]
+        <a href="http://evergreen-ils.org">
+            <img src="[% ctx.media_prefix %]/opac/images/eg_tiny_logo.png"
+                style="border:none; width: 94px; height: 16px;"
+                alt="[% l('Evergreen') %]"
+            />
+        [% l('provided through C/W MARS, Inc.') %]
+        </a>
+    </div>
+</div>
+</div>
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/form.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/form.tt2
new file mode 100644 (file)
index 0000000..4ceda0e
--- /dev/null
@@ -0,0 +1,144 @@
+<!-- TODO: MOVE INTO SEPARATE FORGOT-PASSWORD PAGE \r
+\r
+<div class="hide_me">\r
+       <div class='login_text color_1' style='padding: 4px; text-align: center;'>\r
+               <span>[% l("Login") %]</span>\r
+       </div>\r
+       <br/>\r
+</div>\r
+<table id='change_pw_table' class='data_grid hide_me' style='margin-left: 20px;' width='95%'>\r
+       <thead>\r
+        <tr><td colspan='2' align='center'><b>[% l("Password") %]</b></td></tr>\r
+    </thead>\r
+    <tbody>\r
+        <tr>\r
+            <td colspan='2' style='padding:10px;'>\r
+                [% l("This appears to be the first time you have logged in.  You will need to change your password.") %]\r
+                [% l("The password must be at least 7 characters in length,\r
+ contain at least one letter (a-z/A-Z),\r
+ and contain at least one number.") %]\r
+            </td>\r
+        </tr>\r
+        <tr>\r
+            <td>[% l("Enter your current password") %]</td>\r
+            <td><input type='password' id='change_pw_current'/></td>\r
+        </tr>\r
+        <tr>\r
+            <td>[% l("Enter the new password") %]</td>\r
+            <td><input type='password' id='change_pw_1'/></td>\r
+        </tr>\r
+        <tr>\r
+            <td>[% l("Re-type the new password for verification") %]</td>\r
+            <td><input type='password' id='change_pw_2'/></td>\r
+        </tr>\r
+        <tr><td><br/></td><td/></tr>\r
+        <tr class='color_1'>\r
+            <td colspan='2' align='center'>\r
+                <span class='login_text' style='margin-right: 20px;'>\r
+                    <input type='submit' value='[% l("Update Password") %]'  id='change_pw_button'/>\r
+                </span>\r
+            </td>\r
+        </tr>\r
+    </tbody>\r
+</table>\r
+\r
+\r
+<span id='pw_no_match' class='hide_me'>[% l("Passwords do not match") %]</span>\r
+<span id='pw_update_successful' class='hide_me'>[% l("Password successfully updated") %]</span>\r
+<span id='pw_not_strong' class='hide_me'>\r
+    [% l("The password provided is not strong enough.") %]\r
+    [% 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.") %]\r
+</span>\r
+\r
+ ^== TODO: MOVE INTO SEPARATE FORGOT-PASSWORD PAGE  -->\r
+\r
+[% IF ctx.login_failed_event %]\r
+<div id='login-failed-message'>\r
+[%\r
+    IF ctx.login_failed_event.textcode == 'PATRON_CARD_INACTIVE';\r
+        l("The barcode used to login is marked as inactive.  Please contact your local library.");\r
+    ELSIF ctx.login_failed_event.textcode == 'PATRON_INACTIVE';\r
+        l("This account has been deactivated.  Please contact your local library.");\r
+    ELSE;\r
+        l("Login failed. The username or password provided was not valid.  \r
+            Ensure Caps-Lock is off and try again or contact your local library.");\r
+    END;\r
+%]\r
+</div>\r
+[% END %]\r
+\r
+<div>\r
+    <div style="height:20px;"></div>\r
+    <form method='POST'>\r
+        <table cellpadding="0" cellspacing="0" border="0">\r
+            <tr>\r
+                <td valign="top" width="676" class="login_boxes left_brain">\r
+                    <table cellpadding="0" cellspacing="0" border="0"\r
+                        width="100%">\r
+                        <tr>\r
+                               <td colspan="2" style="padding-bottom: 10px;">\r
+                                <h1>[% l('Log in to Your Account') %]</h1>\r
+                                [% l('Please enter the following information:') %]\r
+                                <br /><br />\r
+                            </td>\r
+                        </tr>\r
+                        <tr>\r
+                            <td width="42%" class="lbl1">\r
+                                [% l('Username') %]\r
+                                <br />\r
+                                <span class="lbl2">\r
+                                    [% l('Enter your barcode or user name.') %]\r
+                                </span>\r
+                                <br /><br />\r
+                            </td>\r
+                            <td width="58%" valign="top">\r
+                                <div class="input_bg">\r
+                                    <input type="text" id="username_field" name="username"/>\r
+                                </div>\r
+                            </td>\r
+                        </tr>\r
+                        <tr>\r
+                            <td colspan="2">\r
+                                <div style="height:15px;"></div>\r
+                            </td>\r
+                        </tr>\r
+                        <tr>\r
+                            <td valign="top" class="lbl1">\r
+                                [% l('Password') %]<br />\r
+                                [% INCLUDE "opac/parts/login/password_hint.tt2" %]\r
+                            </td>\r
+                            <td valign="top">\r
+                                <div class="input_bg">\r
+                                    <input name="password" type="password" />\r
+                                </div>\r
+                                <div style="padding-top:7px;">\r
+                                    [%\r
+                                        # If no redirect is offered or it's leading us back to the \r
+                                        # login form, redirect the user to My Account\r
+                                        redirect = CGI.param('redirect_to') || ctx.referer;\r
+                                        IF !redirect OR redirect.match(ctx.path_info _ '$');\r
+                                            redirect = CGI.url('-full' => 1) _ '/opac/myopac/main';\r
+                                        END;\r
+                                        redirect = redirect  | replace('^http:', 'https:');\r
+                                    %]\r
+                                    <input type='hidden' name='redirect_to' value='[% redirect %]'/>\r
+                                    <input type="checkbox" name="persist" id="login_persist" /><label for="login_persist"> [% l('Stay logged in?') %]</label>\r
+                                </div>\r
+                                <div style="padding-top:14px;">\r
+                                    <input type="submit" value="[% l('Log in') %]" alt="[% l('Log in') %]" class="opac-button" />\r
+                                    [% IF reset_password %]\r
+                                    <a href='[% mkurl(ctx.opac_root _ '/password_reset', {}, 1) %]'>[% l('Forgot your password?') %]</a>\r
+                                    [% END %]\r
+                                </div>\r
+                            </td>\r
+                        </tr>\r
+                    </table>\r
+                    <br /><br />\r
+                </td>\r
+                   <td><div style="width:10px;"></div></td>\r
+                [% INCLUDE "opac/parts/login/help.tt2" %]\r
+            </tr>\r
+        </table>\r
+    </form>\r
+    <div class="clear-both"></div>\r
+</div>\r
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/help.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/help.tt2
new file mode 100644 (file)
index 0000000..85a05ba
--- /dev/null
@@ -0,0 +1,11 @@
+<td class="login_boxes right_brain" align="center" valign="top" width="291">
+<p>
+    <a href="http://www.cwmars.org/content/using-online-catalog"><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.cwmars.org/content/frequently-asked-questions-0"><img
+        alt="[% l('FAQs') %]" src="[% ctx.media_prefix %]/images/faqs-btn.png" style="margin-top:13px;" /></a>
+</td>
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/hold_status.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/hold_status.tt2
new file mode 100644 (file)
index 0000000..58b4d6a
--- /dev/null
@@ -0,0 +1,29 @@
+[% BLOCK get_hold_status %]
+    <div>
+    [% 
+        IF hold.hold.status == 4;
+            l("Available") | html;
+            IF ahr.shelf_expire_time;
+                '<br/>';
+                l('Expires [_1]', 
+                    date.format(ctx.parse_datetime(ahr.shelf_expire_time), DATE_FORMAT)) | html;
+            END;
+
+        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) | html;
+
+        ELSIF hold.hold.status == 3 OR hold.hold.status == 8;
+            l("In Transit") | html;
+
+        ELSIF hold.hold.status < 3;
+            l("Waiting for copy") | html;
+        END 
+    %]
+    </div>
+    <div>
+        [% l("[quant,_1,hold,holds] on [quant,_2,circulating copy,circulating copies]", 
+            hold.hold.queue_position, hold.hold.potential_copies) | html %]
+    </div>
+[% END %]
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/home_searchbar.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/home_searchbar.tt2
new file mode 100644 (file)
index 0000000..67e9f0c
--- /dev/null
@@ -0,0 +1,78 @@
+<center>
+[% PROCESS "opac/parts/org_selector.tt2" %]
+<div id="search-wrapper">
+    [% UNLESS took_care_of_form -%]
+    <form action="[% ctx.opac_root %]/results" method="get">
+    [%- END %]
+    <div class="searchbar">
+        <span class='search_box_wrapper'>
+            <input type="text" id="search_box" name="query" style="width:40em; height: 1.5em; font-size: 16px;" 
+                value="[% is_advanced ? ctx.naive_query_scrub(ctx.processed_search_query) : CGI.param('query') | html %]"
+                [%- IF use_autosuggest.enabled == "t" %]
+                dojoType="openils.widget.AutoSuggest" type_selector="'qtype'"
+                submitter="this.textbox.form.submit();"
+                [%-     IF use_autosuggest.value.search('opac_visible') %]
+                store_args='{"org_unit_getter": function() { return [% ctx.search_ou %]; }}'
+                [%-     END # opac_visible -%]
+                [%- ELSE -%]
+                    [% IF basic_search != "f" %] autofocus [% END %] x-webkit-speech
+                [%- END # autosuggest enabled %] />
+        </span>
+
+<br />
+[%- l(' ');
+        IF search.basic_config.type == 'attr';
+            INCLUDE "opac/parts/coded_value_selector.tt2"
+                attr=search.basic_config.group none_ok=1 none_label=search.basic_config.none_label;
+        ELSIF search.basic_config.type == 'filter';
+            INCLUDE "opac/parts/filter_group_selector.tt2"
+                filter_group=search.basic_config.group none_ok=1 none_label=search.basic_config.none_label;
+        END;
+            l(' for ');
+        %]
+
+
+    [%- INCLUDE "opac/parts/qtype_selector.tt2" id="qtype";
+            l(' in '); INCLUDE build_org_selector show_loc_groups=1
+    %]
+
+<span>
+        <input id='search-submit-go' type="submit" value="[% l('Search') %]" alt="[% l('Search') %]" class="opac-button"
+            onclick='setTimeout(function(){$("search-submit-spinner").className=""; $("search-submit-go").className="hidden"}, 2000)'/>
+        <img id='search-submit-spinner' src='/opac/images/progressbar_green.gif' style='height:16px;width:16px;' class='hidden' alt=''/>
+    </span>
+    </div>
+    [% IF ctx.bookbag %]
+    <div id="search-only-bookbag-container">
+        <input type="checkbox" id="search-only-bookbag" name="bookbag"
+            value="[% ctx.bookbag.id | html %]" checked="checked" />
+        <label for="search-only-bookbag">
+            [% l('Search only within the chosen list') %]
+        </label>
+    </div>
+    [% END %]
+    [% IF is_advanced || is_special %]
+    <div>
+        <input type="hidden" name="_adv" value="1" />
+        [% IF ctx.processed_search_query OR (NOT is_advanced AND NOT is_special) %]
+        <input name='page' type='hidden' value="0" />
+        [% END %]
+    </div>
+    [%- END %]
+    [% UNLESS took_care_of_form %]</form>[% END %]
+    [% IF (is_advanced AND NOT is_special) AND CGI.param('qtype') %]
+    <div class="opac-auto-102">
+        [ <a href="[% mkurl(ctx.opac_root _ '/advanced') %]">[%
+            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>
+</center>
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/homesearch.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/homesearch.tt2
new file mode 100644 (file)
index 0000000..92092e6
--- /dev/null
@@ -0,0 +1,15 @@
+<div>\r
+<h1>New Look and New Features!</h1>\r
+<p>We've added <strong>Novelist Select</strong> to our online catalog. Now, in addition to seeing the items you're looking for in the catalog, you'll also see:\r
+<ul>\r
+<li>Suggestions for other titles you might also like</li>\r
+<li>Other authors who might interest you</li>\r
+<li>Summaries &amp; Reviews</li>\r
+<li>Recommended lists of titles &amp; articles from Novelist</li>\r
+<li>Reader reviews &amp; ratings</li>\r
+</ul>\r
+Just search for things as you normally would then click on a title you're interested in to see all the new content.</p>\r
+<p>\r
+Everything is designed to make your experience richer. We hope you enjoy it!\r
+</p>\r
+</div>\r
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/login/form.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/login/form.tt2
new file mode 100644 (file)
index 0000000..f658346
--- /dev/null
@@ -0,0 +1,65 @@
+[% 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 id='login-form-box' class='login_boxes left_brain' style='float:left'>
+    <h1>[% l('Log in to Your Account') %]</h1>
+    [% l('Please enter the following information:') %]
+    <form method='POST'>
+        <table>
+            <tr>
+                <td style="width: 20em; vertical-align: top; padding-top: 1.5em;" class='lbl1'><label for='username_field'>[% l('Library Card Number or Username') %]</label>
+                    <div class="lbl2">[% l('Enter your barcode (no spaces) or user name.') %]</div>
+                </td>
+                <td style="vertical-align: top; padding-top: 1.5em;">
+                    <div class="input_bg">
+                        <input type="text" id="username_field" name="username" autofocus />
+                    </div>
+                </td>
+            </tr>
+            <tr>
+                <td class="lbl1" style="width: 20em; vertical-align: top; padding-top: 1.5em">
+                    <label for="password_field">[% l('Password or PIN') %]</label>
+                    <div>[% INCLUDE "opac/parts/login/password_hint.tt2" %]</div>
+                </td>
+                <td  style="vertical-align: top; padding-top: 1.5em;">
+                    <div class="input_bg">
+                        <input id="password_field" name="password" type="password" />
+                    </div>
+                    <div title="If you check the checkbox, you will stay logged in for up to 2 weeks unless you log out.">
+                        [%
+                            # 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" id="login_persist" /><label for="login_persist"> [% l('Stay logged in?') %]</label>
+                    </div>
+                    <div style="padding-top: 1em; margin-right: 1em;">
+                        <input type="submit" value="[% l('Log in') %]" alt="[% l('Log in') %]" class="opac-button" />
+                        [% IF reset_password %]
+                        <a href='[% mkurl(ctx.opac_root _ '/password_reset', {}, 1) %]'>[% l('Forgot your password?') %]</a>
+                        [% END %]
+                    </div>
+                </td>
+            </tr>
+        </table>
+    </form>
+<img title="[% l('To see the details of our secure certificate, click on the little padlock at the beginning of the navigation bar in your browser.') %]" src="[% ctx.media_prefix %]/opac/images/comodo_secure_76x26_transp.png" />
+</div>
+<div style='float:right; max-width: 200px; text-align: center; margin-right: 25%;'>[% INCLUDE "opac/parts/login/help.tt2" %]</div>
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/login/help.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/login/help.tt2
new file mode 100644 (file)
index 0000000..9d6c20c
--- /dev/null
@@ -0,0 +1,11 @@
+<!-- <td class="login_boxes right_brain" align="center" valign="top" width="291"> -->
+<p>
+    <a href="http://www.cwmars.org/content/using-online-catalog"><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.cwmars.org/content/frequently-asked-questions-0"><img
+        alt="[% l('FAQs') %]" src="[% ctx.media_prefix %]/images/faqs-btn.png" style="margin-top:13px;" /></a>
+<!-- </td> -->
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/login/password_hint.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/login/password_hint.tt2
new file mode 100644 (file)
index 0000000..6b8b7da
--- /dev/null
@@ -0,0 +1,4 @@
+<div class="lbl2">
+[%- l('If you do not remember your password, please click the Forgot your password link or contact your library.'); %]
+<p><b> Note:</b> Your username and password are both case-sensitive.</p>
+</div>
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/metarecord_hold_filters.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/metarecord_hold_filters.tt2
new file mode 100644 (file)
index 0000000..6c8cc2a
--- /dev/null
@@ -0,0 +1,95 @@
+[%#
+Draws the format multi-select and the language multi-select for
+limiting the set of desired records for a given metarecord.
+%]
+
+<style>
+  /* TODO: MOVE ME */
+  .metarecord_filters {
+      padding: 5px;
+      margin-top: 5px;
+      border-bottom: 1px solid #333;
+      border-top: 1px solid #333;
+  }
+  .metarecord_filter_container {
+    float : left;
+    margin-right: 10px;
+  }
+  .metarecord_filter_container select {
+    padding: 2px;
+    width: 13em; /* consistent w/ adv search selectors */
+  }
+  .metarecord_filter_header {
+    padding-bottom: 5px;
+  }
+</style>
+
+[% BLOCK metarecord_hold_filters_selector;
+    # in edit mode, pull the target from the existing hold
+    target_id = hold_data.hold.hold.target || hold_data.target.id;
+
+    selected_formats = {};
+    selected_langs = {};
+    FOR fmt IN hold_data.metarecord_selected_filters.formats;
+        code = fmt.code;
+        selected_formats.$code = fmt;
+    END;
+    FOR lang IN hold_data.metarecord_selected_filters.langs;
+        code = lang.code;
+        selected_langs.$code = lang;
+    END;
+%]
+
+<div class="metarecord_filters">
+<div><p><strong>This hold will be filled by the first item available in any of the formats or languages you have chosen.</strong><br /><a class="tooltips" href="#"><strong>More Information<img alt="More Information" src="/images/question-mark.png"></strong><span>The selections below DO NOT place holds on more than one item. If you select more than one format, your hold will be filled by the first available copy in any selected format.<br /><br /> For example, you might see a regular print, large print or audiobook option. If you just want a paper copy, you might select regular print and large print, but not the audiobook.</span></a></p></div>
+  <div class="metarecord_filter_container">
+    <div class="metarecord_filter_header">
+      <div>[% l('Select your desired format(s).') %]</div>
+      <div>[% l('If none are selected, any available formats may be used.') %]</div>
+    </div>
+    <select multiple='multiple' 
+      name="metarecord_formats_[% target_id %]">
+      [% FOR ccvm IN
+          hold_data.metarecord_filters.formats.sort('search_label');
+          NEXT IF ccvm.opac_visible == 'f' %]
+        <option value="[% ccvm.code %]"[%- code = ccvm.code; 
+            IF selected_formats.$code %] selected='selected'[% END -%]>
+          [% ccvm.search_label | html %]
+        </option>
+      [% END %]
+    </select>
+  </div>
+  [% IF hold_data.metarecord_filters.langs.size;
+        my_lang = ctx.get_i18n_l(ctx.eg_locale).marc_code;
+  %]
+  <div class="metarecord_filter_container">
+    <div class="metarecord_filter_header">
+      <div>[% l('Select your desired language(s).') %]</div>
+      <div>[% l('If none are selected, any available languages may be used.') %]</div>
+    </div>
+    <select multiple='multiple' 
+      name="metarecord_langs_[% target_id %]">
+      [% FOR lang_ccvm IN hold_data.metarecord_filters.langs.sort('value');
+            NEXT IF lang_ccvm.opac_visible == 'f';
+            selected = 0; 
+            code = lang_ccvm.code;
+            IF selected_langs.size;
+                # user has already selected their preferred language(s)
+                SET selected = 1 IF selected_langs.$code;
+
+            ELSIF !hold_data.hold.hold.target; # new hold
+                # no prefered language selected; use current locale
+                SET selected = 1 IF code == my_lang;
+            END;
+        %]
+        <option value="[% lang_ccvm.code %]"[%- 
+            IF selected %] selected='selected'[%- END %]>
+          [% lang_ccvm.value | html %]
+        </option>
+      [% END %]
+    </select>
+  </div>
+  [% END %]
+  <div class="clear-both">&nbsp;</div>
+</div>
+[% END # metarecord_hold_filters_selector %]
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/misc_util.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/misc_util.tt2
new file mode 100644 (file)
index 0000000..36659e0
--- /dev/null
@@ -0,0 +1,623 @@
+[% 
+    # Support multiscript records via alternate graphic 880 fields
+    # get_graphic_880s(target_field='100')
+    # See "Model A" in http://www.loc.gov/marc/bibliographic/ecbdmulti.html
+    # and $6 description in http://www.loc.gov/marc/bibliographic/ecbdcntf.html
+    MACRO get_graphic_880s BLOCK;
+        FOR node IN xml.findnodes('//*[@tag="' _ target_field _ '"]');
+            raw_vals = [];
+            core_val = '';
+            FOR subnode IN node.findnodes('./*[not(contains("w 0 4 5 6 7 8 9", @code))]');
+                raw_vals.push(subnode.textContent());
+            END;
+            core_val = raw_vals.join(" ");
+            raw_vals = [];
+
+            linked_fields = [];
+            FOR sub IN node.findnodes('./*[@code="6"]');
+                linked_fields.push(sub.textContent);
+            END;
+            graphics = [];
+            get_linked_880s;
+            graphic_880s.push({
+                primary => {"occur" => occurrence, "value" => core_val},
+                graphic => graphics
+            });
+        END;
+    END;
+
+    MACRO get_linked_880s BLOCK;
+        FOR link_field IN linked_fields;
+            target = target_field _ link_field.substr(3);
+            # Get the linked 880 value
+            raw_val = '';
+            dir = '';
+            occurrence = '';
+            script = '';
+            FOR node IN xml.findnodes('//*[@tag="880"]');
+                # Operate only on the target linked fields
+                FOR linknode IN node.findnodes('./*[@code="6"]');
+                    lf = linknode.textContent();
+                    IF lf.substr(0, target.length) == target;
+                        occurrence = lf.substr(4, 2);
+                        rawscript = lf.substr(7, 2);
+                        SWITCH rawscript;
+                        CASE '(3';
+                            script = 'Arabic';
+                        CASE '(B';
+                            script = 'Latin';
+                        CASE '$1';
+                            script = 'CJK';
+                        CASE '(N';
+                            script = 'Cyrillic';
+                        CASE '(S';
+                            script = 'Greek';
+                        CASE '(2';
+                            script = 'Hebrew';
+                        END;
+
+                        rawdir = lf.substr(9, 1);
+                        SWITCH rawdir;
+                        CASE 'r';
+                            dir = 'rtl';
+                        END;
+
+                        raw_vals = [];
+                        FOR subnode IN node.findnodes('./*[not(contains("w 0 5 6 8 9", @code))]');
+                            raw_vals.push(subnode.textContent());
+                        END;
+                        raw_val = raw_vals.join(" ");
+                    END;
+                END;
+            END;
+            graphics.push({
+                occur => occurrence,
+                value => raw_val,
+                script => script,
+                dir => dir
+            });
+        END;
+    END;
+
+    BLOCK get_ccvm_icon;
+        ctx.media_prefix _ '/images/format_icons/' _ ccvm.ctype _ '/' _ ccvm.code _ '.png';
+    END;
+
+    # Extract MARC fields from XML
+    #   get_marc_attrs( { marc_xml => doc } )
+    BLOCK get_marc_attrs;
+        xml = args.marc_xml;
+
+        # Map item types to schema.org types; impedance mismatch :(
+        args.schema.itemtype = {};
+        schema_typemap = {};
+
+        schema_typemap.bluray = 'Movie'; # Movie could also be TVSeries
+        schema_typemap.book = 'Book';
+        schema_typemap.braille = 'Book';
+        schema_typemap.casaudiobook = 'Book AudioObject';
+        schema_typemap.casmusic = 'MusicAlbum';
+        schema_typemap.cdaudiobook = 'Book AudioObject';
+        schema_typemap.cdmusic = 'MusicAlbum';
+        schema_typemap.dvd = 'Movie';
+        schema_typemap.eaudio = 'AudioObject';
+        schema_typemap.ebook = 'Book';
+        # schema_typemap.equip = '';
+        schema_typemap.evideo = 'Movie';
+        # schema_typemap.kit = '';
+        schema_typemap.lpbook = 'Book';
+        schema_typemap.map = 'Map';
+        # schema_typemap.microform = '';
+        schema_typemap.music = 'MusicAlbum';
+        schema_typemap.phonomusic = 'MusicAlbum';
+        # schema_typemap.phonospoken = '';
+        # schema_typemap.picture = ''; Painting or Photograph?
+        schema_typemap.score = 'Book'; # schema.org has no generic Music type
+        schema_typemap.serial = 'Periodical';
+        schema_typemap.software = 'SoftwareApplication';
+        schema_typemap.vhs = 'Movie';
+
+        schema_typemap.a = 'Book';
+        schema_typemap.e = 'Map';
+        schema_typemap.j = 'MusicAlbum';
+
+        # Hard-coded to match defaults in config.copy_status for all OPAC-visible statuses
+        schema_copy_status = {};
+        schema_copy_status.0 = '<link property="availability" href="http://schema.org/InStock" />'; # Available
+        schema_copy_status.1 = '<link property="availability" href="http://schema.org/OutOfStock" />'; # Checked out
+        schema_copy_status.5 = '<link property="availability" href="http://schema.org/PreOrder" />'; # In process
+        schema_copy_status.6 = '<link property="availability" href="http://schema.org/PreOrder" />'; # In transit
+        schema_copy_status.7 = '<link property="availability" href="http://schema.org/InStock" />'; # Reshelving
+        schema_copy_status.8 = '<link property="availability" href="http://schema.org/OutOfStock" />'; # On holds shelf
+        schema_copy_status.9 = '<link property="availability" href="http://schema.org/PreOrder" />'; # On order
+        schema_copy_status.12 = '<link property="availability" href="http://schema.org/InStoreOnly" />'; # Reserves
+
+        args.isbns = [];
+        FOR isbn IN xml.findnodes('//*[@tag="020"]/*[@code="a"]');
+            args.isbns.push(isbn.textContent);
+        END;
+
+        # UPCs can be identified either by ind1="1" or subfield 2 of "upc"
+        args.upcs = [];
+        FOR upc IN xml.findnodes('//*[@tag="024" and @ind="1"]/*[@code="a"]');
+            args.upcs.push(upc.textContent);
+        END;
+        FOR upcfield IN xml.findnodes('//*[@tag="024"]/*[@code="2" and text()="upc"]');
+            my_parent = upcfield.parentNode();
+            FOR upc IN my_parent.findnodes('./*[@code="a"]');
+                args.upcs.push(upc.textContent);
+            END;
+        END;
+        args.upc = args.upcs.0; # use first UPC as the default
+
+        # These are URIs that link out to related works for linked data purposes,
+        # such as OCLC Work Entities like http://worldcat.org/entity/work/id/415491
+
+        # We differentiate between http://schema.org/sameAs relations, which
+        # are roughly the same as the work we're describing here, and
+        # http://schema.org/exampleOfWork which point to a broader work, of which
+        # this is a more specific edition or manifestation.
+        args.links.sameAs = [];
+        args.links.exampleOfWork = [];
+        FOR link_node IN xml.findnodes('//*[@tag="024"]/*[@code="2" and text()="uri"]');
+            my_parent = link_node.parentNode();
+            FOR link IN my_parent.findnodes('./*[@code="a"]');
+                link_uri = link.textContent | trim;
+                IF link_uri.search('worldcat.org/entity/work');
+                    args.links.exampleOfWork.push(link_uri);
+                ELSE;
+                    args.links.sameAs.push(link_uri);
+                END;
+            END;
+        END;
+        FOR lccn IN xml.findnodes('//*[@tag="010"]/*[@code="a"]');
+            lccn_num = lccn.textContent | trim;
+            args.links.sameAs.push('http://lccn.loc.gov/' _ lccn_num);
+        END;
+        FOR oclcnum IN xml.findnodes('//*[@tag="035"]/*[@code="a"]');
+            oclcnum = oclcnum.textContent | trim;
+            NEXT UNLESS oclcnum.search('^\(OCoLC\)');
+            oclcnum = oclcnum | remove('\(OCoLC\)');
+            # These prefixes are often included in the 035, even though they should not be
+            oclcnum = oclcnum | remove('ocm');
+            oclcnum = oclcnum | remove('ocn');
+            oclcnum = oclcnum | remove('on') | trim;
+            args.links.sameAs.push('http://www.worldcat.org/oclc/' _ oclcnum);
+        END;
+        args.links.sameAs = args.links.sameAs.unique;
+
+        args.issns = [];
+        FOR sub IN xml.findnodes('//*[@tag="022"]/*[@code="a"]');
+            args.issns.push(sub.textContent);
+        END;
+        args.issn = (args.issns.size) ? args.issn.0 : '';
+
+        graphic_880s = [];
+        get_graphic_880s(target_field='100');
+        get_graphic_880s(target_field='110');
+        get_graphic_880s(target_field='111');
+        args.graphic_authors = graphic_880s;
+        args.authors = [];
+        FOR author IN args.graphic_authors;
+            args.authors.push(author.primary.value);
+        END;
+        args.author = (args.authors.size) ? args.authors.0 : '';
+
+        # Include subfields 'abnp' to generate a more comprehensive title display in search results
+        titresults = xml.findnodes('//*[@tag="245"]/*[@code="a" or @code="b" or @code="n" or @code="p"]');
+        titresults_content = [];
+            FOR sub IN titresults; titresults_content.push(sub.textContent); END;
+        args.title = titresults_content.join(" ");
+        # Avoid ugly trailing syntax on brief titles
+        args.title = args.title | replace('[:;/]$', '');
+
+        graphic_880s = [];
+        get_graphic_880s(target_field='245');
+        args.graphic_titles = graphic_880s;
+        args.titles = [];
+        FOR title IN args.graphic_titles;
+            args.titles.push(title.primary.value);
+        END;
+        args.title_extended = (args.titles.size) ? args.titles.0 : '';
+
+        args.pubplaces = [];
+        pubplace_hunt = xml.findnodes('//*[@tag="260"]/*[@code="a"]') ||
+            xml.findnodes('//*[@tag="264" and @ind2="1"]/*[@code="a"]');
+        FOR sub IN pubplace_hunt;
+            args.pubplaces.push(sub.textContent);
+        END;
+        args.pubplace = (args.pubplaces.size) ? args.pubplaces.0 : '';
+
+        args.publishers = [];
+        publishers_hunt = xml.findnodes('//*[@tag="260"]/*[@code="b"]') ||
+            xml.findnodes('//*[@tag="264" and @ind2="1"]/*[@code="b"]');
+        FOR sub IN publishers_hunt;
+            args.publishers.push(sub.textContent);
+        END;
+        args.publisher = (args.publishers.size) ? args.publishers.0 : '';
+
+        args.pubdates = [];
+        pubdates_hunt = xml.findnodes('//*[@tag="260"]/*[@code="c"]') || 
+            xml.findnodes('//*[@tag="264" and @ind2="1"]/*[@code="c"]');
+        FOR sub IN pubdates_hunt;
+            args.pubdates.push(sub.textContent);
+        END;
+        args.pubdate = (args.pubdates.size) ? args.pubdates.0 : '';
+
+        # Get RDA Copyright Info.
+        args.copyrights = [];
+        FOR sub IN xml.findnodes('//*[@tag="264" and @ind2="4"]/*[@code="c"]');
+            args.copyrights.push(sub.textContent);
+        END;
+        args.copyright = (args.copyrights.size) ? args.copyrights.0 : '';
+
+        IF args.copyright.length >= 4;
+            args.copyrightYear = args.copyright.match('(\d{4})');
+            IF args.copyrightYear;
+                args.copyrightYear = args.copyrightYear.0;
+            END;
+        END;
+
+        # Get the RDA Production info.
+        args.producers = [];
+        FOR sub IN xml.findnodes('//*[@tag="264" and @ind2="0"]/*[@code="b"]');
+            args.producers.push(sub.textContent);
+        END;
+        args.producer = (args.producers.size) ? args.producers.0 : '';
+
+        args.prodplaces = [];
+        FOR sub IN xml.findnodes('//*[@tag="264" and @ind2="0"]/*[@code="a"]');
+            args.prodplaces.push(sub.textContent);
+        END;
+        args.prodplace = (args.prodplaces.size) ? args.prodplaces.0 : '';
+
+        args.proddates = [];
+        FOR sub IN xml.findnodes('//*[@tag="264" and @ind2="0"]/*[@code="c"]');
+            args.proddates.push(sub.textContent);
+        END;
+        args.proddate = (args.proddates.size) ? args.proddates.0 : '';
+
+        # Get the RDA Distribution args.
+        args.distributors = [];
+        FOR sub IN xml.findnodes('//*[@tag="264" and @ind2="2"]/*[@code="b"]');
+            args.distributors.push(sub.textContent);
+        END;
+        args.distributor = (args.distributors.size) ? args.distributors.0 : '';
+
+        args.distplaces = [];
+        FOR sub IN xml.findnodes('//*[@tag="264" and @ind2="2"]/*[@code="a"]');
+            args.distplaces.push(sub.textContent);
+        END;
+        args.distplace = (args.distplaces.size) ? args.distplaces.0 : '';
+
+        args.distdates = [];
+        FOR sub IN xml.findnodes('//*[@tag="264" and @ind2="2"]/*[@code="c"]');
+            args.distdates.push(sub.textContent);
+        END;
+        args.distdate = (args.distdates.size) ? args.distdates.0 : '';
+
+        # Get the RDA Manufacture args.
+        args.manufacturers = [];
+        FOR sub IN xml.findnodes('//*[@tag="264" and @ind2="3"]/*[@code="b"]');
+            args.manufacturers.push(sub.textContent);
+        END;
+        args.manufacturer = (args.manufacturers.size) ? args.manufacturers.0 : '';
+
+        args.manplaces = [];
+        FOR sub IN xml.findnodes('//*[@tag="264" and @ind2="3"]/*[@code="a"]');
+            args.manplaces.push(sub.textContent);
+        END;
+        args.manplace = (args.manplaces.size) ? args.manplaces.0 : '';
+
+        args.mandates = [];
+        FOR sub IN xml.findnodes('//*[@tag="264" and @ind2="3"]/*[@code="c"]');
+            args.mandates.push(sub.textContent);
+        END;
+        args.mandate = (args.mandates.size) ? args.mandates.0 : '';
+
+        # RDA adds 264 to the pubinfo 880 consideration mix
+        graphic_880s = [];
+        get_graphic_880s(target_field='260');
+        get_graphic_880s(target_field='264');
+        args.graphic_pubinfos = graphic_880s;
+        args.pubinfos = [];
+        FOR pubinfo IN args.graphic_pubinfos;
+            args.pubinfos.push(pubinfo.primary.value);
+        END;
+        args.pubinfo = (args.pubinfos.size) ? args.pubinfos.0 : '';
+
+        args.summaries = [];
+        FOR sub IN xml.findnodes('//*[@tag="520"]/*[@code="a"]');
+            args.summaries.push(sub.textContent);
+        END;
+        args.summary = (args.summaries.size) ? args.summaries.0 : '';
+
+        args.targetauds = [];
+        FOR sub IN xml.findnodes('//*[@tag="521"]/*[@code="a"]');
+            args.targetauds.push(sub.textContent);
+        END;
+        args.targetaud = (args.targetauds.size) ? args.targetauds.0 : '';
+
+        # 250 gets pride of place for edition statement, and is the
+        # only logical choice for 880 graphic fields
+        graphic_880s = [];
+        get_graphic_880s(target_field='250');
+        args.graphic_editions = graphic_880s;
+        args.editions = [];
+        FOR edition IN args.graphic_editions;
+            args.editions.push(edition.primary.value);
+        END;
+
+        ed_hunt = xml.findnodes('//*[@tag="250"]/*[@code="a"]') ||
+            xml.findnodes('//*[@tag="534"]/*[@code="b"]') ||
+            xml.findnodes('//*[@tag="775"]/*[@code="b"]');
+        FOR sub IN ed_hunt;
+            args.editions.push(sub.textContent);
+        END;
+        args.edition = (args.editions.size) ? args.editions.0 : '';
+
+        phys_content = [];
+        FOR sub IN xml.findnodes(
+            '//*[@tag="300"]/*[@code="a" or @code="b" or @code="c" or @code="e"]'
+        );
+            phys_content.push(sub.textContent);
+        END;
+        args.phys_desc = phys_content.join(" ");
+
+        graphic_880s = [];
+        get_graphic_880s(target_field='505');
+        args.graphic_contents = graphic_880s;
+        FOR content IN args.graphic_contents;
+            args.contents.push(content.primary.value);
+        END;
+        args.content = (args.contents.size) ? args.contents.0 : '';
+
+        # Maintain contents_list in case any custom use was made of it
+        args.contents_list = [];
+        FOR sub IN xml.findnodes('//*[@tag="505"]');
+            args.contents_list.push(sub.textContent);
+        END;
+
+        # MARC Callnumber
+        args.marc_cns = [];
+        FOR sub IN xml.findnodes('//*[@tag="092" or @tag="099"]/*');
+            args.marc_cns.push(sub.textContent);
+        END;
+        args.marc_cn = (args.marc_cns.size ) ? args.marc_cns.0 : '';
+            
+
+        # clean up the ISBN
+        args.isbn_clean = args.isbns.0.replace('\ .*', '');
+        FOR isbn IN args.isbns;
+            clean_isbn = isbn.replace('\ .*', '');
+            clean_isbn = clean_isbn.replace('-', '');
+            IF clean_isbn.length == 13;
+                args.gtin13 = clean_isbn;
+                LAST;
+            END;
+        END;
+
+        # Extract the 856 URLs that are not otherwise represented by asset.uri's
+        args.online_res = [];
+        FOR node IN xml.findnodes('//*[@tag="856" and @ind1="4" and (@ind2="0" or @ind2="1")]');
+            IF node.findnodes('./*[@code="9" or @code="w" or @code="n"]'); NEXT; END; # asset.uri's
+            label = node.findnodes('./*[@code="y" or @code="z"][1]');
+            notes = node.findnodes('./*[@code="3"]');
+            FOR href IN node.findnodes('./*[@code="u"]');
+                NEXT UNLESS href;
+                # it's possible for multiple $u's to exist within 1 856 tag.
+                # in that case, honor the label/notes data for the first $u, but
+                # leave any subsequent $u's as unadorned href's. 
+                # use href/link/note keys to be consistent with args.uri's
+                args.online_res.push({
+                    href => href.textContent, 
+                    link => (loop.first AND label) ? label.textContent : href.textContent,
+                    note => (loop.first) ? notes.textContent : ''
+                });
+            END;
+        END;
+        args.holdings = [];
+        args.uris = [];
+        args.issns = [];
+        args.resolver_isbns = [];
+        args.resolver_issns = [];
+
+        # we use $9 of ISBN and ISSN as a flag for e-version
+        FOR resolver_isbn IN xml.findnodes('//*[@tag="020"]/*[@code="9"]');
+            IF resolver_isbn.textContent == "SFX" || resolver_isbn.textContent == "CUFTS";
+                my_parent = resolver_isbn.parentNode();
+                FOR resolver_isbn_val IN my_parent.findnodes('./*[@code="a"]');
+                    args.resolver_isbns.push(
+                        resolver_isbn_val.textContent.replace('-', '').replace('\ .*', '')
+                    );
+                END;
+            END;
+        END;
+
+        FOR resolver_issn IN xml.findnodes('//*[@tag="022"]/*[@code="9"]');
+            IF resolver_issn.textContent == "SFX" || resolver_issn.textContent == "CUFTS";
+                my_parent = resolver_issn.parentNode();
+                FOR resolver_issn_val IN my_parent.findnodes('./*[@code="a"]');
+                    args.resolver_issns.push(
+                        resolver_issn_val.textContent.replace('[^\d\-X]', '')
+                    );
+                END;
+            END;
+        END;
+
+        # now snag all issns 
+        FOR rawissn IN xml.findnodes('//*[@tag="022"]/*[@code="a"]');
+            args.issns.push(
+                rawissn.textContent.replace('[^\d\-X]', '')
+            );
+        END;
+
+        ou_hiding_disabled = ctx.org_hiding_disabled();
+
+        FOR volume IN xml.findnodes('//*[local-name()="volumes"]/*[local-name()="volume"]');
+
+            # Check volume visibility - could push this into XPath
+            vol.label = volume.getAttribute('label');
+
+            # Prepend prefix, if any
+            prefix = volume.findnodes('./*[local-name()="call_number_prefix"][@ident!="-1"]');
+            IF prefix.getAttribute('label') != '';
+                vol.label = prefix.getAttribute('label') _ " " _ vol.label;
+            END;
+
+            # Append prefix, if any
+            suffix = volume.findnodes('./*[local-name()="call_number_suffix"][@ident!="-1"]');
+            IF suffix.getAttribute('label') != '';
+                vol.label = vol.label _ " " _ suffix.getAttribute('label');
+            END;
+
+            vol.id = volume.getAttribute('id');
+            NEXT IF volume.getAttribute('opac_visible') == 'false';
+            NEXT IF volume.getAttribute('deleted') == 'true';
+
+            IF vol.label == '##URI##';
+                FOR uri IN volume.findnodes('./*[local-name()="uris"]/*[local-name()="uri"]');
+                    res = {};
+                    res.href = uri.getAttribute('href');
+                    res.link = uri.getAttribute('label');
+                    res.note = uri.getAttribute('use_restriction');
+                    # Avoid displaying the href as the link text if we can display the note instead
+                    IF res.link == res.href AND res.note;
+                        res.link = res.note;
+                        res.note = '';
+                    END;
+                    args.uris.push(res);
+                END;
+                NEXT;
+            ELSE;
+                copies = volume.findnodes('./*[local-name()="copies"]/*[local-name()="copy"]');
+                FOR copy IN copies;
+                    parts = copy.findnodes('./*[local-name()="monograph_parts"]/*[local-name()="monograph_part"]');
+                    FOREACH part IN parts;
+                        part_label = part.getAttribute('label');
+                        LAST IF part_label != '';
+                    END;
+                    # Check copy visibility
+                    cp.deleted = copy.getAttribute('deleted');    
+                    cp.visible = copy.getAttribute('opac_visible');
+                    NEXT IF (cp.deleted == 'true' OR cp.visible == 'false');
+
+                    # Iterate through all of the children to determine visibility
+                    FOR node IN cp.childNodes;
+                        NEXT IF cp.visible == 'false';
+                        vis = node.getAttribute('opac_visible');
+                        del = node.getAttribute('deleted');
+                        IF vis == 'false' or del == 'true';
+                            cp.visible = 'false';
+                        END;
+                    END;
+
+                    NEXT IF cp.visible == 'false';
+                    
+                    loc = copy.findnodes('./*[local-name()="location"]');
+                    NEXT IF loc.getAttribute('opac_visible') == 'false';
+
+                    circlib = copy.findnodes('./*[local-name()="circlib"]');
+                    NEXT IF circlib.getAttribute('opac_visible') == 'false';
+
+                    status = copy.findnodes('./*[local-name()="status"]');
+                    NEXT IF status.getAttribute('opac_visible') == 'false';
+
+                    # extract the circ_lib id from the circ_lib node
+                    circ_lib = copy.findnodes('./*[local-name()="circ_lib"]');
+                    circ_lib_id = circ_lib.getAttribute('id').replace('.*/', '');
+
+                    UNLESS ou_hiding_disabled;
+                        NEXT UNLESS ctx.org_within_hiding_scope(circ_lib_id);
+                    END;
+
+                    holding = {
+                        circ_lib => circ_lib_id,
+                        label => vol.label,
+                        part_label => part_label,
+                        location => loc.textContent,
+                        library => circlib.textContent,
+                        status => status.textContent,
+                        status_code => status.getAttribute('ident'),
+                        barcode => copy.getAttribute('barcode'),
+                        owner => volume.getAttribute('lib')
+                    };
+                    args.holdings.push(holding);
+                    part_label = '';
+                END;
+            END;
+        END;
+
+        # Extract the copy count summary
+        count_type = (ctx.is_staff) ? 'staff' : 'public';
+
+        # Consortial copy count summary first
+        xpath = '//*[local-name()="counts"]/*[local-name()="count"][@type="' _ count_type _ '"]';
+        args.copy_counts = {};
+        FOR node IN xml.findnodes(xpath);
+            FOR attr IN ['count', 'available', 'unshadow', 'transcendant', 'org_unit']; 
+                depth = node.getAttribute('depth');
+                count_org_unit = node.getAttribute('org_unit');
+                args.copy_counts.$depth.$attr = node.getAttribute(attr);
+                args.org_copy_counts.$count_org_unit.$attr = node.getAttribute(attr);
+            END;
+        END;
+
+        # Get preferred library copy count
+        args.plib_copy_counts = {};
+        count_type = 'pref_lib';
+        xpath = '//*[local-name()="counts"]/*[local-name()="count"][@type="' _ count_type _ '"]';
+        FOR node IN xml.findnodes(xpath);
+            FOR attr IN ['count', 'available', 'unshadow', 'transcendant', 'org_unit']; 
+                depth = node.getAttribute('depth');
+                args.plib_copy_counts.$depth.$attr = node.getAttribute(attr);
+            END;
+        END;
+
+        # "mattype" == "custom marc format specifier"
+        icon_style = ctx.get_cgf('opac.icon_attr').value || 'item_type';
+        formats_xpath = '//*[local-name()="attributes"]/*[local-name()="field"][@name="' _ icon_style _ '"]';
+
+        args.all_formats = [];
+        FOR node IN xml.findnodes(formats_xpath);
+            IF node AND node.textContent;
+                ccvm = ctx.get_ccvm(node.getAttribute('cvmid'));
+                NEXT IF ccvm.opac_visible == 'f';
+
+                format = {};
+                type = ccvm.code.remove('-'); # blu-ray to bluray
+                format.label = ccvm.search_label || ccvm.value;
+                format.icon = PROCESS get_ccvm_icon ccvm=ccvm;
+                format.itemtype = schema_typemap.$type || 'CreativeWork';
+
+                args.all_formats.push(format); # metarecords want all formats
+
+                IF !args.format_label;
+                    # use the first format as the default
+                    args.format_label = format.label; 
+                    args.schema.itemtype = format.itemtype;
+                    args.format_icon = format.icon;
+                END;
+            END;
+        END;
+       
+        args.bibid = [];
+        FOR bibid IN xml.findnodes('//*[@tag="901"]/*[@code="c"]');
+            args.bibid.push(bibid.textContent);
+        END;
+        args.bibid = args.bibid.0; 
+
+    END;
+
+    # Get the library or location group
+    # get_library()
+    # magically upgrades any use of 'loc' to 'locg', 
+    # which is a superset of 'loc'.
+    BLOCK get_library;
+        loc_name = 'locg';
+        loc_value = ctx.copy_location_group_org ||  # resolved locg
+            CGI.param(loc_name) || CGI.param('loc') || ctx.search_ou;
+    END;
+
+%]
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/myopac/main_refund_policy.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/myopac/main_refund_policy.tt2
new file mode 100644 (file)
index 0000000..bf3389c
--- /dev/null
@@ -0,0 +1,16 @@
+<tr>
+    <td colspan="3">
+        <br />
+        [% l('Important! Check with your library on their refund policy prior to payment. Not all libraries issue refunds. If a refund is available you must have a printed receipt to be eligible for a refund.')
+        %]
+        <br />
+        <strong>
+        [% l('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>
+    </td>
+</tr>
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/password_hint.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/password_hint.tt2
new file mode 100644 (file)
index 0000000..6d8e2be
--- /dev/null
@@ -0,0 +1,5 @@
+<span class="lbl2">\r
+    [% | l('<br/>', '<br/>') %]\r
+      <b> Note:</b> Your username and password are both case-sensitive.\r
+    [% END %]\r
+</span>\r
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/place_hold.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/place_hold.tt2
new file mode 100644 (file)
index 0000000..497688b
--- /dev/null
@@ -0,0 +1,191 @@
+[%  PROCESS "opac/parts/misc_util.tt2";
+    PROCESS "opac/parts/hold_error_messages.tt2";
+    PROCESS "opac/parts/metarecord_hold_filters.tt2";
+%]
+
+<div id='holds_box' class='canvas' style='margin-top: 6px;'>
+    <h1>[% l('Place Hold') %]</h1>
+
+    [% some_holds_allowed = -1 %]
+      
+    <form method="post">
+        <input type="hidden" name="hold_type" value="[% CGI.param('hold_type') | html %]" />
+        [%  
+            redirect = CGI.param('hold_source_page') || CGI.param('redirect_to') || CGI.referer;
+            # since we have to be logged in to get this far, return to a secure page
+            redirect = redirect.replace('^http:', 'https:') 
+        %]
+        <input type="hidden" name="redirect_to" value="[% redirect | html %]" />
+        <input type="hidden" name="hold_source_page" value="[% CGI.param('hold_source_page') | html %]" />
+
+        [% IF ctx.is_staff %]
+        <p class="staff-hold">
+            <input type="radio" id="hold_usr_is_requestor_not"
+                onchange="staff_hold_usr_input_disabler(this);"
+                name="hold_usr_is_requestor" value="0"
+                />
+            <label for="hold_usr_is_requestor_not">
+                [% l("Place hold for patron by barcode:") %]
+            </label>
+            <input type="text" name="hold_usr" id="hold_usr_input" 
+              value="[% CGI.param('usr_barcode') | html %]"
+              onchange="staff_hold_usr_barcode_changed();" 
+              onpaste="setTimeout(staff_hold_usr_barcode_changed,1);" 
+              onkeypress="return no_hold_submit(event)" autofocus /> 
+            <span id="patron_name"></span>
+            <span id="patron_usr_barcode_not_found" style="display: none">
+              [% l('Patron barcode was not found') %]
+            </span><br />
+            <input type="hidden" id="staff_barcode" 
+              value="[% ctx.staff_recipient.card.barcode | html %]"/>
+            <span>
+                <input type="radio" id="hold_usr_is_requestor"
+                    onchange="staff_hold_usr_input_disabler(this);"
+                    name="hold_usr_is_requestor" value="1" />
+                <label for="hold_usr_is_requestor">
+                    [% l("Place this hold for me ([_1] [_2])", ctx.user.first_given_name, ctx.user.family_name) | html %]
+                </label>
+            </span>
+        </p>
+        [% END %]
+
+        <!-- loop through the holds and display status of request where appropriate -->
+        <table id='hold-items-list'>
+        [% FOR hdata IN ctx.hold_data;
+            attrs = {marc_xml => hdata.marc_xml};
+            PROCESS get_marc_attrs args=attrs;
+            this_hold_disallowed = 0;
+
+            IF CGI.param('hold_type') == 'M';
+              IF hdata.metarecord_filters.formats.size == 0;
+                this_hold_disallowed = 1;
+                # if this is the first hold and it's disallowed, 
+                # assume all holds are, until we proven otherwise
+                SET some_holds_allowed = 0 IF some_holds_allowed == -1;
+              ELSE; some_holds_allowed = 1; END;
+            END %]
+
+            <tr>
+                <td>
+                    [% IF !this_hold_disallowed %]
+                    <input type="hidden" name="hold_target" value="[% hdata.target.id | html %]" />
+                    [% END %]
+                    <div class='hold-items-list-title'>[% attrs.title_extended | html %]</div>
+                    [% IF hdata.parts AND !this_hold_disallowed %]
+                        [% IF hdata.parts.size > 0 %]
+                        <div style='padding-left: 10px; font-weight: bold;'><!-- Added more weight to font - NOBLE -->
+                            <span><label for='select_hold_part'>[%
+                                hdata.part_required ? l('Select a Part:') : l('Get a Complete Set (default) or Select a Part:') #changed wording - NOBLE
+                            %]</label></span>
+                            <select id='select_hold_part' name='part'>
+                                [% IF !hdata.part_required %]
+                                <option selected='selected' value=''>[% l('- Complete Set -') %]</option><!-- Changed wording from "All Parts" - NOBLE -->
+                                [% END %]
+                                [% FOR part IN hdata.parts %]
+                                <option value='[% part.id %]'>[% part.label | html %]</option>
+                                [% END %]
+                            </select>
+                        </div>
+                        [% ELSE %]
+                        <input type='hidden' name='part' value=''/>
+                        [% END %]
+                    [% END %]
+                    [% IF NOT metarecords.disabled %]
+                        [% IF CGI.param('hold_type') == 'T' AND hdata.record.metarecord %]
+                        <!-- Grab the bre_id so that we can restore it if user accidentally clicks advanced options -->
+                           [% bre_id = hdata.target.id %]
+                            <a  id='advanced_hold_link'
+                                href="[% mkurl('', {hold_type => 'M', hold_target => hdata.record.metarecord.id, bre_id => bre_id}) %]">
+                                [% l('Advanced Hold Options') %]</a>
+                        [% END %]
+                        [% IF CGI.param('hold_type') == 'M' AND CGI.param('bre_id') %]
+                            <input type="hidden" name="bre_id" value="[% CGI.param('bre_id') %]" />
+                            <a id='basic_hold_link'
+                               href="[% mkurl('', {hold_target => CGI.param('bre_id'), hold_type => 'T'}) %]">
+                                [% l('Basic Hold Options') %]</a>
+                        [% END %]
+                        [% IF hdata.metarecord_filters.formats.size OR # should this be size > 1
+                            (hdata.metarecord_filters.langs.size && hdata.metarecord_filters.langs.size > 1);
+                            PROCESS metarecord_hold_filters_selector hold_data=hdata;
+                        END;
+                    END %]
+                </td>
+            </tr>
+
+            [% IF this_hold_disallowed %]
+              <tr><td>
+                <div class="mr_holds_no_formats">
+                [% l('This item does not have any formats available for holds placement') %]
+                </div>
+              </td></tr>
+            [% END %]
+
+            [%  IF !loop.last AND ctx.hold_data.size > 1 %]
+            <tr class="holds_item_row_separator"><td> </td></tr>
+            [% END %]
+
+        [% END %]
+        </table>
+
+        [% IF some_holds_allowed %]
+
+        <p>
+            [%- org_select_id = 'pickup_lib'; -%]
+            <label for="[% org_select_id %]">[%l('Pickup location:') %]</label>
+            [% PROCESS "opac/parts/org_selector.tt2";
+                INCLUDE build_org_selector name='pickup_lib' 
+                    value=ctx.default_pickup_lib id=org_select_id 
+                    can_have_vols_only=1 hold_pickup_lib=1 %]
+        </p>
+        <p>
+            [% l('Notify when hold is ready for pickup?') %]
+            <blockquote>
+                <input type="checkbox" id="email_notify" name="email_notify" value="t"
+                    [% IF !ctx.user.email %]disabled="true"[% ELSIF ctx.default_email_notify %]checked="checked"[% END %]/>
+                    <label for="email_notify">[% l('Yes, by Email') %]</label><br/>
+                <blockquote>
+                    [% IF !ctx.user.email and !ctx.is_staff; l('No configured Email address. See "My Account" for setting your Email address.');
+                     ELSE; l('Email Address:') %] <span name="email_address">[% ctx.user.email %]</span>[% END %]
+                </blockquote>
+                [%- IF allow_phone_notifications == 'true' and !ctx.is_staff %]
+                <div class="suppress"><input type="checkbox" id="phone_notify_checkbox" name="phone_notify_checkbox"
+                    [% IF ctx.default_phone_notify %]checked="checked"[% END %]/>
+                    <label for="phone_notify_checkbox">[% l('Yes, by Phone') %]</label><br/>
+                <blockquote>
+                    <label>[% l('Phone Number:') %]<input type="text" name="phone_notify" [% setting = 'opac.default_phone';
+                    IF ctx.user_setting_map.$setting; %] value='[% ctx.user_setting_map.$setting | html %]'
+                    [%- ELSIF ctx.user.day_phone; %] value='[% ctx.user.day_phone | html %]' [% END %]/></label>
+                </blockquote></div><!-- End Suppress. NOBLE -->
+<!-- JFK code begin - remove suppress for staff client -->
+                [%- ELSIF allow_phone_notifications == 'true' and ctx.is_staff %]
+                <div><input type="checkbox" id="phone_notify_checkbox" name="phone_notify_checkbox"
+                    [% IF ctx.default_phone_notify %]checked="checked"[% END %]/>
+                    <label for="phone_notify_checkbox">[% l('Yes, by Phone') %]</label><br/>
+                <blockquote>
+                    <label>[% l('Phone Number:') %]<input type="text" name="phone_notify" [% setting = 'opac.default_phone';
+                    IF ctx.user_setting_map.$setting; %] value='[% ctx.user_setting_map.$setting | html %]'
+                    [%- ELSIF ctx.user.day_phone; %] value='[% ctx.user.day_phone | html %]' [% END %]/></label>]
+                </blockquote></div>
+<!-- JFK code end -->
+                [% END %]
+                [% IF ctx.get_org_setting(ctx.search_ou, 'sms.enable') == 1 %]
+                <input type="checkbox" id="sms_notify_checkbox" name="sms_notify_checkbox"
+                    [% IF ctx.default_sms_notify %]checked="checked"[% END %]/>
+                    <label for="sms_notify_checkbox">[% l('Yes, by Text Messaging') %]</label><br/>
+                <blockquote>
+<!-- Added bottom padding to separate boxes - NOBLE -->
+                    <div style="padding-bottom:5px;">[% INCLUDE "opac/parts/sms_carrier_selector.tt2" %]</div>
+                    [% INCLUDE "opac/parts/sms_number_textbox.tt2" %]<br/>
+                </blockquote>
+                [% END %]
+            </blockquote>
+        </p>
+<!-- Added style to push buttons over - NOBLE -->
+        <input id="place_hold_submit" type="submit" name="submit" 
+            value="[% l('Submit') %]" title="[% l('Submit') %]"
+            alt="[% l('Submit') %]" class="opac-button" />
+        [% END # some_holds_allowed %]
+        <input type="reset" name="cancel" onclick="window.location='[% redirect | html %]'" value="[% l('Cancel') %]" id="holds_cancel" class="opac-button" />
+    </form>
+</div>
+
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/qtype_selector.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/qtype_selector.tt2
new file mode 100644 (file)
index 0000000..4ed9e63
--- /dev/null
@@ -0,0 +1,22 @@
+[%  query_types = [
+    {value => "keyword", label => l("Keyword")},
+    {value => "title", label => l("Title"), plural_label => l("Titles"), browse => 1},
+    {value => "jtitle", label => l("Journal Title")},
+    {value => "author", label => l("Author"), plural_label => l("Authors"), browse => 1},
+    {value => "subject", label => l("Subject"), plural_label => l("Subjects"), browse => 1},
+    {value => "series", label => l("Series"), plural_label => l("Series"), browse => 1}
+] %]
+<select name="[% name || 'qtype' %]"[% IF id; ' id="'; id ; '"' ; END -%]
+    title="[% l('Select query type:') %]">
+    [%  query_type = query_type || CGI.param('qtype') || search.default_qtypes.0;
+      FOR qt IN query_types;
+        NEXT IF browse_only AND NOT qt.browse -%]
+    <option value='[% qt.value | html %]'[%
+        query_type == qt.value ? ' selected="selected"' : ''
+    %]>[% IF plural AND qt.plural_label;
+        qt.plural_label | html;
+    ELSE;
+        qt.label | html;
+    END %]</option>
+    [% END -%]
+</select>
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/record/addedcontent.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/record/addedcontent.tt2
new file mode 100644 (file)
index 0000000..b0235a9
--- /dev/null
@@ -0,0 +1,57 @@
+<div class='rdetail_extras_div'> 
+
+[% 
+    ac_types = {
+        reviews => l('Reviews'),
+        anotes  => l('Author Notes'),
+        toc     => l('Table of Contents'),
+        excerpt => l('Excerpt'),
+        summary => l('Summary')
+    };
+
+    selected_type = CGI.param('ac');
+    
+    # For each type of added content, render the link if it's known to have
+    # content, do not render the link if it's known to not have content.  If 
+    # the content status is unknown, render the link, but hide the link via CSS
+    # if dojo is enabled.  If dojo is not enabled, render and display the link.
+%]
+
+    <div id='ac_tab_wrapper'>
+        <a name="addedcontent"></a><!-- Anchor is here! -->
+    [% 
+        all_hidden = 1;
+        FOR type IN ac_types.keys;
+            tab_class = 'ac_tab';
+            SET tab_class = tab_class _ ' ac_tab_selected' IF type == selected_type; 
+            IF ctx.added_content.$type.status != '2'; # no content
+                all_hidden = 0;
+                IF ctx.added_content.$type.status == '3' AND want_dojo; # status unknown
+                    tab_class = tab_class _ ' hidden';
+                END %]
+            <div class="[% tab_class %]" id="ac:[% type %]">
+                <a href="[% mkurl('', {ac => type}) _ '#addedcontent' %]">[% ac_types.$type %]</a>
+            </div>
+            [% END;
+        END;
+    %]
+    </div>
+
+    <div id='ac_content'>
+        <!-- <hr/> --><!-- Comment out line -->
+        [% 
+            IF selected_type; 
+                content = ctx.added_content.$selected_type.content;
+                IF content;
+                    content;
+                ELSE;
+                    l(''); #Removed "No Content Available" text
+                END;
+            ELSIF all_hidden;
+                l(''); #Removed "No Content Available" text
+            END;
+        %]
+    </div>
+</div>
+
+
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/record/awards.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/record/awards.tt2
new file mode 100644 (file)
index 0000000..36a0b62
--- /dev/null
@@ -0,0 +1,18 @@
+<div class='rdetail_extras_div'> 
+    <div style="margin-bottom:20px;"></div>
+
+    <!-- Chilifresh patron reviews -->
+<!--    <strong>[% l('Patron Reviews:') %]</strong>
+    <div style="margin-bottom:20px;">
+        <span class="chili_review" id="isbn_[% attrs.isbn_clean | html %]"> </span>
+        <div id="chili_review_[% attrs.isbn_clean | html %]" style="display: none;" align="center" width="100%"></div>
+    </div> -->
+
+    <!-- Novelist suggestions-->
+    [% IF ENV.OILS_NOVELIST_URL %] 
+        <div id='novelist-loading'>[% l('No NoveList content is available for this item.') %]</div>
+        <div data-novelist-novelistselect="[% attrs.isbn_clean || attrs.upc %]"></div>
+    [% END %]
+
+</div>
+
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/record/contents.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/record/contents.tt2
new file mode 100644 (file)
index 0000000..477f838
--- /dev/null
@@ -0,0 +1,206 @@
+[%-
+contents =  [
+    {
+        label => l('General Note: '),
+        xpath => '//*[@tag="500"]'
+    }, {
+        label => l('Issued our Bound With: '),
+        xpath => '//*[@tag="501"]'
+    }, {
+        label => l('Dissertation: '),
+        xpath => '//*[@tag="502"]'
+    }, {
+        label => l('Bibliography, etc.: '),
+        xpath => '//*[@tag="504"]'
+    }, {
+        label => l('Formatted Contents: '),
+        xpath => '//*[@tag="505"]'
+    }, {
+        label => l('Restrictions on Access: '),
+        xpath => '//*[@tag="506"]'
+    }, {
+        label => l('Scale: '),
+        xpath => '//*[@tag="507"]'
+    }, {
+        label => l('Creation/Production Credits: '),
+        xpath => '//*[@tag="508"]'
+    }, {
+        label => l('Citation/References: '),
+        xpath => '//*[@tag="510"]'
+    }, {
+        label => l('Participant or Performer: '),
+        xpath => '//*[@tag="511"]'
+    }, {
+        label => l('Type of Report and Period Covered: '),
+        xpath => '//*[@tag="513"]'
+    }, {
+        label => l('Data Quality: '),
+        xpath => '//*[@tag="514"]'
+    }, {
+        label => l('Numbering Peculiarities: '),
+        xpath => '//*[@tag="515"]'
+    }, {
+        label => l('Type of Computer File or Data: '),
+        xpath => '//*[@tag="516"]'
+    }, {
+        label => l('Date/Time and Place of an Event: '),
+        xpath => '//*[@tag="518"]'
+    }, {
+        label => l('Summary or Annotation: '),
+        xpath => '//*[@tag="520"]'
+    }, {
+        label => l('Rating/Audience Level: '),
+        xpath => '//*[@tag="521"]'
+    }, {
+        label => l('Geographic Coverage: '),
+        xpath => '//*[@tag="522"]'
+    }, {
+        label => l('Preferred Citation: '),
+        xpath => '//*[@tag="524"]'
+    }, {
+        label => l('Supplement: '),
+        xpath => '//*[@tag="525"]'
+    }, {
+        label => l('Study Program Information: '),
+        xpath => '//*[@tag="526"]'
+    }, {
+        label => l('Additional Formats: '),
+        xpath => '//*[@tag="530"]'
+    }, {
+        label => l('Reproduction: '),
+        xpath => '//*[@tag="533"]'
+    }, {
+        label => l('Original Version: '),
+        xpath => '//*[@tag="534"]'
+    }, {
+        label => l('Location of Originals/Duplicates: '),
+        xpath => '//*[@tag="535"]'
+    }, {
+        label => l('Funding Information: '),
+        xpath => '//*[@tag="536"]'
+    }, {
+        label => l('System Details or Requirement: '),
+        xpath => '//*[@tag="538"]'
+    }, {
+        label => l('Terms Governing Use and Reproduction: '),
+        xpath => '//*[@tag="540"]'
+    }, {
+        label => l('Immediate Source of Acquisition: '),
+        xpath => '//*[@tag="541"]'
+    }, {
+        label => l('Copyright Status: '),
+        xpath => '//*[@tag="542"]'
+    }, {
+        label => l('Location of Other Archival Materials: '),
+        xpath => '//*[@tag="544"]'
+    }, {
+        label => l('Biographical or Historical Data: '),
+        xpath => '//*[@tag="545"]'
+    }, {
+        label => l('Language: '),
+        xpath => '//*[@tag="546"]'
+    }, {
+        label => l('Former Title Complexity: '),
+        xpath => '//*[@tag="547"]'
+    }, {
+        label => l('Issuing Body: '),
+        xpath => '//*[@tag="550"]'
+    }, {
+        label => l('Entity and Attribute Information: '),
+        xpath => '//*[@tag="552"]'
+    }, {
+        label => l('Cumulative Index/Finding Aids: '),
+        xpath => '//*[@tag="555"]'
+    }, {
+        label => l('Information About Documentation: '),
+        xpath => '//*[@tag="556"]'
+    }, {
+        label => l('Ownership and Custodial History: '),
+        xpath => '//*[@tag="561"]'
+    }, {
+        label => l('Copy and Version Identification: '),
+        xpath => '//*[@tag="562"]'
+    }, {
+        label => l('Binding Information: '),
+        xpath => '//*[@tag="563"]'
+    }, {
+        label => l('Case File Characteristics: '),
+        xpath => '//*[@tag="565"]'
+    }, {
+        label => l('Methodology: '),
+        xpath => '//*[@tag="567"]'
+    }, {
+        label => l('Additional Versions: '),
+        xpath => '//*[@tag="580"]'
+    }, {
+        label => l('Publications About Described Materials: '),
+        xpath => '//*[@tag="581"]'
+    }, {
+        label => l('Action: '),
+        xpath => '//*[@tag="583"]'
+    }, {
+        label => l('Accumulation and Frequency of Use: '),
+        xpath => '//*[@tag="584"]'
+    }, {
+        label => l('Exhibitions: '),
+        xpath => '//*[@tag="585"]'
+    }, {
+        label => l('Awards: '),
+        xpath => '//*[@tag="586"]'
+    }, {
+        label => l('Source of Description: '),
+        xpath => '//*[@tag="588"]'
+    } 
+];
+
+BLOCK render_contents;
+    xpath = xpath || '//*[starts-with(@tag,"5")]';
+    FOR node IN ctx.marc_xml.findnodes(xpath);
+        all_content = [];
+        graphics = [];
+        FOR subfield IN node.childNodes;
+            NEXT UNLESS subfield.nodeName == "subfield";
+            code = subfield.getAttribute('code');
+            IF code == '6';
+               linked_fields = [subfield.textContent()];
+               target_field = node.getAttribute('tag');
+               get_linked_880s;
+            END;
+            NEXT UNLESS code.match('[a-z]');
+            all_content.push(subfield.textContent);
+        END;
+        total_contents = all_content.join(" ").replace('\s+$', '');
+        %] [% total_contents | html;
+        IF total_contents.size; "<br/>"; END;
+        FOREACH link880 IN graphics;
+            '<div class="graphic880"' _ link880.dir _ '>';
+            link880.value | html;
+            '</div>';
+        END;
+    END;
+END 
+%]
+[%  BLOCK render_all_contents;
+    FOREACH cont IN contents;
+        content = PROCESS render_contents(xpath=cont.xpath);
+        IF content.match('\S');
+-%]
+<tr>
+    <td class='rdetail_content_type'>[% cont.label %]</td>
+    <td class='rdetail_content_value' property='keywords'>[% content %]</td>
+</tr>
+        [%- END; %]
+    [%- END; %]
+[%- END %]
+
+[%-  content_html = PROCESS render_all_contents;
+    IF content_html.length > 0;
+%]
+<!-- <h2 class='rdetail_contents'>[% l('Content descriptions') %]</h2> -->
+<h2 class='rdetail_contents'>[% l('Notes') %]</h2>
+<table class='rdetail_content'>
+    <tbody>
+[%- content_html %]
+    </tbody>
+</table>
+[%- END %]
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/record/copy_table.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/record/copy_table.tt2
new file mode 100644 (file)
index 0000000..7874521
--- /dev/null
@@ -0,0 +1,294 @@
+[%-
+
+# If being used in serial mode, flatten list of units so that they can be
+# used like one long list of copies without changing so much code below.
+IF serial_holdings;
+    copies = [];
+    FOREACH h IN serial_holdings;
+        units = h.units.slice(0); # copy
+        FOREACH unit IN units;
+            unit.holding_label = h.label;
+        END;
+        copies = copies.merge(units);
+    END;
+END;
+
+FOREACH copy_info IN copies;
+    IF copy_info.call_number_label != '##URI##';
+        has_copies = 'true';
+    END;
+    IF copy_info.part_label != '';
+        has_parts = 'true';
+    END;
+    IF has_parts && has_copies;
+        LAST;
+    END;
+END;
+-%]
+[%- IF has_copies; %]
+<table class="table_no_border_space table_no_cell_pad table_no_border" width="100%" id="rdetails_status">
+    <thead>
+        <tr>
+            [% IF serial_holdings -%]
+            <th scope='col'>[% l("Issue Label") %]</th>
+            [%- ELSE -%]
+            <th scope='col'>[% l("Location") %]</th>
+            [%- END %]
+            <th scope='col'>[% l("Call Number / Copy Notes") %]</th>
+            [%- IF has_parts == 'true' %]
+            <th scope='col'>[% l("Part") %]</th>
+            [%- END %]
+            <th scope='col'>[% l("Text to Phone") %]</th>
+            <th scope='col'>[% l("Barcode") %]</th>
+            <th scope='col'>[% l("Shelving Location") %]</th>
+            [%- IF ctx.is_staff %]
+            <th scope='col'>[% l("Age Hold Protection") %]</th>
+            <th scope='col'>[% l("Active/Create Date") %]</th>
+            [%- END %]
+            [%- IF ctx.is_staff OR serial_holdings %]
+            <th scope='col'>[% l("Holdable?") %]</th>
+            [%- END %]
+            <th scope='col'>[% l("Status") %]</th>
+            <th scope='col'>[% l("Due Date") %]</th>
+        </tr>
+    </thead>
+    <tbody class="copy_details_table">
+[%- FOREACH peer IN ctx.foreign_copies;
+        FOREACH bib IN peer.foreign_copy_maps; %]
+    <tr class="copy_details_row"><td>
+    [%- bib_lib_name = ctx.get_aou(bib.target_copy.circ_lib).name | html;
+        l("[_1] (foreign item)", bib_lib_name); -%]
+        <ul><li>
+            <span class="bib_peer_type">[% bib.peer_type.name | html %]</span>:
+            <a href="[% mkurl(ctx.opac_root _ '/record/' _ bib.target_copy.call_number.record) %]">
+                <span class="bib_peer_title">[% peer.title | html %]</span> / 
+                <span class="bib_peer_author">[% peer.author | html %]</span>
+            </a>
+        </li></ul>
+    </td>
+    <td>[% bib.target_copy.call_number.label | html %]</td>
+    <td>[% bib.target_copy.barcode | html %]</td>
+    <td>[% copy_info.copy_location | html %]</td>
+    <td>[% copy_info.copy_status | html %]</td>
+    <td>[% copy_info.due_date | html %]</td>
+</tr>
+   [%- END; # FOREACH peer
+END; # FOREACH bib
+-%]
+        [%- last_cn = 0;
+        FOR copy_info IN copies;
+            callnum = copy_info.call_number_label;
+            NEXT IF callnum == '##URI##';
+
+            callnum_prefix = copy_info.call_number_prefix_label;
+            IF callnum_prefix != "";
+                callnum = callnum_prefix _ " " _ callnum;
+            END;
+
+            callnum_suffix = copy_info.call_number_suffix_label;
+            IF callnum_suffix != "";
+                callnum = callnum  _ " " _ callnum_suffix;
+            END;
+        -%]
+        <tr class="copy_details_offers_row" property="offers" typeof="Offer">
+            [%- IF serial_holdings %]<td class='rdetail-issue-issue'>
+                [%- copy_info.holding_label | html; -%]
+            </td>
+            [%- ELSE %]<td>
+            [%- INCLUDE "opac/parts/library_name_link.tt2"; -%]
+                <link property="businessFunction" href="http://purl.org/goodrelations/v1#LeaseOut">
+                <meta property="price" content="0.00">
+            </td>[% END %]
+            <td><span property="sku">[% callnum | html %]</span> [% IF ctx.get_org_setting(CGI.param('loc') 
+                OR ctx.aou_tree.id, 'sms.enable') == 1 %]<a href="[% mkurl(ctx.opac_root _ '/sms_cn', 
+               {copy_id => copy_info.id}) %];rec=[%- ctx.bre_id -%]" rel="nofollow" vocab=""></a>[% END %]</td>
+            [%- IF has_parts == 'true' %]
+            <td>[% copy_info.part_label | html %]</td>
+            [%- END %]
+            <td>
+[% IF ctx.get_org_setting(CGI.param('loc') OR ctx.aou_tree.id, 'sms.enable') == 1 %](<a href="[% mkurl(ctx.opac_root _ '/sms_cn', {copy_id => copy_info.id}) %]">Text</a>)[% END %]</td>
+            <td property="serialNumber">
+                [% copy_info.barcode | html -%]
+                [% IF ctx.is_staff %]
+                  [%- IF ctx.is_browser_staff %]
+                    <a target="_blank" href="[% ctx.base_path %]/staff/cat/item/[% copy_info.id %]">[% l('view') %]</a>
+                    [% IF ctx.has_perm('UPDATE_COPY', copy_info.circ_lib) 
+                        OR ctx.has_perm('UPDATE_COPY', copy_info.call_number_owning_lib) %]
+                        <span> | </span>
+                        <!-- XXX: copy edit is not yet supported in browser client.
+                          Enable this link when available
+                        -->
+                        <!--
+                        <a href="[% ctx.base_path %]/staff/cat/item/[% copy_info.id %]/edit">[% l('edit') %]</a>
+                        -->
+                    [% END %]
+                  [% ELSE %]
+                    <a onclick="xulG.new_tab(xulG.urls.XUL_COPY_STATUS, {}, {'from_item_details_new': true, 'barcodes': ['[%- copy_info.barcode | html | replace('\'', '\\\'') -%]']})"
+                        href="javascript:;">[% l('view') %]</a>
+                    [%# if the user can edit copies, show the copy edit link %]
+                    [% IF ctx.has_perm('UPDATE_COPY', copy_info.circ_lib) 
+                        OR ctx.has_perm('UPDATE_COPY', copy_info.call_number_owning_lib) %]
+                        <span> | </span>
+                        <a href="javascript:;" 
+                            onclick="xulG.volume_item_creator({copy_id : [% copy_info.id %]})">
+                            [% l(' edit') %]
+                        </a>
+                    [% END %]
+                  [% END %]
+                [% END %]
+                [%- IF attrs.gtin13;
+                    '<meta property="gtin13" content="' _ attrs.gtin13 _ '" />';
+                END; -%]
+            </td>
+            <td property="availableAtOrFrom">[% copy_info.copy_location | html %]</td>
+            [%- IF ctx.is_staff %]
+            <td>
+                [% copy_info.age_protect ?
+                    ctx.get_crahp(copy_info.age_protect).name : l('None') | html %]
+            </td>
+            <td>[% 
+                IF ctx.get_org_setting(copy_info.circ_lib, 'circ.holds.age_protect.active_date') == 1;
+                    disp_date = copy_info.active_date ? copy_info.active_date : copy_info.create_date;
+                ELSE;
+                    disp_date = copy_info.create_date;
+                END;
+           
+                IF disp_date;
+                    date.format(
+                        ctx.parse_datetime(disp_date),
+                        DATE_FORMAT
+                    );
+                ELSE;
+                   '-';
+                END;
+            %]</td>
+            [% END # is_staff %]
+            [% IF ctx.is_staff OR serial_holdings %]
+            <td>[%  # Show copy/volume hold links to staff (without
+                # checking whether they have permissions to do those).
+                overall_holdable = (
+                    copy_info.holdable == 't' AND
+                    copy_info.location_holdable == 't' AND
+                    copy_info.status_holdable == 't'
+                );
+                IF overall_holdable;
+                    hold_link = '';
+                    param_sep = l(" / ");
+
+                    # Only staff get to place copy or volume holds
+                    IF ctx.is_staff; 
+                        hold_link = '<a href="' _
+                            mkurl(ctx.opac_root _ '/place_hold', {
+                                hold_target => copy_info.id,
+                                hold_type => 'C',
+                                hold_source_page => mkurl()
+                            }) _ '">' _ l('Copy hold') _ '</a>';
+                        IF copy_info.call_number != last_cn;
+                            last_cn = copy_info.call_number; 
+                            hold_link = hold_link _ param_sep;
+                            hold_link = hold_link _ '<a href="' _
+                                mkurl(ctx.opac_root _ '/place_hold', {
+                                    hold_target => copy_info.call_number,
+                                    hold_type => 'V',
+                                    hold_source_page => mkurl()
+                                }) _ '">' _ l('Volume hold') _ '</a>';
+                        END;
+                        IF serial_holdings;
+                            hold_link = hold_link _ param_sep;
+                        END;
+                    END; 
+                    IF serial_holdings; 
+                        hold_link = hold_link _
+                            '<a class="rdetail-issue-place-hold" href="' _
+                            mkurl(ctx.opac_root _ '/place_hold', {
+                                hold_target => copy_info.issuance,
+                                hold_type => 'I',
+                                hold_source_page => mkurl()
+                            }) _ '" rel="nofollow" vocab="">' _ l('Issue hold') _ '</a>';
+                    END; 
+
+                    hold_link;
+                ELSE; 
+                    l("Not holdable");
+                END %]</td>
+            [%- END %]
+            <td>[%-
+                schema_copy_status.${copy_info.status_code};
+                copy_info.copy_status | html;
+            -%]</td>
+            <td>[%
+                IF copy_info.due_date;
+                    date.format(
+                        ctx.parse_datetime(copy_info.due_date),
+                        DATE_FORMAT
+                    );
+                ELSE;
+                    '-';
+                END %]</td>
+        </tr>
+
+        [% IF copy_info.notes; %]
+            [% FOREACH note IN copy_info.notes; %]
+                <tr><td>&nbsp;</td><td class="copy_note" colspan="4" property="description"><strong>[% note.title | html %]:</strong> [% note.value | html %]</td></tr>
+            [% END %]
+        [% END %]
+
+<tr><td>
+[%- IF copy_info.peer_bib_marc.size > 1;
+'<ul>';
+    FOREACH bib IN copy_info.peer_bib_marc;
+        attrs = {marc_xml => bib};
+        PROCESS get_marc_attrs args=attrs %]
+[%- IF attrs.bibid != ctx.bre_id; -%]
+    <li property="isRelatedTo" typeof="Product">
+        [%- # Map the bound-with relationship -%]
+        <a href="[% mkurl(ctx.opac_root _ '/record/' _ attrs.bibid) %]" property="url">
+            <span class="bib_peer_title" property="name">[% attrs.title | html %]</span>
+            / <span class="bib_peer_author">[% attrs.author | html %]</span>
+        </a>
+    </li>
+[%- END; # IF attrs.bibid %]
+[%- END; # FOREACH bib in copy_info.peer_bib_marc
+'</ul>';
+    END # IF copy_info.peer_bib_marc.size
+%]
+</td></tr>
+[%- END; # FOR copy_info
+%]
+        <tr>
+        [%- IF ctx.copy_offset > 0 AND NOT serial_holdings;
+            new_offset = ctx.copy_offset - ctx.copy_limit;
+            IF new_offset < 0; new_offset = 0; END %]
+            <td>
+                <a href="[% mkurl('', {copy_offset => new_offset, copy_limit => ctx.copy_limit}) %]">&laquo; [%
+                    l('Previous [_1]', ctx.copy_offset - new_offset) %]</a>
+            </td>
+        [%- END %]
+        [%- IF copies.size >= ctx.copy_limit AND NOT serial_holdings %]
+            <td>
+                <a href="[% mkurl('', {copy_offset => ctx.copy_offset + ctx.copy_limit, copy_limit => ctx.copy_limit}) %]">[%
+                    l('Next [_1]', ctx.copy_limit) %] &raquo;</a>
+            </td>
+        [%- END %]
+        </tr>
+        [% IF NOT serial_holdings -%]
+        <tr>
+            <td>
+                [%- more_copies_limit = 50 %] [%# TODO: config %]
+                [%- IF  ctx.copy_limit != more_copies_limit AND copies.size >= ctx.copy_limit %]
+                    <div class="rdetail_show_copies">
+                        <img src="[% ctx.media_prefix %]/images/plus_sign.png" alt="[% l('Show more copies icon') %]"/>
+                        <a href="[% mkurl('', {copy_limit => more_copies_limit, copy_offset => 0}) %]">[% l('Show more copies') %]</a>
+                    </div>
+                [%- ELSIF ctx.copy_limit == more_copies_limit %]
+                    <div  class="rdetail_show_copies">
+                        <img src="[% ctx.media_prefix %]/images/minus_sign.png" alt="[% l('Show fewer copies icon') %]"/>
+                        <a href="[% mkurl('', {copy_limit => 0, copy_offset => 0}) %]">[% l('Show fewer copies') %]</a>
+                    </div>
+                [%- END %]
+            </td>
+        </tr>
+        [%- END %]
+    </tbody>
+</table>
+[% END; %]
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/record/extras.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/record/extras.tt2
new file mode 100644 (file)
index 0000000..8d75fac
--- /dev/null
@@ -0,0 +1,104 @@
+[%
+    arrow_right = '&#9658;';
+    arrow_down = '&#9660;';
+%]
+<div>
+    <div id='rdetail_extras_div' style='width: 100%;'> 
+        [%
+            IF ctx.google_books_preview;
+                label = l('Google Preview');
+                name = 'google_preview';
+                href = 'javascript:GBDisplayPreview();';
+        %]
+        <div id="gbp_extra" class="rdetail_extras hide_me">
+            <div class="rdetail_extras_hr"></div>
+            <div id="gbp_extra_links" class="rdetail_extras_link">
+                <a id='gbp_arrow_link' name='[% name %]' href='[% href %]' class='rdetail_extras_lbl'>[% arrow_right %]</a>
+                <a id='gbp_arrow_down_link' name='[% name %]' href='[% href %]' class='rdetail_extras_lbl hide_me'>[% arrow_down %]</a>
+                <a name='[% name %]_lbl' href='[% href %]' class="rdetail_extras_lbl">[% label %]</a></div>
+        </div>
+        <div id="gbp_extra_container" class='rdetail_extras_div'></div>
+        [%  END %]
+
+        [%  # Hidden extras are not yet implemented.  Some may require JS
+
+        MACRO tab_is_active(tab) BLOCK;
+            exp_name = 'expand_' _ tab;
+            IF ctx.$exp_name OR ctx.expand_all; 1; END;
+        END;
+
+        # Let's see if we should hide the content cafe / simple summary content
+        hide_summary = 1;
+        IF attrs.summaries.0; hide_summary = 0; ELSE;
+            # Expose content cafe if it's reasonable to do so.
+            # This approach only works when using embedded content cafe.
+            IF ENV.OILS_CONTENT_CAFE_USER; 
+                ident = attrs.isbn_clean || attrs.upc; 
+                IF ident; hide_summary = 0; END;
+            END;
+        END;
+
+        # if no added content is available, hide the main tab.
+        # if any content is available, use the first tab as the default display tab.
+        default_ac = '';
+        IF !tab_is_active('addedcontent');
+            hide_ac = 1;
+            FOR type IN ctx.added_content.keys;
+                IF ctx.added_content.$type.status != '2'; # not available
+                    hide_ac = 0;
+                END;
+                IF ctx.added_content.$type.status == '1';
+                    SET default_ac = type UNLESS default_ac;
+                END;
+            END;
+        END;
+
+        extras = [
+        #    {name => 'summaryplus',  label => l('Summaries & More'), hide => hide_summary},
+        #    {name => 'annotation', label => l('Annotation'), hide => 1}, 
+        #    {name => 'awards',  label => l('Awards, Reviews, & Suggested Reads')}, 
+        #    {name => 'excerpt',  label => l('Excerpt'), hide => 1},
+            {name => 'issues',   label => l('Issues Held'), hide => !(ctx.have_holdings_to_show || ctx.have_mfhd_to_show)},
+        #    {name => 'preview',  label => l('Preview'), hide => 1}, 
+        #    {name => 'addedcontent',  label => l('Additional Content'), hide => hide_ac},  # hide if all content is known to not exist
+        #    {name => 'cnbrowse', label => l('Shelf Browser')},
+            {name => 'marchtml', label => l('Bibliographic Record')}
+        ];
+
+        FOREACH extra IN extras;
+            IF extra.hide; NEXT; END; 
+            name = extra.name;
+        %]
+        <div class="rdetail_extras">
+            <div class="rdetail_extras_hr"></div>
+            <div class="rdetail_extras_link">
+                [%  
+                    IF tab_is_active(name);
+                        href = mkurl('', {}, ['expand', 'ac']);
+                        arrow = arrow_down;
+                    ELSE;
+                        IF name == 'addedcontent' AND default_ac;
+                            href = mkurl('', {expand => name, ac => default_ac}) _ '#' _ name; 
+                        ELSE;
+                            href = mkurl('', {expand => name}) _ '#' _ name; 
+                        END;
+                        arrow = arrow_right;
+                    END;
+                %]
+                <a name='[% name %]' href='[% href %]' class="rdetail_extras_lbl">[% arrow %] [% extra.label | html %]</a>
+            </div>
+        </div>
+        <div class='rdetail_extras_div'>
+            [%  IF tab_is_active(name);
+                    IF name == 'marchtml';
+                        ctx.marchtml;
+                    ELSE;
+                        # Load the template for the selected extra
+                        INCLUDE "opac/parts/record/${name}.tt2";
+                    END;
+                END; 
+            %]
+        </div>
+        [% END %]
+    </div>
+</div>
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/record/marcextras.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/record/marcextras.tt2
new file mode 100644 (file)
index 0000000..f3af3a9
--- /dev/null
@@ -0,0 +1,104 @@
+[%
+    arrow_right = '&#9658;';
+    arrow_down = '&#9660;';
+%]
+<div>
+    <div id='rdetail_extras_div'> 
+        [%
+            IF ctx.google_books_preview;
+                label = l('Google Preview');
+                name = 'google_preview';
+                href = 'javascript:GBDisplayPreview();';
+        %]
+        <div id="gbp_extra" class="rdetail_extras hide_me">
+            <div class="rdetail_extras_hr"></div>
+            <div id="gbp_extra_links" class="rdetail_extras_link">
+                <a id='gbp_arrow_link' name='[% name %]' href='[% href %]' class='rdetail_extras_lbl'>[% arrow_right %]</a>
+                <a id='gbp_arrow_down_link' name='[% name %]' href='[% href %]' class='rdetail_extras_lbl hide_me'>[% arrow_down %]</a>
+                <a name='[% name %]_lbl' href='[% href %]' class="rdetail_extras_lbl">[% label %]</a></div>
+        </div>
+        <div id="gbp_extra_container" class='rdetail_extras_div'></div>
+        [%  END %]
+
+        [%  # Hidden extras are not yet implemented.  Some may require JS
+
+        MACRO tab_is_active(tab) BLOCK;
+            exp_name = 'expand_' _ tab;
+            IF ctx.$exp_name OR ctx.expand_all; 1; END;
+        END;
+
+        # Let's see if we should hide the content cafe / simple summary content
+        hide_summary = 1;
+        IF attrs.summaries.0; hide_summary = 0; ELSE;
+            # Expose content cafe if it's reasonable to do so.
+            # This approach only works when using embedded content cafe.
+            IF ENV.OILS_CONTENT_CAFE_USER; 
+                ident = attrs.isbn_clean || attrs.upc; 
+                IF ident; hide_summary = 0; END;
+            END;
+        END;
+
+        # if no added content is available, hide the main tab.
+        # if any content is available, use the first tab as the default display tab.
+        default_ac = '';
+        IF !tab_is_active('addedcontent');
+            hide_ac = 1;
+            FOR type IN ctx.added_content.keys;
+                IF ctx.added_content.$type.status != '2'; # not available
+                    hide_ac = 0;
+                END;
+                IF ctx.added_content.$type.status == '1';
+                    SET default_ac = type UNLESS default_ac;
+                END;
+            END;
+        END;
+
+        extras = [
+        #    {name => 'summaryplus',  label => l('Summaries & More'), hide => hide_summary},
+        #    {name => 'annotation', label => l('Annotation'), hide => 1}, 
+        #    {name => 'awards',  label => l('Awards, Reviews, & Suggested Reads')}, 
+        #    {name => 'excerpt',  label => l('Excerpt'), hide => 1},
+        #    {name => 'issues',   label => l('Issues Held'), hide => !(ctx.have_holdings_to_show || ctx.have_mfhd_to_show)},
+        #    {name => 'preview',  label => l('Preview'), hide => 1}, 
+        #    {name => 'addedcontent',  label => l('Additional Content'), hide => hide_ac},  # hide if all content is known to not exist
+        #    {name => 'cnbrowse', label => l('Shelf Browser')},
+            {name => 'marchtml', label => l('Bibliographic Record')}
+        ];
+
+        FOREACH extra IN extras;
+            IF extra.hide; NEXT; END; 
+            name = extra.name;
+        %]
+        <div class="rdetail_extras">
+            <div class="rdetail_extras_hr"></div>
+            <div class="rdetail_extras_link">
+                [%  
+                    IF tab_is_active(name);
+                        href = mkurl('', {}, ['expand', 'ac']);
+                        arrow = arrow_down;
+                    ELSE;
+                        IF name == 'addedcontent' AND default_ac;
+                            href = mkurl('', {expand => name, ac => default_ac}) _ '#' _ name; 
+                        ELSE;
+                            href = mkurl('', {expand => name}) _ '#' _ name; 
+                        END;
+                        arrow = arrow_right;
+                    END;
+                %]
+                <a name='[% name %]' href='[% href %]' class="rdetail_extras_lbl">[% arrow %] [% extra.label | html %]</a>
+            </div>
+        </div>
+        <div class='rdetail_extras_div'>
+            [%  IF tab_is_active(name);
+                    IF name == 'marchtml';
+                        ctx.marchtml;
+                    ELSE;
+                        # Load the template for the selected extra
+                        INCLUDE "opac/parts/record/${name}.tt2";
+                    END;
+                END; 
+            %]
+        </div>
+        [% END %]
+    </div>
+</div>
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/record/summary.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/record/summary.tt2
new file mode 100644 (file)
index 0000000..8cb5c3d
--- /dev/null
@@ -0,0 +1,343 @@
+[%  PROCESS "opac/parts/misc_util.tt2";
+    USE ResolverResolver;
+    ctx.page_title = attrs.title | html
+    ctx.metalinks.push('<meta property="og:image" content="' _ ctx.media_prefix _ '/opac/extras/ac/jacket/large/r/' _ ctx.bre_id _ '" />');
+%]
+[%# Most of the changes in this file that make it different from the vanilla template
+     have to do with reorganization of the way the data displays on the screen. This was
+     done based on the wishes of our members.
+%]
+<!-- ****************** rdetail_summary.xml ***************************** -->
+<abbr class="unapi-id" title='tag:[% ctx.hostname %],[% date.format(date.now, '%Y') %]:biblio-record_entry/[% ctx.bre_id %]'></abbr>
+
+<hr />
+
+[%-# This holds the record summary information %]
+<div id="rdetail_summary_header">
+[%# rdetail_image_div moved higher in display %]
+    <div id="rdetail_image_div">
+        <a href='[% ctx.media_prefix %]/opac/extras/ac/jacket/large/r/[% ctx.bre_id | uri %]'><img
+            alt="[% l('Image of item') %]" id='rdetail_image'
+            src='[% ctx.media_prefix %]/opac/extras/ac/jacket/[% record.summary.jacket_size %]/r/[% ctx.bre_id | uri %]' /></a>
+        <br />
+    </div>
+
+    <div id='rdetail_title_div'>
+        <h1 id='rdetail_title' property="name">[% attrs.title_extended | html %]</h1>
+        [%-
+            FOR link880 IN attrs.graphic_titles;
+                FOR alt IN link880.graphic;
+                    '<h2 class="graphic880"';
+                    IF alt.dir;
+                        ' dir="' _ alt.dir _ '"';
+                    END;
+                    '>'; alt.value | html; '</h2>';
+                END;
+            END;
+        -%]
+        [%- INCLUDE "opac/parts/record/authors.tt2" %]
+    </div>
+
+    <div id="format_actions">
+        [%- IF attrs.format_label %]
+          [% FOR format IN attrs.all_formats %]
+              <img title="[% format.label | html %]" 
+                  alt="[% format.label | html %]" 
+                  src="[% format.icon %]" /> 
+              [% format.label | html %]
+          [% END %]
+        [%- END %]
+[%# Record details moved up in display.  h2 commented out - not wanted in display. %]
+<!-- <h2 id='rdetail_record_details'>[% l("Record details") %]</h2> -->
+<ul>
+    [%- IF attrs.isbns.0;
+          FOR isbn IN attrs.isbns;
+            isbn_extra = '';
+            IF (matches = isbn.match('^(.+?)(\s.+)$'));
+              isbn = matches.0;
+              isbn_extra = matches.1;
+            END;
+    %]
+    <li class='rdetail_isbns'>
+        <strong class='rdetail_label'>[% l('ISBN:'); %]</strong>
+        <span class='rdetail_value' property='isbn'>[% isbn | html  %]</span>[% isbn_extra | html %]
+    </li>
+        [%- END %]
+    [%- END %]
+    [%- IF attrs.issns.0; FOR issn IN attrs.issns %]
+    <li class='rdetail_issns'>
+        <strong class='rdetail_label'>[% l('ISSN:'); %]</strong>
+        <span class='rdetail_value'>[% issn | html  %]</span>
+    </li>
+        [%- END %]
+    [%- END %]
+[%# edition moved above physical description for display. %]
+    [%- IF attrs.edition %]
+    <li id='rdetail_edition'>
+        <strong class='rdetail_label'>[% l("Edition:") %]</strong>
+        <span class='rdetail_value'>[% attrs.edition | html %]</span>
+        [%-
+        FOR entry IN attrs.graphic_editions;
+            FOR alt IN entry.graphic;
+                diratt = "";
+                IF alt.dir;
+                    diratt = ' dir="' _ alt.dir _ '"';
+                END;
+        -%]
+        <div class="graphic880 rdetail_value"[% diratt %]>
+            [% alt.value | html %]
+        </div>
+        [%-
+            END;
+        END;
+        -%]
+    </li>
+    [%- END %]
+
+    [%- IF attrs.phys_desc %]
+    <li id='rdetail_phys_desc'>
+        <strong class='rdetail_label'>[% l("Physical Description:") %]</strong>
+        <span class='rdetail_value'>[% attrs.phys_desc | html %]</span>
+    </li>
+    [%- END %]
+    [%- IF attrs.targetaud %]
+    <li id='rdetail_targetaud' style="list-style:none;">
+        <strong class='rdetail_label'>[% l("Rating: ") %]</strong>
+        <span class='rdetail_value'>[% attrs.targetaud | html %]</span>
+    </li>
+    [%- END %]
+
+    [%- IF attrs.publisher %]
+    <li id='rdetail_publisher'>
+        <strong class='rdetail_label'>[% l("Publisher:") %]</strong>
+        <span class='rdetail_value' property="publisher" typeof="Organization">
+        [%- IF attrs.pubplace; %]
+            <span property="location">[% attrs.pubplace | html; %]</span>
+        [%- END; %]
+            <span property="name">[% attrs.publisher | html; %]</span>
+        </span>
+        [%- IF attrs.pubdate; %]
+            <span property="datePublished">[% attrs.pubdate | html; %]</span>
+        [%- END; %]
+        [%-
+        IF attrs.graphic_pubinfos.size > 0;
+            FOR entry IN attrs.graphic_pubinfos;
+                FOR alt IN entry.graphic;
+                    diratt = "";
+                    IF alt.dir;
+                        diratt = ' dir="' _ alt.dir _ '"';
+                    END;
+        -%]
+        <div class="graphic880"[% diratt %]>
+            [% alt.value | html %]
+        </div>
+        [%-
+                END;
+            END;
+        END
+        -%]
+    </li>
+    [%- END %]
+    [%- IF attrs.producer %]
+        <li id='rdetail_producer'>
+            <strong class='rdetail_label'>[% l("Producer:") %]</strong>
+            <span class='rdetail_value'>
+            [%- IF attrs.prodplace; %]
+                <span>[% attrs.prodplace | html; %]</span>
+            [%- END; %]
+                <span>[% attrs.producer | html; %]</span>
+            [%- IF attrs.proddate; %]
+                <span>[% attrs.proddate | html; %]</span>
+            [%- END; %]
+            </span>
+        </li>
+    [%- END %]
+    [%- IF attrs.distributor %]
+        <li id='rdetail_distributor'>
+            <strong class='rdetail_label'>[% l("Distributor:") %]</strong>
+            <span class='rdetail_value'>
+            [%- IF attrs.distplace; %]
+                <span>[% attrs.distplace | html; %]</span>
+            [%- END; %]
+                <span>[% attrs.distributor | html; %]</span>
+            [%- IF attrs.distdate; %]
+                <span>[% attrs.distdate | html; %]</span>
+            [%- END; %]
+            </span>
+        </li>
+    [%- END %]
+    [%- IF attrs.manufacturer %]
+        <li id='rdetail_manufacturer'>
+            <strong class='rdetail_label'>[% l("Manufacturer:") %]</strong>
+            <span class='rdetail_value' property="manufacturer" typeof="Organization">
+            [%- IF attrs.manplace; %]
+                <span property="location">[% attrs.manplace | html; %]</span>
+            [%- END; %]
+                <span property="name">[% attrs.manufacturer | html; %]</span>
+            [%- IF attrs.mandate; %]
+                <span>[% attrs.mandate | html; %]</span>
+            [%- END; %]
+            </span>
+        </li>
+    [%- END %]
+    [%- IF attrs.copyright %]
+    <li id='rdetail_copyright'>
+        <strong class='rdetail_label'>[% l("Copyright:") %]</strong>
+        <span class='rdetail_value'>[% attrs.copyright | html_entity; %]
+        [%-# Provide the 4-digit year, cleansed of '@' and other junk %]
+        [%- IF attrs.copyrightYear -%]
+            <meta property='copyrightYear' content='[% attrs.copyrightYear | html; %]'>
+        [%- END -%]
+        </span>
+    </li>
+    [%- END %]
+</ul>
+[%# rdetail_actions_div moved down for display. %]
+        <div id="rdetail_actions_div">
+            [%- search_ou = ctx.search_ou;
+                IF ctx.place_unfillable ||
+                    ( attrs.marc_xml.findnodes('//*[local-name()="holdings" and @has_holdable="true"]').size
+                        && (ctx.holds_block.enabled != 'true' || !attrs.org_copy_counts.$search_ou.available)
+                    )
+             %]
+            <div class="rdetail_aux_utils place_hold">
+                <a href="[% mkurl(ctx.opac_root _ '/place_hold', 
+                    {hold_target => ctx.bre_id, hold_type => 'T', hold_source_page => mkurl()}, stop_parms) %]" 
+                class="no-dec" rel="nofollow" vocab=""><img src="[% ctx.media_prefix %]/images/green_check.png" 
+                    [% img_alt(l('Place Hold on [_1]', attrs.title)) %]/>
+                <span class="place_hold">[% l('Place Hold') %]</span></a>
+            </div>
+            [%- END -%]
+            <div class="rdetail_aux_utils toggle_list">
+            [%  IF ctx.user;
+                INCLUDE "opac/parts/bookbag_actions.tt2";
+            %]
+            [%  ELSE;
+                operation = ctx.mylist.grep(ctx.bre_id).size ? "delete" : "add";
+                label = (operation == "add") ? l("Add to my list") : l("Remove from my list"); 
+            %]
+                <a href="[% mkurl(ctx.opac_root _ '/mylist/' _ operation, {record => ctx.bre_id}, stop_parms) %]" class="no-dec" rel="nofollow" vocab="">
+                    <img src="[% ctx.media_prefix %]/images/clipboard.png" alt="" />
+                    [% label %]
+                </a>
+            [% END %]
+            </div>
+            <div class="rdetail_aux_utils">
+                <img src="[% ctx.media_prefix %]/images/clipboard.png" alt="[% l('Print / Email Actions Image') %]" />
+                <a href="[% mkurl(ctx.opac_root _ '/record/print/' _ ctx.bre_id) %]" class="no-dec" rel="nofollow" vocab="">[% l('Print') %]</a> /
+                <a href="[% mkurl(ctx.opac_root _ '/record/email/' _ ctx.bre_id) %]" class="no-dec" rel="nofollow" vocab="">[% l('Email') %]</a>
+            </div>
+            [%- IF ctx.refworks.enabled == 'true' %]
+                [%- INCLUDE 'opac/parts/record/refworks.tt2' %]
+            [%- END %]
+            <div class="rdetail_aux_utils share_record">
+                <a href="[% mkurl('', {locg =>CGI.param('locg'), copy_depth =>CGI.param('copy_depth')}, 1) %]" class="no-dec">
+                     <img src="[% ctx.media_prefix %]/images/link.png" alt="[% l('Permalink') %]" />
+                     [% l('Permalink') %]
+                </a>
+            </div>
+        </div>
+    </div>
+</div>
+
+[%- IF openurl.enabled == 'true';
+    openurls = [];
+    FOREACH issn IN args.issns;
+        NEXT IF issn == '';
+        openurls = openurls.import(ResolverResolver.resolve_issn(issn, openurl.baseurl));
+    END;
+    IF openurls.size && openurls.0 != '';
+%]
+    <div id='rdetail_openurl'>
+        <strong class='rdetail_openurl_title'>[% l("Online access") %]</strong>
+        <table><tbody>
+[%-
+        FOREACH res IN openurls;
+%]
+        <tr>
+            <td class='rdetail_openurl_entry'><a href="[% res.target_url %]">[% res.public_name | html %]</a></td>
+            <td>[% res.target_coverage | html %]
+            [%- IF res.target_embargo != '';
+                    ' - ';
+                    res.target_embargo | html;
+                END;
+            -%]
+            </td>
+        </tr>
+    [%- END %]
+    </tbody></table>
+    </div>    
+[%- END %]
+[%- END %]
+[%- merged_uris = args.uris.merge(args.online_res);
+num_uris = merged_uris.size;
+IF num_uris > 0;
+-%]
+[%# Electronic resources label changed to Online access
+     uri.link after ELSE changed to Click here 
+%]
+<h2 class="rdetail_uris">[% l("Online access") %]</h2>
+<div class="rdetail_uris">
+    [%- IF num_uris > 1 %]<ul>[% END %]
+    [%- FOR uri IN merged_uris %]
+        [%- IF num_uris == 1 -%]
+            <p class="rdetail_uri" property="offers" vocab="http://schema.org/" typeof="Offer">
+        [%- ELSE -%]
+            <li class="rdetail_uri" property="offers" vocab="http://schema.org/" typeof="Offer">
+        [%- END -%]
+        <a href="[% uri.href %]" property="url">
+        [%- IF uri.href != uri.link;
+                '<span property="description">' _ uri.link _ '</span>';
+            ELSE;
+                'Click here';
+            END;
+        -%]
+        </a>
+        [%- ' - <span property="description">' _ uri.note _ '</span>' IF uri.note %]
+        <link property="availability" href="http://schema.org/OnlineOnly" />
+        [%- IF attrs.gtin13; '<meta property="gtin13" content="' _ attrs.gtin13 _ '" />'; END; %]
+        [%- IF num_uris == 1 %]</p>[% ELSE %]</li>[% END %]
+    [%- END %]
+    [%- IF num_uris > 1 %]</ul>[% END %]
+</div>
+[%- END %]
+[%- # Hold/copy summary
+    IF ctx.copy_summary.0.count
+%]
+<div id="copy_hold_counts">
+[%- INCLUDE "opac/parts/record/copy_counts.tt2" %]
+    <span id="rdetail_hold_counts">
+        <h2>[% l('Current holds') %]</h2>
+        <p>
+            [% 
+                # If org hiding is enabled/relevant, only show 
+                # counts for copies within the hiding scope.
+                count_entry = 0;
+                FOR count_chunk IN ctx.copy_summary;
+                    IF ctx.org_within_hiding_scope(count_chunk.org_unit);
+                        # always true when hiding is disabled
+                        LAST;
+                    END;
+                    count_entry = count_entry + 1;
+                END;
+                l("[quant,_1,current hold,current holds] with [quant,_2,total copy,total copies].", 
+                    ctx.record_hold_count, ctx.copy_summary.$count_entry.count) 
+            %]
+        </p>
+    </span>
+[%# This ctx is to allow display of the bib record link higher in the staff client. %]
+[%- IF ctx.is_staff %]
+[%- INCLUDE "opac/parts/record/marcextras.tt2" %]
+[%- END %]
+[%- INCLUDE "opac/parts/record/copy_table.tt2" copies=ctx.copies %]
+</div>
+[%- END %]
+
+
+[%- INCLUDE "opac/parts/record/contents.tt2" %]
+[%- INCLUDE "opac/parts/record/subjects.tt2" %]
+[%- INCLUDE "opac/parts/record/series.tt2" %]
+[%# awards.tt2 and addedcontent.tt2 must be included for Novelist Select %]
+[%- INCLUDE "opac/parts/record/awards.tt2" %]
+[%- INCLUDE "opac/parts/record/addedcontent.tt2" %]
+[%- INCLUDE "opac/parts/record/extras.tt2" %]
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/result/copy_counts.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/result/copy_counts.tt2
new file mode 100644 (file)
index 0000000..dc8aab7
--- /dev/null
@@ -0,0 +1,41 @@
+[%- depths = attrs.copy_counts.size;
+    depth = 0;
+    displayed_ous = {};
+    hiding_disabled = ctx.org_hiding_disabled();
+    WHILE depth < depths;
+        org_unit = ctx.get_aou(attrs.copy_counts.$depth.org_unit);
+        ou_name = org_unit.name;
+        displayed_ous.$ou_name = 1;
+        IF attrs.copy_counts.$depth.count > 0 AND (
+            hiding_disabled OR ctx.org_within_hiding_scope(org_unit.id));
+%]
+<div class="result_count">
+[% IF ctx.get_aou(attrs.copy_counts.$depth.org_unit).opac_visible == 't' %]
+    [% l('[_1] of [quant,_2,copy,copies] available at [_3].',
+        attrs.copy_counts.$depth.available,
+        attrs.copy_counts.$depth.count,
+        ou_name) | html
+    %]
+[% END %]
+</div>
+[%-     END;
+    depth = depth + 1;
+    END;
+
+    depth = attrs.plib_copy_counts.size - 1;
+    org_unit = ctx.get_aou(attrs.plib_copy_counts.$depth.org_unit);
+    ou_name = org_unit.name;
+    UNLESS displayed_ous.exists(ou_name);
+    
+%]
+[%- IF attrs.plib_copy_counts.$depth.count > 0 AND (
+        hiding_disabled OR ctx.org_within_hiding_scope(org_unit.id)) %]
+<div class="result_count preferred">[%
+     l('[_1] of [quant,_2,copy,copies] available at [_3].',
+        attrs.plib_copy_counts.$depth.available,
+        attrs.plib_copy_counts.$depth.count,
+        ou_name) | html
+    %]
+</div>
+[%- END %]
+[%- END %]
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/result/lowhits.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/result/lowhits.tt2
new file mode 100644 (file)
index 0000000..5416705
--- /dev/null
@@ -0,0 +1,57 @@
+<div>
+    <div id="zero_search_hits">
+        <div class="zero_search_hits_saved">
+            [% INCLUDE "opac/parts/staff_saved_searches.tt2" %]
+        </div>
+        <div class="zero_search_hits_main">
+            <p>[% l('Sorry, no entries were found for') %]
+                [% IF is_advanced OR is_special; l('your search'); ELSE %]
+                <q>[% CGI.param('query') | html %]</q>
+                [% END %]
+                [% IF ctx.bookbag;
+                    l('within') %]
+                    <span class="lowhits-bookbag-name">[% ctx.bookbag.name | html %]</span>.
+                [% END %]
+
+            </p>
+<p>Here are some suggestions that might help you find what you're looking for:
+</p>
+<p>If you were limiting your search to one specific library, you might want to try choosing "All C/W MARS libraries" from the library drop down list.</p>
+<p><strong>Simplify your search.</strong> Use as few words and limiters as you can. Often you can get the results you want without using any limiters.
+</p>
+<p><strong>Check</strong> to make sure you're <strong>spelling</strong> your search words correctly: for example, twlight will not return results for twilight, don't is different from dont, and tool kit is different from toolkit.
+</p>
+<p>Also, there is the possibility that the item you're looking for is not available from any of our libraries. If this is the case, you can try the <a href="http://www.cwmars.org/content/commonwealth-catalog">Commonwealth Catalog</a> and search state-wide.
+</p>
+        </div>
+        <div style="float:right;width:353px;background:#ccc;padding:10px;margin-top:7px;">
+            [% INCLUDE "opac/parts/result/lowhits_purchase.tt2" %]
+            <p>
+                <strong>Keyword Search Tips</strong><br />
+                Try changing to <strong>Advanced 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 any number of characters.<br />
+                (example: <strong>environment* agency</strong>)
+            </p>
+            <p>
+                <strong>Anchored Searching</strong><br />
+                You may use ^ and $ to indicate "phrase begins with" and
+                "phrase ends with," respectively, within a search phrase
+                enclosed in quotation marks.<br />
+                (examples: <strong>"^harry"</strong> for phrases that begin with
+                the term <em>harry</em>.
+                <strong>"stone$"</strong> for phrases that end in <em>stone</em>.)
+            </p>
+        </div>
+    </div>
+</div>
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/result/table.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/result/table.tt2
new file mode 100644 (file)
index 0000000..9397c55
--- /dev/null
@@ -0,0 +1,474 @@
+[%  PROCESS "opac/parts/misc_util.tt2";
+
+    USE ResolverResolver;
+
+    ctx.result_start = 1 + ctx.page_size * page;
+    ctx.result_stop = ctx.page_size * (page + 1);
+    IF ctx.result_stop > ctx.hit_count; ctx.result_stop = ctx.hit_count; END;
+
+    result_count = ctx.result_start;
+
+%]
+
+[% PROCESS "opac/parts/result/paginate.tt2" %] 
+[% ctx.results_count_header = PROCESS results_count_header;
+    ctx.results_count_header %]
+[% IF ctx.bookbag %]
+<div id="result-bookbag-heading">
+    <div class="result-bookbag-name">[% ctx.bookbag.name | html %]</div>
+    <div class="result-bookbag-description">[% ctx.bookbag.description | html %]</div>
+</div>
+[% END %]
+<div id="result_table_div">
+    <div class="facet_sidebar_hidden" id="facet_sidebar">
+    <h3 class="sr-only">[% l('Saved Searches') %]</h3>
+    [% INCLUDE "opac/parts/staff_saved_searches.tt2" %]
+    <h3 class="sr-only">[% l('Search Results facets') %]</h3>
+    [% INCLUDE 'opac/parts/result/facets.tt2' %]
+    <h3 class="sr-only">[% l('Search Results List') %]</h3>
+    </div>
+            <div id="result_block" class="result_block_visible">
+                <table id="result_table_table" title="[% l('Search Results') %]"
+                  class="table_no_border_space table_no_cell_pad">
+                    <thead class="sr-only">
+                      <tr>
+                        <th>[% l('Search result number') %]</th>
+                        <th>[% l('Book jacket cover art') %]</th>
+                        <th>[% l('Item details and Actions') %]</th>
+                      </tr>
+                    </thead>
+                    <tbody id="result_table">
+                    [%  FOR rec IN ctx.records;
+                            attrs = {marc_xml => rec.marc_xml};
+                            PROCESS get_marc_attrs args=attrs;
+                            IF CGI.param('detail_record_view')
+                                OR (show_more_details.default == 'true'
+                                OR show_more_details.default == 'hide');
+                                attrs.title = attrs.title_extended;
+                            END;
+                            # note: rec.id refers to the record identifier, regardless
+                            # of the type of record. i.e. rec.id = mmr_id ? mmr_id : bre_id
+                            IF rec.mmr_id;
+                                IF rec.mr_constituent_count > 1;
+                                    # metarecords link to record list page
+                                    record_url = mkurl(ctx.opac_root _ '/results', 
+                                        {metarecord => rec.mmr_id}, ['page']);
+                                ELSE;
+                                    # for MR, bre_id refers to the master and in
+                                    # this case, only, record
+                                    record_url = mkurl(ctx.opac_root _ '/record/' _ rec.bre_id);
+                                END;
+                                hold_type = 'M';
+                            ELSE;
+                                record_url = mkurl(ctx.opac_root _ '/record/' _ rec.bre_id);
+                                hold_type = 'T';
+                            END;
+                    -%]
+                        <tr class="result_table_row">
+                                            <td class="results_row_count" name="results_row_count">[%
+                                                    result_count; result_count = result_count + 1
+                                                %].</td>
+                                            <td class='result_table_pic_header'>
+                                                <a href="[% record_url %]"><img alt="[% l('Book cover') %]"
+                                                        name='item_jacket' class='result_table_pic' width="55"
+                                                        src='[% ctx.media_prefix %]/opac/extras/ac/jacket/small/r/[% rec.bre_id | uri %]' /></a><br />
+                                            </td>
+                                            <td class='result_table_title_cell' name='result_table_title_cell'>
+                                               <div class="result_metadata">
+<br />
+                                                    [% IF rec.mmr_id %]
+                                                    <abbr class="unapi-id" 
+                                                      title='tag:[% ctx.hostname %],[% date.format(date.now, '%Y') %]:metabib-metarecord/[% rec.mmr_id %]'>
+                                                    </abbr>
+                                                    [% ELSE %]
+                                                    <abbr class="unapi-id" 
+                                                      title='tag:[% ctx.hostname %],[% date.format(date.now, '%Y') %]:biblio-record_entry/[% rec.bre_id %]'>
+                                                    </abbr>
+                                                    [% END %]
+                                                    <a class='record_title search_link' name='record_[% rec.id %]'
+                                                        href="[% record_url %]"
+                                                        [% html_text_attr('title', l('Display record details for "[_1]"', attrs.title)) %]>
+                                                        [% attrs.title | html %]
+                                                     </a>
+                                                     [% IF rec.mr_constituent_count.defined && rec.mr_constituent_count > 1 %]
+                                                     <span title="[% l('This group contains [_1] records', rec.mr_constituent_count) %]">
+                                                      ([% rec.mr_constituent_count %])
+                                                     </span>
+                                                     [% END %]
+
+[%-
+FOR entry IN attrs.graphic_titles;
+    FOR alt IN entry.graphic;
+        diratt = "";
+        IF alt.dir;
+            diratt = ' dir="' _ alt.dir _ '"';
+        END;
+-%]
+<div class="graphic880"[% diratt %]>
+    [% alt.value | html %]
+</div>
+[%-
+    END;
+END;
+-%]
+                                                    <div>
+                                                        <a title="[% l("Perform an Author Search") %]"
+                                                                class="record_author"
+                                                                href="[%- 
+                                                                    authorquery = attrs.author | replace('[#"^$\+\-,\.:;&|\[\]()]', ' ');
+                                                                    mkurl(ctx.opac_root _ '/results', {qtype => 'author', query => authorquery}, general_search_parms.merge(expert_search_parms, browse_search_parms, facet_search_parms))
+                                                                    -%]" rel="nofollow" vocab="">[% attrs.author | html %]</a>
+[%-
+FOR entry IN attrs.graphic_authors;
+    FOR alt IN entry.graphic;
+        diratt = "";
+        IF alt.dir;
+            diratt = ' dir="' _ alt.dir _ '"';
+        END;
+-%]
+<div class="graphic880"[% diratt %]>
+    [% alt.value | html %]
+</div>
+[%-
+    END;
+END;
+-%]
+
+                                                    </div>
+                                                    <div class='result_table_title_cell'>
+                                                    [%- IF attrs.format_label; %]
+                                                        [% FOR format IN attrs.all_formats %]
+                                                            <img title="[% format.label | html %]" 
+                                                                alt="[% format.label | html %]" 
+                                                                src="[% format.icon %]" /> 
+                                                            [% format.label | html %]
+                                                        [% END %]
+                                                    [%- END %]
+                                                    </div>
+                                                    <table 
+                                                       role="presentation"
+                                                       title="[% l('Record Holdings Summary') %]"
+                                                       class="table_no_border_space table_no_cell_pad table_no_border results_info_table">
+                                                        [% UNLESS rec.mmr_id %]
+                                                           [% IF args.holdings.size > 0 %]
+                                                        <tr name='bib_cn_list' class='result_table_title_cell'>
+                                                            <td valign='top'>
+                                                                <strong>[% l('Call number:') %]</strong>
+                                                            </td>
+                                                            <td>[% args.holdings.0.label | html %]</td>
+                                                        </tr>
+                                                           [% END %]
+                                                        [% END %]
+
+                                                        [% IF attrs.edition %]
+                                                            <tr name="results_edition_tr">
+                                                                <td valign="top">
+                                                                    <strong>[% l('Edition:') %]</strong>
+                                                                </td>
+                                                                <td>[% attrs.edition | html %]
+[%-
+FOR entry IN attrs.graphic_editions;
+    FOR alt IN entry.graphic;
+        diratt = "";
+        IF alt.dir;
+            diratt = ' dir="' _ alt.dir _ '"';
+        END;
+-%]
+<div class="graphic880"[% diratt %]>
+    [% alt.value | html %]
+</div>
+[%-
+    END;
+END;
+-%]
+</td>
+                                                            </tr>
+                                                        [% END %]
+
+                                                        [% IF attrs.phys_desc %]
+                                                            <tr name="results_phys_desc_tr">
+                                                                <td nowrap="nowrap" valign="top">
+                                                                    <strong>[% l('Phys. Desc.:') %]</strong>
+                                                                </td>
+                                                                <td>
+                                                                    [% args.phys_desc | html %]
+                                                                </td>
+                                                            </tr>
+                                                        [% END %]
+
+
+                                                        [% IF attrs.targetaud %]
+                                                            <tr name="results_target_aud_tr">
+                                                                <td valign="top">
+                                                                    <strong>[% l('Rating: ') %]</strong>
+                                                                </td>
+                                                                <td>[% attrs.targetaud | html %]
+[%-
+FOR entry IN attrs.graphic_targetaud;
+    FOR alt IN entry.graphic;
+        diratt = "";
+        IF alt.dir;
+           diratt = ' dir="' _ alt.dir _ '"';
+        END;
+-%]
+<div class="graphic880"[% diratt %]>
+    [% alt.value | html %]
+</div>
+[%-
+    END;
+END;
+-%]
+</td>
+</tr>
+[% END %]
+
+                                                        [% IF attrs.publisher %]
+                                                            <tr name="results_pub_tr">
+                                                                <td valign="top">
+                                                                    <strong>[% l('Publisher:') %]</strong>
+                                                                </td>
+                                                                <td>[% attrs.pubplace | html; %] [% attrs.publisher | html; %] [% attrs.pubdate | html; %]
+[%-
+FOR entry IN attrs.graphic_pubinfos;
+    FOR alt IN entry.graphic;
+        diratt = "";
+        IF alt.dir;
+            diratt = ' dir="' _ alt.dir _ '"';
+        END;
+-%]
+<div class="graphic880"[% diratt %]>
+    [% alt.value | html %]
+</div>
+[%-
+    END;
+END;
+-%]
+</td>
+                                                            </tr>
+                                                        [% ELSIF attrs.producer %]
+                                                            <tr name="results_pub_tr">
+                                                                <td valign="top">
+                                                                    <strong>[% l('Producer:') %]</strong>
+                                                                </td>
+                                                                <td>[% attrs.prodplace | html; %] [% attrs.producer | html; %] [% attrs.proddate | html; %]</td>
+                                                            </tr>
+                                                        [% ELSIF attrs.distributor %]
+                                                            <tr name="results_pub_tr">
+                                                                <td valign="top">
+                                                                    <strong>[% l('Distributor:') %]</strong>
+                                                                </td>
+                                                                <td>[% attrs.distplace | html; %] [% attrs.distributor | html; %] [% attrs.distdate | html; %]</td>
+                                                            </tr>
+                                                        [% ELSIF attrs.manufacturer %]
+                                                            <tr name="results_pub_tr">
+                                                                <td valign="top">
+                                                                    <strong>[% l('Manufacturer:') %]</strong>
+                                                                </td>
+                                                                <td>[% attrs.manplace | html; %] [% attrs.manufacturer | html; %] [% attrs.mandate | html; %]</td>
+                                                            </tr>
+                                                        [% END %]
+                                                        [% FOR uri IN args.uris %]
+                                                            <tr name='bib_uri_list' class='result_table_title_cell'>
+                                                                <td valign='top'>
+                                                                    <strong>[% l('Online access') %]</strong>
+                                                                </td>
+                                                                <td><a href="[% uri.href %]">[% uri.link | html %]</a>[% ' - ' _ uri.note | html IF uri.note %]</td>
+                                                            </tr>
+                                                        [% END %]
+                                                        [%- IF CGI.param('detail_record_view')
+                                                            OR (show_more_details.default == 'true'
+                                                            OR show_more_details.default == 'hide');
+                                                        -%]
+                                                        <!-- These fields are visible when viewing the results page in 'detailed' mode -->
+                                                        [% UNLESS rec.mmr_id %]
+                                                        <!-- Do not show publication-specific information on a metarecord search results page -->
+                                                      
+                                                        [% IF attrs.isbns.size > 0 %]
+                                                            <tr name="results_isbn_tr">
+                                                                <td valign="top">
+                                                                    <strong>[% l('ISBN:') %]</strong>
+                                                                </td>
+                                                                <td>[% attrs.isbns.0 | html %]</td>
+                                                            </tr>
+                                                        [% END %]
+                                                        [%- IF attrs.issns.size > 0 %]
+                                                            <tr name="results_issn_tr">
+                                                                <td valign="top">
+                                                                    <strong>[% l('ISSN:') %]</strong>
+                                                                </td>
+                                                                <td>[% attrs.issns.0 | html %]</td>
+                                                            </tr>
+                                                        [%- END %]
+                                                        [%- IF openurl.enabled == 'true';
+                                                            FOREACH issn IN args.issns;
+                                                                NEXT IF issn == '';
+                                                                res_urls = ResolverResolver.resolve_issn(issn, openurl.baseurl);
+                                                                FOREACH res IN res_urls;
+                                                        %]
+                                                        <tr name="results_issn_tr">
+                                                            <td valign="top">
+                                                                <strong><a href="[% res.target_url %]">
+                                                                [% res.public_name | html %]</a></strong>
+                                                            </td>
+                                                            <td>[% res.target_coverage | html %]
+                                                            [%- IF res.target_embargo != '';
+                                                                    ' - ';
+                                                                    res.target_embargo | html;
+                                                                END;
+                                                            -%]
+                                                            </td>
+                                                        </tr>
+                                                                [% END %]
+                                                            [% END %]
+                                                        [% END %]
+
+                                                         [% END %]
+                                                            [%- IF args.holdings.size > 0;
+                                                                FOREACH copy IN args.holdings;
+                                                                    IF copy.part_label != '';
+                                                                        has_parts = 'true';
+                                                                        LAST;
+                                                                    END;
+                                                                END;
+                                                            %]
+                                                            <tr name='bib_cn_list' class='result_table_title_cell'>
+                                                                <td colspan='2'>
+                                                                    <table title="[% l('Record Holdings Details') %]"
+                                                                           class='result_holdings_table'>
+                                                                        <thead><tr>
+                                                                            <th>[% l('Library') %]</th>
+                                                                            <th>[% l('Shelving location') %]</th>
+                                                                            <th>[% l('Call number') %]</th>
+                                                                            [%- IF has_parts == 'true'; %]
+                                                                            <th>[% l('Part') %]</th>
+                                                                            [%- END %]
+                                                                            <th>[% l('Status') %]</th>
+                                                                        </tr></thead>
+                                                                        <tbody>
+                                                                [% FOR copy IN args.holdings %]
+                                                                        <tr>
+                                                                            <td>
+[%- copy_info = copy;
+    INCLUDE "opac/parts/library_name_link.tt2"; %]
+                                                                            </td>
+                                                                            <td>[% copy.location | html %]</td>
+                                                                            <td>[% copy.label | html %]</td>
+                                                                            [%- IF has_parts == 'true'; %]
+                                                                            <td>[% copy.part_label %]</td>
+                                                                            [%- END %]
+                                                                            <td>[% copy.status | html %]</td>
+                                                                        </tr>
+                                                                [% END %]
+                                                                        </tbody>
+                                                                    </table>
+                                                                </td>
+                                                            </tr>
+                                                            [%- has_parts = 'false';
+                                                                END;
+                                                             %]
+                                                        [% END %] <!-- END detail_record_view -->
+                                                    </table>
+                                                    [% PROCESS "opac/parts/result/copy_counts.tt2" %]
+                                                    [% IF rec.user_circulated %]
+                                                    <div class="result_item_circulated">
+                                                        <img src="[% ctx.media_prefix %]/images/green_check.png" alt="[% l('Checked Out Before') %]"/>
+                                                        <span>[% l('I have checked this item out before') %]</span>
+                                                    </div>
+                                                    [% END %]
+                                                    [% IF ctx.bookbag;
+                                                        rec_id = rec.id;
+                                                        FOR note IN ctx.bookbag_items_by_bre_id.$rec_id.notes %]
+                                                    <div class="result-bookbag-item-note">
+                                                        [% note.note | html %]
+                                                    </div>
+                                                        [% END %]
+                                                    [% END %]
+                                                </div>
+                                                <div class="result_table_utils_cont">
+                                                    <div class="result_table_utils">
+[%- search_ou = ctx.search_ou;
+    num_holdable_copies = attrs.marc_xml.findnodes('//*[local-name()="holdings" and @has_holdable="true"]').size || 0;
+    IF ctx.place_unfillable ||
+        ( num_holdable_copies > 0
+            && (ctx.holds_block.enabled != 'true' || attrs.org_copy_counts.$search_ou.available == 0)
+        )
+%]
+                                                        <div class="results_aux_utils place_hold"><a
+                                                                href="[% mkurl(ctx.opac_root _ '/place_hold',
+                                                                    {hold_target => rec.id, hold_type => hold_type, 
+                                                                      hold_source_page => mkurl()}, ['query','tag','subfield','term','_special','sort','page']) %]"
+                                                                [% html_text_attr('title', l('Place Hold on [_1]', attrs.title)) %]
+                                                                    class="no-dec" rel="nofollow" vocab=""><img
+                                                                src="[% ctx.media_prefix %]/images/green_check.png"
+                                                                alt=""/><span class="result_place_hold">[% l('Place Hold') %]</span></a>
+                                                        </div>
+[%- END -%]
+                                                        <div class="results_aux_utils result_util">
+                                                            [%  IF ctx.user;
+                                                                INCLUDE "opac/parts/bookbag_actions.tt2";
+                                                            %]
+                                                            [%  ELSE;
+                                                                operation = ctx.mylist.grep(rec.id).size ? "delete" : "add";
+                                                                label = (operation == "add") ?  l("Add to my list") : l("Remove from my list");
+                                                                title_label = (operation == "add") ? 
+                                                                  l("Add [_1] to my list", attrs.title) : 
+                                                                  l("Remove [_1] from my list", attrs.title);
+                                                                href = mkurl(ctx.opac_root _ '/mylist/' _ operation, 
+                                                                        {record => rec.id, anchor => 'record_' _ rec.id}, 1);
+                                                            %]      
+                                                            <a href="[% href %]" class="no-dec" 
+                                                                [% html_text_attr('title', title_label) %] rel="nofollow" vocab="">
+                                                                <img src="[% ctx.media_prefix %]/images/clipboard.png" alt="" />
+                                                                [% label %]
+                                                            </a>
+                                                            [% END %]
+                                                        </div>
+                                                    </div>
+                                                </div>
+
+                                            </td>
+
+                                        </tr>
+                                        [%- IF ENV.OILS_CHILIFRESH_ACCOUNT %]
+                                        <tr>
+                                            <td/>
+                                            <td align='center'> <!-- Chilifresh reviews link --> 
+                                                <span class="chili_review" id="isbn_[% attrs.isbn_clean | html %]"> </span>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td/>
+                                            <td colspan='5'> <!-- Chilifresh reviews panel -->
+                                                <div id="chili_review_[% attrs.isbn_clean | html %]" style="display: none;" align="center"></div>
+                                            </td>
+                                        </tr>
+                                        [%- END %]
+                    [% END %]
+                    </tbody>
+                </table>
+            </div>
+</div>
+<div class="result_footer_nav1">
+    [% ctx.results_count_header %]
+</div>
+<script>
+resultBlock = document.getElementById('result_block');
+resultButton = document.getElementById('return_to_hits');
+facetSidebar = document.getElementById('facet_sidebar');
+facetButton =  document.getElementById('refine_hits');
+function getFacety() {
+    resultBlock.setAttribute('class', 'result_block_hidden');
+    resultButton.setAttribute('class', 'results_header_btns result_block_visible');
+    facetSidebar.setAttribute('class', 'facet_sidebar_visible');
+    facetButton.setAttribute('class', 'result_block_hidden');
+    window.location.hash = 'return_to_hits';
+}
+function getResulty() {
+    resultBlock.setAttribute('class', 'result_block_visible');
+    resultButton.setAttribute('class', 'result_block_hidden');
+    facetSidebar.setAttribute('class', 'facet_sidebar_hidden');
+    facetButton.setAttribute('class', 'results_header_btns result_block_visible');
+    window.location.hash = 'refine_hits';
+}
+</script>
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/searchbar.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/searchbar.tt2
new file mode 100644 (file)
index 0000000..8e0772e
--- /dev/null
@@ -0,0 +1,116 @@
+<h3 class="sr-only">[% l('Catalog Search') %]</h3>
+[% PROCESS "opac/parts/org_selector.tt2" %]
+<div id="search-wrapper">
+    [% UNLESS took_care_of_form -%]
+    <form action="[% ctx.opac_root %]/results" method="get">
+    [%- END %]
+    <div id="search-box">
+<!--        <span class="search_catalog_lbl mobile_hide">[% l('Search the Catalog') %]</span> -->
+        <span class="adv_search_catalog_lbl"><a href="[% mkurl(ctx.opac_root _ '/advanced', {},  expert_search_parms.merge(browse_search_parms, facet_search_parms)) %]"
+            id="home_adv_search_link" rel="nofollow" vocab="">[% l('More Search Options') %]</a></span>
+        <span class="browse_the_catalog_lbl"><a href="[% mkurl(ctx.opac_root _ '/browse', {}, expert_search_parms.merge(general_search_parms, facet_search_parms, ['fi:has_browse_entry'])) %]" rel="nofollow" vocab="">[% l('Browse the Catalog') %]</a></span>
+    </div>
+<center>
+    <div class="searchbar">
+        <span class='search_box_wrapper'>
+            [%- # autosuggest breaks accessibility, as the aria-label
+                # attribute is removed when the Dijit is created. :(  %]
+            <label id="search_box_label" for="search_box">[% l(' ') %]
+            <input type="text" id="search_box" name="query" style="width:40em; height:1.5em; font-size:16px; aria-label="[%
+                    l('Enter search query:');
+                %]" value="[% is_advanced ? ctx.naive_query_scrub(ctx.processed_search_query) : CGI.param('query') | html %]"
+                [%- IF use_autosuggest.enabled == "t" %]
+                dojoType="openils.widget.AutoSuggest" type_selector="'qtype'"
+                submitter="this.textbox.form.submit();"
+                [%-     IF use_autosuggest.value.search('opac_visible') %]
+                store_args='{"org_unit_getter": function() { return [% ctx.search_ou %]; }}'
+                [%-     END # opac_visible -%]
+                [%- ELSE -%]
+                    [% IF basic_search != "f" %] autofocus [% END %] x-webkit-speech
+                [%- END # autosuggest enabled %] />
+            </label>
+        </span>
+<br />
+        <label id="search_qtype_label" for="qtype">
+        [%- 
+            l(' ');
+            INCLUDE "opac/parts/qtype_selector.tt2" id="qtype";
+        -%]
+        </label>
+        <label id="search_itype_label" for="search_itype_selector">
+        [%-
+            l(' ');
+            IF search.basic_config.type == 'attr';
+                INCLUDE "opac/parts/coded_value_selector.tt2"
+                    attr=search.basic_config.group none_ok=1 
+                    id='search_itype_selector'
+                    none_label=search.basic_config.none_label;
+            ELSIF search.basic_config.type == 'filter';
+                INCLUDE "opac/parts/filter_group_selector.tt2"
+                    filter_group=search.basic_config.group none_ok=1 
+                    id='search_itype_selector'
+                    none_label=search.basic_config.none_label;
+            END;
+        -%]
+        </label>
+        <label id="search_locg_label" for="search_org_selector">
+        [%- 
+            l('in ');
+            select_lib_label = l("Select search library");
+            INCLUDE build_org_selector arialabel=select_lib_label 
+              id='search_org_selector' show_loc_groups=1
+        -%]
+        </label>
+    <span>
+    [%- IF (show_more_details.default == 'true' OR show_more_details.default == 'hide') AND !CGI.param('detail_record_view') %]
+        <input id="detail" type="hidden" name="detail_record_view" value="1"/>
+    [%- END %]
+        <input id='search-submit-go' type="submit" value="[% l('Search') %]" class="opac-button"
+            onclick='setTimeout(function(){$("search-submit-spinner").className=""; $("search-submit-go").className="hidden"}, 2000)'/>
+        <img id='search-submit-spinner' src='/opac/images/progressbar_green.gif' style='height:16px;width:16px;' class='hidden' alt='[% l("Search In Progress") %]'/>
+    </span>
+    </div>
+    [% IF ctx.bookbag %]
+    <div id="search-only-bookbag-container">
+        <input type="checkbox" id="search-only-bookbag" name="bookbag"
+            value="[% ctx.bookbag.id | html %]" checked="checked" />
+        <label for="search-only-bookbag">
+            [% l('Search only within the chosen list') %]
+        </label>
+    </div>
+    [% END %]
+    [% IF is_advanced || is_special %]
+    <div>
+        <input type="hidden" name="_adv" value="1" />
+        [% IF ctx.processed_search_query OR (NOT is_advanced AND NOT is_special) %]
+        <input name='page' type='hidden' value="0" />
+        [% END %]
+        [% IF is_special %]
+            <input type="hidden" name="_special" value="1" /> [%
+            number_of_expert_rows = CGI.param('tag').list.size;
+            index = 0;
+            WHILE index < number_of_expert_rows %]
+                <input type="hidden" name="tag" value="[% CGI.param('tag').list.$index %]" />
+                <input type="hidden" name="subfield" value="[% CGI.param('subfield').list.$index %]" />
+                <input type="hidden" name="term" value="[% CGI.param('term').list.$index %]" />
+                [% index = index + 1; %]
+            [% END %]
+        [% END %]
+    </div>
+    [%- END %]
+    [% UNLESS took_care_of_form %]</form>[% END %]
+    [% IF (is_advanced AND NOT is_special) AND CGI.param('qtype') %]
+    <div class="opac-auto-102">
+        [ <a href="[% mkurl(ctx.opac_root _ '/advanced') %]" rel="nofollow" vocab="">[%
+            l('Refine My 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>
+</center>
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/seo_meta.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/seo_meta.tt2
new file mode 100644 (file)
index 0000000..f8c5ffc
--- /dev/null
@@ -0,0 +1,2 @@
+<meta name="description" content="CWMARS Online Catalog">
+<meta name="keywords" content="CWMARS, Online Catalog, Library Catalog">
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/table.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/table.tt2
new file mode 100644 (file)
index 0000000..56cda3d
--- /dev/null
@@ -0,0 +1,389 @@
+[%  PROCESS "opac/parts/misc_util.tt2";
+
+    USE ResolverResolver;
+
+    ctx.result_start = 1 + ctx.page_size * page;
+    ctx.result_stop = ctx.page_size * (page + 1);
+    IF ctx.result_stop > ctx.hit_count; ctx.result_stop = ctx.hit_count; END;
+
+    result_count = ctx.result_start;
+
+%]
+
+[% PROCESS "opac/parts/result/paginate.tt2" %] 
+[% ctx.results_count_header = PROCESS results_count_header;
+    ctx.results_count_header %]
+
+[% IF ctx.bookbag %]
+<div id="result-bookbag-heading">
+    <div class="result-bookbag-name">[% ctx.bookbag.name | html %]</div>
+    <div class="result-bookbag-description">[% ctx.bookbag.description | html %]</div>
+</div>
+[% END %]
+<div id="result_table_div">
+            <div class="facet_sidebar">
+                [% INCLUDE "opac/parts/staff_saved_searches.tt2" %]
+                [% INCLUDE 'opac/parts/result/facets.tt2' %]
+            </div>
+            <div class="result_block">
+                <table cellpadding="0" cellspacing="0"
+                    border="0" 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;
+                            IF CGI.param('detail_record_view');
+                                attrs.title = attrs.title_extended;
+                            END;
+                    -%]
+                        <tr class="result_table_row">
+                                            <td class="results_row_count" name="results_row_count">[%
+                                                    result_count; result_count = result_count + 1
+                                                %].</td>
+                                            <td class='result_table_pic_header'>
+                                                [% ident = attrs.isbn_clean || attrs.upc; IF ident; %]
+                                                <a href="[% mkurl(ctx.opac_root _ '/record/' _ rec.id) %]"><img alt="[% l('Image of item') %]"
+                                                        name='item_jacket' class='result_table_pic' width="55"
+                                                        src='[% ctx.media_prefix %]/opac/extras/ac/jacket/small/[% ident | uri %]' /></a><br />
+                                                [% END %]
+                                            </td>
+                                            <td class='result_table_title_cell' name='result_table_title_cell'>
+                                            <div class="bold">
+                                                        <a name='record_[% rec.id %]' name='item_title'
+                                                        href="[% mkurl(ctx.opac_root _ '/record/' _ rec.id) %]"
+                                                        [% HTML.attributes(title => l('Display record details for "[_1]"', attrs.title)) %]
+                                                        class='search_link'>[% attrs.title | html %]</a></div>
+[%-
+FOR entry IN attrs.graphic_titles;
+    FOR alt IN entry.graphic;
+        diratt = "";
+        IF alt.dir;
+            diratt = ' dir="' _ alt.dir _ '"';
+        END;
+-%]
+<div class="graphic880"[% diratt %]>
+    [% alt.value | html %]
+</div>
+[%-
+    END;
+END;
+-%]
+                                                <div>
+                                                    <div>
+                                                        <em><a title="[% l("Perform an Author Search") %]"
+                                                                name='item_author'
+                                                                href="[%- 
+                                                                    authorquery = attrs.author | replace('[#"^$\+\-,\.:;&|\[\]()]', '');
+                                                                    mkurl(ctx.opac_root _ '/results', {qtype => 'author', query => authorquery}, ['page'])
+                                                                    -%]">[% attrs.author | html %]</a></em>
+                                                                    [%- UNLESS CGI.param('detail_record_view')
+                                                                        OR (show_more_details.default == 'true'
+                                                                        OR show_more_details.default == 'hide')
+                                                                    %]
+<!--  [% attrs.pubdate | html %] -->
+                                                                    [%- END -%]
+[%-
+FOR entry IN attrs.graphic_authors;
+    FOR alt IN entry.graphic;
+        diratt = "";
+        IF alt.dir;
+            diratt = ' dir="' _ alt.dir _ '"';
+        END;
+-%]
+<div class="graphic880"[% diratt %]>
+    [% alt.value | html %]
+</div>
+[%-
+    END;
+END;
+-%]
+                                                    </div>
+                                                    <table cellpadding="0" cellspacing="0" border="0"
+                                                        class="results_info_table">
+                                                        [% IF args.holdings.size > 0 %]
+                                                        <tr name='bib_cn_list' class='result_table_title_cell'>
+                                                            <td valign='top'>
+                                                                <strong>[% l('Call number:') %]</strong>
+                                                            </td>
+                                                            <td>[% args.holdings.0.label | html %]</td>
+                                                        </tr>
+                                                        [% END %]
+                                                        [% IF attrs.pubinfo %]
+                                                            <tr name="results_pub_tr">
+                                                                <td valign="top">
+                                                                    <strong>[% l('Publisher: ') %]</strong>
+                                                                </td>
+                                                                <td>[% attrs.pubinfo | html %]
+[%-
+FOR entry IN attrs.graphic_pubinfos;
+    FOR alt IN entry.graphic;
+        diratt = "";
+        IF alt.dir;
+            diratt = ' dir="' _ alt.dir _ '"';
+        END;
+-%]
+<div class="graphic880"[% diratt %]>
+    [% alt.value | html %]
+</div>
+[%-
+    END;
+END;
+-%]
+</td>
+                                                            </tr>
+                                                        [% END %]
+                                                        [% IF attrs.edition %]
+                                                            <tr name="results_edition_tr">
+                                                                <td valign="top">
+                                                                    <strong>[% l('Edition: ') %]</strong>
+                                                                </td>
+                                                                <td>
+                                                                    [% attrs.edition | html %]</td>
+                                                            </tr>
+                                                        [% END %]
+                                                        [% IF attrs.targetaud %]
+                                                            <tr>
+                                                                <td valign="top">
+                                                                    <strong>[% l('Rating: ') %]</strong>
+                                                                </td>
+                                                                <td>
+                                                                    [% attrs.targetaud | html %]</td>
+                                                            </tr>
+                                                        [% END %]
+                                                        [% IF attrs.phys_desc %]
+                                                            <tr name="results_phys_desc_tr">
+                                                                <td nowrap="nowrap" valign="top">
+                                                                    <strong>[% l('Phys. Desc.: ') %]</strong>
+                                                                </td>
+                                                                <td>
+                                                                    [% args.phys_desc | html %]
+                                                                </td>
+                                                             </tr>
+                                                        [% END %]
+                                                        [% IF CGI.param('detail_record_view') %]
+                                                        <!-- These fields are visible when viewing the results page in 'detailed' mode -->
+<!--
+                                                        [% IF attrs.pubinfo %]
+                                                            <tr name="results_pub_tr">
+                                                                <td valign="top">
+                                                                    <strong>[% l('Publisher:') %]</strong>
+                                                                </td>
+                                                                <td>[% attrs.pubinfo | html %]</td>
+                                                            </tr>
+                                                        [% END %]
+-->
+                                                        [% IF attrs.isbns.size > 0 %]
+                                                            <tr name="results_isbn_tr">
+                                                                <td valign="top">
+                                                                    <strong>[% l('ISBN:') %]</strong>
+                                                                </td>
+                                                                <td>[% attrs.isbns.0 | html %]</td>
+                                                            </tr>
+                                                        [% END %]
+                                                        [%- IF openurl.enabled == 'true';
+                                                            FOREACH issn IN args.issns;
+                                                                NEXT IF issn == '';
+                                                                res_urls = ResolverResolver.resolve_issn(issn, openurl.baseurl);
+                                                                FOREACH res IN res_urls;
+                                                        %]
+                                                        <tr name="results_issn_tr">
+                                                            <td valign="top">
+                                                                <strong><a href="[% res.target_url %]">
+                                                                [% res.public_name | html %]</a></strong>
+                                                            </td>
+                                                            <td>[% res.target_coverage | html %]</td>
+                                                        </tr>
+                                                                [% END %]
+                                                            [% END %]
+                                                        [% END %]
+<!--
+                                                        [% IF attrs.edition %]
+                                                            <tr name="results_edition_tr">
+                                                                <td valign="top">
+                                                                    <strong>[% l('Edition:') %]</strong>
+                                                                </td>
+                                                                <td>[% attrs.edition | html %]
+[%-
+FOR entry IN attrs.graphic_editions;
+    FOR alt IN entry.graphic;
+        diratt = "";
+        IF alt.dir;
+            diratt = ' dir="' _ alt.dir _ '"';
+        END;
+-%]
+<div class="graphic880"[% diratt %]>
+    [% alt.value | html %]
+</div>
+[%-
+    END;
+END;
+-%]
+</td>
+                                                            </tr>
+                                                        [% END %]
+                                                        [% IF attrs.phys_desc %]
+                                                            <tr name="results_phys_desc_tr">
+                                                                <td nowrap="nowrap" valign="top">
+                                                                    <strong>[% l('Phys. Desc.:') %]</strong>
+                                                                </td>
+                                                                <td>
+                                                                    [% args.phys_desc | html %]
+                                                                </td>
+                                                            </tr>
+                                                        [% END %]
+-->
+                                                        [% FOR uri IN args.uris %]
+                                                            <tr name='bib_uri_list' class='result_table_title_cell'>
+                                                                <td valign='top'>
+                                                                    <strong>[% l('Electronic resource') %]</strong>
+                                                                </td>
+                                                                <td><a href="[% uri.href %]">[% uri.link | html %]</a>[% ' - ' _ uri.note | html IF uri.note %]</td>
+                                                            </tr>
+                                                            [% END %]
+                                                            [%- IF args.holdings.size > 0;
+                                                                FOREACH copy IN args.holdings;
+                                                                    IF copy.part_label != '';
+                                                                        has_parts = 'true';
+                                                                        LAST;
+                                                                    END;
+                                                                END;
+                                                            %]
+                                                            <tr name='bib_cn_list' class='result_table_title_cell'>
+                                                                <td colspan='2'>
+                                                                    <table class='result_holdings_table'>
+                                                                        <thead><tr>
+                                                                            <th>[% l('Library') %]</th>
+                                                                            <th>[% l('Shelving location') %]</th>
+                                                                            <th>[% l('Call number') %]</th>
+                                                                            [%- IF has_parts == 'true'; %]
+                                                                            <th>[% l('Part') %]</th>
+                                                                            [%- END %]
+                                                                            <th>[% l('Status') %]</th>
+                                                                        </tr></thead>
+                                                                        <tbody>
+                                                                [% FOR copy IN args.holdings %]
+                                                                        <tr>
+                                                                            <td>[% copy.library | html %]</td>
+                                                                            <td>[% copy.location | html %]</td>
+                                                                            <td>[% copy.label | html %]</td>
+                                                                            [%- IF has_parts == 'true'; %]
+                                                                            <td>[% copy.part_label %]</td>
+                                                                            [%- END %]
+                                                                            <td>[% copy.status | html %]</td>
+                                                                        </tr>
+                                                                [% END %]
+                                                                        </tbody>
+                                                                    </table>
+                                                                </td>
+                                                            </tr>
+                                                            [%- has_parts = 'false';
+                                                                END;
+                                                             %]
+                                                        [% END %] <!-- END detail_record_view -->
+                                                    </table>
+                                                    [% PROCESS "opac/parts/result/copy_counts.tt2" %]
+<div><span>&nbsp;</span></div>
+                                                    [% IF rec.user_circulated %]
+                                                    <div class="result_item_circulated">
+                                                        <img src="[% ctx.media_prefix %]/images/green_check.png" alt="[% l('Checked Out Before') %]"/>
+                                                        <span>[% l('I have checked this item out before') %]</span>
+                                                    </div>
+                                                    [% END %]
+                                                    [% IF ctx.bookbag;
+                                                        rec_id = rec.id;
+                                                        FOR note IN ctx.bookbag_items_by_bre_id.$rec_id.notes %]
+                                                    <div class="result-bookbag-item-note">
+                                                        [% note.note | html %]
+                                                    </div>
+                                                        [% END %]
+                                                    [% END %]
+                                                </div>
+                                            </td>
+
+                                            <td name='result_table_format_cell' class='result_table_format_cell' width="1">
+
+                                                [% IF attrs.format_icon %]
+                                                <img title="[% attrs.format_label | html %]" alt="[% attrs.format_label | html %]" src="[% attrs.format_icon %]" />
+                                                [% END %]
+
+                                                <!-- unAPI link -->
+                                                <abbr class="unapi-id" title='tag:[% ctx.hostname %],[% date.format(date.now, '%Y') %]:biblio-record_entry/[% rec.id %]'></abbr>
+
+                                                <!-- 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 class="result_table_utils_cont">
+                                                    <div class="result_table_utils">
+[%- search_ou = ctx.search_ou;
+    num_holdable_copies = attrs.marc_xml.findnodes('//*[local-name()="holdings" and @has_holdable="true"]').size || 0;
+    IF ctx.place_unfillable ||
+        ( num_holdable_copies > 0
+            && (ctx.holds_block.enabled != 'true' || attrs.org_copy_counts.$search_ou.available == 0)
+        )
+%]
+                                                        <div class="results_aux_utils place_hold"><a
+                                                                href="[% mkurl(ctx.opac_root _ '/place_hold', 
+                                                                    {hold_target => rec.id, hold_type => 'T', hold_source_page => mkurl()}) %]" 
+                                                                    name="place_hold_link" class="no-dec"><img
+                                                                src="[% ctx.media_prefix %]/images/green_check.png"
+                                                                alt=""/><span class="result_place_hold">[% l('Place Hold') %]</span></a>
+                                                        </div>
+[%- END -%]
+                                                        <div class="results_aux_utils result_util">
+                                                            [%  IF ctx.user;
+                                                                INCLUDE "opac/parts/bookbag_actions.tt2";
+                                                            %]
+                                                            [%  ELSE;
+                                                                operation = ctx.mylist.grep(rec.id).size ? "delete" : "add";
+                                                                label = (operation == "add") ? l("Add to my list") : l("Remove from my list");
+                                                                href = mkurl(ctx.opac_root _ '/mylist/' _ operation, 
+                                                                        {record => rec.id, anchor => 'record_' _ rec.id}, 1);
+                                                            %]      
+                                                            <a href="[% href %]" class="no-dec">
+                                                                <img src="[% ctx.media_prefix %]/images/clipboard.png" alt="" />
+                                                                [% label %]
+                                                            </a>
+                                                            [% END %]
+                                                        </div>
+                                                        [% IF ENV.OILS_CONTENT_CAFE_USER %]
+                                                        <div class="results_aux_utils result_util">
+                                                            <a title="[% l('Reviews and More') %]" target='_blank' 
+                                                                href="[% ctx.ext_proto %]://contentcafe2.btol.com/ContentCafe/Jacket.aspx?UserID=[%- 
+                                                                    ENV.OILS_CONTENT_CAFE_USER %]&amp;Password=[%-
+                                                                    ENV.OILS_CONTENT_CAFE_PASS %]&amp;ItemKey=[% ident | uri %]&amp;Options=Y">
+                                                                <img src='[% ctx.media_prefix %]/images/starz.png'/> 
+                                                                <span class="results_reviews">[% l('Reviews &amp; More') %]</span>
+                                                            </a>
+                                                        </div>
+                                                        [% END %]
+                                                    </div>
+                                                </div>
+                                            </td>
+                                        </tr>
+                                        [%- IF ENV.OILS_CHILIFRESH_ACCOUNT %]
+                                        <tr>
+                                            <td/>
+                                            <td align='center'> <!-- Chilifresh reviews link --> 
+                                                <span class="chili_review" id="isbn_[% attrs.isbn_clean | html %]"> </span>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td/>
+                                            <td colspan='5'> <!-- Chilifresh reviews panel -->
+                                                <div id="chili_review_[% attrs.isbn_clean | html %]" style="display: none;" align="center"></div>
+                                            </td>
+                                        </tr>
+                                        [%- END %]
+                    [% END %]
+                    </tbody>
+                </table>
+            </div>
+</div>
+<div>
+    [% ctx.results_count_header %]
+</div>
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/topnav.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/topnav.tt2
new file mode 100644 (file)
index 0000000..7b335b9
--- /dev/null
@@ -0,0 +1,78 @@
+[%- IF ctx.maintenance_message -%]
+<div id="maintenance_message">[% ctx.maintenance_message %]</div>
+[%- END -%]
+[% IF !ctx.is_staff %]
+<div id="header-wrap">
+<div id="header">
+    <div class="float-left">
+        [% INCLUDE "opac/parts/topnav_logo.tt2" %]
+    </div>
+    <div class="float-left">
+        [% IF !ctx.user %]
+        <div id="your-acct-login">
+            <a href="[% mkurl(ctx.opac_root _ '/myopac/main') %]" 
+                class="opac-button opac-button-header" id="home_myopac_link">
+                [% l('Log into My Account') %]
+            </a>
+        </div>
+        [% ELSE %]
+        <div id="dash_wrapper">
+            <div id="dash_identity">
+                <span id="dash_user">
+                    [%  l('[_1] [_2]', ctx.user.first_given_name, ctx.user.family_name) | html %]
+                </span>
+                <span class="dash_divider">|</span>
+                <span class="dash_account_buttons">
+                <div id="dash_user_message_button_container">
+                    <a href="[% mkurl(ctx.opac_root _ '/myopac/messages', {}, ['single', 'message_id']) %]" class="opac-button">
+                        [% l('Messages') %]
+                    </a>
+                    [% IF ctx.user_stats.messages.unread %]
+                        <div id="unread_message_count_floater">
+                            [%- ctx.user_stats.messages.unread -%]
+                            <span class="sr-only">[% l('unread') %]</a>
+                        </div>
+                    [% END %]
+                </div>
+                <a href="[% mkurl(ctx.opac_root _ '/myopac/main', {}, ['single', 'message_id']) %]"
+                    class="opac-button">[% l('My Account') %]</a>
+                <a href="[% mkurl(ctx.opac_root _ '/myopac/lists', {}, ['single', 'message_id']) %]"
+                    class="opac-button">[% l('My Lists') %]</a>
+                <a href="[% mkurl(ctx.opac_root _ '/logout', {}, 1) %]"
+                    class="opac-button" id="logout_link">[% l('Logout') %]</a>
+                </span>
+            </div>
+            <div id="dashboard">
+                <span class="dash-align">
+                    <a class="dash-link" href="[% mkurl(ctx.opac_root _ '/myopac/circs', {}, ['limit','offset', 'single', 'message_id'])
+                        %]"><span id="dash_checked">[% ctx.user_stats.checkouts.total_out
+                        %]</span> [% l("Checked Out") %]</a>
+                </span>
+                <span class="dash_divider">|</span>
+                <span class="dash-align">
+                    <a class="dash-link" href="[% mkurl(ctx.opac_root _ '/myopac/holds', {}, ['available', 'single', 'message_id'])
+                        %]"><span id="dash_holds">[% ctx.user_stats.holds.total
+                        %]</span> [% l("On Hold") %]</a>
+                </span>
+                <span class="dash_divider">|</span>
+                <span class="dash-align">
+                    <a class="dash-link" href="[% mkurl(ctx.opac_root _ '/myopac/holds',
+                        {available => 1}, ['single', 'message_id']) %]"><span id="dash_pickup">[%
+                        ctx.user_stats.holds.ready %]</span> [% l("Ready for Pickup") %]</a>
+                </span>
+                <span class="dash_divider">|</span>
+                <span class="dash-align">
+                    <a class="dash-link" href="[% mkurl(ctx.opac_root _ '/myopac/main', {}, ['single', 'message_id'])
+                        %]"><span id="dash_fines">[% money(ctx.user_stats.fines.balance_owed)
+                        %]</span> [% l("Fines") %]</a>
+                </span>
+            </div>
+        </div>
+        [% END %]
+    </div>
+    [%- INCLUDE "opac/parts/locale_picker.tt2" %]
+    <div class="common-no-pad"></div>
+</div>
+</div>
+[% INCLUDE "opac/parts/topnav_links.tt2" %]
+[% END %]
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/topnav_links.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/topnav_links.tt2
new file mode 100644 (file)
index 0000000..6b94fe6
--- /dev/null
@@ -0,0 +1,11 @@
+<div id="gold-links-holder">
+    <div id="gold-links">
+<div id="header-links" class="float-none">
+<a href="http://www.cwmars.org/content/new-titles">See New Titles at your library</a>
+<a href="http://catalog.cwmars.org/eg/kpac/home">Kids Catalog</a>
+        </div>
+
+<!-- </style>  -->
+    </div>
+</div>
+
diff --git a/Open-ILS/src/cwopac_templates/opac/parts/topnav_logo.tt2 b/Open-ILS/src/cwopac_templates/opac/parts/topnav_logo.tt2
new file mode 100644 (file)
index 0000000..d56ab97
--- /dev/null
@@ -0,0 +1,3 @@
+<div id="topnav_logo"> <a href="/"><img alt="[% l('Evergreen Logo') %]" \r
+     src="[% ctx.media_prefix %]/opac/images/small_logo[% ENV.OILS_OPAC_LIBRARY_ID %].jpg" /></a></div>\r
+\r
diff --git a/Open-ILS/src/cwopac_templates/opac/password_reset.tt2 b/Open-ILS/src/cwopac_templates/opac/password_reset.tt2
new file mode 100644 (file)
index 0000000..17e58ac
--- /dev/null
@@ -0,0 +1,83 @@
+[%# The customizations in this file are primarily changes to the
+    default text messages displayed to the patron.
+    The INCLUDE for password_reset_msg.tt2 is also moved down.
+%]
+
+[%- PROCESS "opac/parts/header.tt2";
+    WRAPPER "opac/parts/base.tt2";
+    INCLUDE "opac/parts/topnav.tt2";
+    ctx.page_title = l('Library system password reset request form');
+-%]
+<h2 class="sr-only">[% l('Reset Password') %]</h2>
+<div class="mobile_hide">
+[% INCLUDE "opac/parts/searchbar.tt2" %]
+</div>
+
+[%  
+    uuid = ctx.page_args.0;
+    msg_map = {
+        SUCCESS => l('Password has been reset'),
+        NO_MATCH => l('Passwords did not match. Please try again'),
+        NOT_ACTIVE => l('This was not an active password reset request. Your password has not been reset.'),
+        NOT_STRONG => l('The password you chose was not considered complex enough to protect your account. Your password has not been reset.'),
+        TWO_PASSWORDS => l('Please enter and repeat your new password.'),
+        REQUEST_SUCCESS => l('Your barcode or user name has been submitted for a password reset. ' _ 
+            'If a matching account with an email address is found, you will soon receive an email at that address with further instructions for resetting your password.')
+    }
+%]
+<div id="content-wrapper">
+    <div id="main-content">
+        <br/>
+        <p class='[% ctx.pwreset.style %]'>[% stat = ctx.pwreset.status; msg_map.$stat %]</p>
+        [% IF uuid %]
+            [% IF stat == 'SUCCESS' %]
+                <p><a href='[% mkurl(ctx.opac_root _ '/myopac/main', {}, 1) %]'>[% l('Log in to My Account') %]</a>
+            [% ELSE %]
+            <form method="post">
+                <input type='hidden' name='uuid' value='[% uuid | html %]'/>
+                <table>
+                    <tr>
+                        <td><label for="pwd1">[% l('New password:') %]</label></td>
+                        <td><input type="password" name="pwd1"/></td>
+                    </tr>
+                    <tr>
+                        <td><label for="pwd2">[% l('Re-enter new password:') %]</label></td>
+                        <td><input type="password" name="pwd2"/></td>
+                    </tr>
+                    <tr>
+                        <td>
+                            <button name="submit" class="opac-button" id="submitButton" type="submit">[% l('Submit') %]</button>
+                        </td>
+                    </tr>
+                </table>
+            </form>
+            [% END %]
+        [% ELSIF !ctx.pwreset.status %]
+        <h2>[% l('Please enter your library card number <strong> OR</strong> user name to identify your library account and request a password reset') %]</h2>
+<!--        [%- INCLUDE "opac/password_reset_msg.tt2" %] -->
+        <form method="post">
+            <table>
+                <tr>
+                    <td><label for="barcode">[% l('Library Card Number:') %] </label></td>
+                    <td><input type="text" id="barcode" name="barcode"/></td>
+                </tr>
+                <tr>
+                    <td colspan="2"><strong>OR</strong></td>
+                <tr>
+                    <td><label for="username">[% l('User name:') %] </label></td>
+                    <td><input type="text" id="username" name="username"/></td>
+                </tr>
+                <tr>
+                    <td colspan="2">Enter one <strong>or</strong> the other. You do not need both.</td>
+                </tr>
+            </table>
+            [% IF ctx.get_org_setting(ctx.physical_loc || ctx.aou_tree.id, 'circ.password_reset_request_requires_matching_email') %]
+            <label for="email">[% l('Email address associated with the account:') %] </label><input type="text" name="email"/><br/>
+            [% END %]
+            <button name="submit" id="submitButton" class="opac-button" type="submit">[% l('Submit') %]</button>
+        </form>
+        [% INCLUDE "opac/password_reset_msg.tt2" %]
+        [% END %]
+    </div>
+</div>
+[%- END %]
diff --git a/Open-ILS/src/cwopac_templates/opac/password_reset_msg.tt2 b/Open-ILS/src/cwopac_templates/opac/password_reset_msg.tt2
new file mode 100644 (file)
index 0000000..5ca2bf0
--- /dev/null
@@ -0,0 +1,7 @@
+[%# The customization in this file is only a change to
+    the default text message.
+%]
+
+<div class="password_message">
+[% l('Note: You must have a valid email address associated with your library account. If not, you will not receive the email to reset your password.<br />If you have any additional questions, please contact your local library for further assistance.'); %]
+</div>