TPAC: Alternate graphic fields (880) display
authorDan Scott <dan@coffeecode.net>
Fri, 4 Jan 2013 21:26:30 +0000 (16:26 -0500)
committerDan Scott <dscott@laurentian.ca>
Wed, 23 Jan 2013 05:25:27 +0000 (00:25 -0500)
In the search results and record details displays, display the
corresponding 880 field(s) whenever possible.

The contents of the 880 field are generally displayed directly
underneath the corresponding primary field, with the exception of the
contributor credits on the record details page, in which the 880
contents appear between the name of the contributor and the
contributor's credit.

Signed-off-by: Dan Scott <dan@coffeecode.net>
Signed-off-by: Kathy Lussier <klussier@masslnc.org>
Signed-off-by: Ben Shum <bshum@biblio.org>
Open-ILS/src/templates/opac/parts/misc_util.tt2
Open-ILS/src/templates/opac/parts/record/authors.tt2
Open-ILS/src/templates/opac/parts/record/contents.tt2
Open-ILS/src/templates/opac/parts/record/subjects.tt2
Open-ILS/src/templates/opac/parts/record/summary.tt2
Open-ILS/src/templates/opac/parts/result/table.tt2

index 45d3f54..36fa33e 100644 (file)
@@ -1,4 +1,84 @@
 [% 
+    # 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 5 6 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;
+
     # Extract MARC fields from XML
     #   get_marc_attrs( { marc_xml => doc } )
     BLOCK get_marc_attrs;
         END;
         args.issn = (args.issns.size) ? args.issn.0 : '';
 
+        graphic_880s = [];
+        get_graphic_880s(target_field='100');
+        args.graphic_authors = graphic_880s;
         args.authors = [];
-        FOR sub IN xml.findnodes('//*[@tag="100"]/*[@code="a"]');
-            args.authors.push(sub.textContent);
+        FOR author IN args.graphic_authors;
+            args.authors.push(author.primary.value);
         END;
         args.author = (args.authors.size) ? args.authors.0 : '';
 
         # Avoid ugly trailing syntax on brief titles
         args.title = args.title | replace('[:;/]$', '');
 
-        # Provide correct spacing between the subfields
-        titsubs = xml.findnodes('//*[@tag="245"]/*[@code]');
-        titsubs_content = [];
-            FOR sub IN titsubs; titsubs_content.push(sub.textContent); END;
-        args.title_extended = titsubs_content.join(" ");
+        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 = [];
         FOR sub IN xml.findnodes('//*[@tag="260"]/*[@code="a"]');
         # Full publisher info
         args.pubinfo = "$args.pubplace $args.publisher $args.pubdate";
 
+        graphic_880s = [];
+        get_graphic_880s(target_field='260');
+        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 : '';
 
+        # 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"]');
         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;
-        args.contents = args.contents_list.join(" ");
-        args.content = (args.contents.size) ? args.contents.0 : '';
 
         # MARC Callnumber
         args.marc_cns = [];
         loc_name = 'locg';
         loc_value = CGI.param(loc_name) || CGI.param('loc') || ctx.search_ou;
     END;
+
 %]
index bc61e48..7e223fb 100644 (file)
@@ -28,6 +28,7 @@ BLOCK build_author_links;
         qterm = '';
         iprop = '';
         tlabel = '';
+        graphics = [];
         FOR subfield IN node.childNodes;
             NEXT UNLESS subfield.nodeName == "subfield";
             code = subfield.getAttribute('code');
@@ -35,6 +36,11 @@ BLOCK build_author_links;
                 relcode = subfield.textContent.substr(0,3);
                 tlabel = relators.$relcode || label;
             END;
+            IF code == '6';
+               linked_fields = [subfield.textContent()];
+               target_field = node.getAttribute('tag');
+               get_linked_880s;
+            END;
             NEXT UNLESS code.match('[a-z]');
             sf_raw = subfield.textContent;
             sf = subfield.textContent | html;
@@ -50,7 +56,17 @@ BLOCK build_author_links;
         ELSIF type == 'added';
             iprop = ' itemprop="contributor"';
         END;
-        '<a href="' _ url _ '"' _ iprop _ '>' _ term.replace('^\s+', '') _ '</a> (' _ author_type _ '). ';
+        '<a href="' _ url _ '"' _ iprop _ '>' _ term.replace('^\s+', '') _ '</a>';
+        FOREACH link880 IN graphics;
+            diratt = '';
+            IF link880.dir;
+                diratt = ' dir="' _ link880.dir _ '"';
+            END;
+            ' <span class="graphic880"' _ diratt _ '>';
+            link880.value | html;
+            '</span>';
+        END;
+        ' (' _ author_type _ '). ';
     END;
 END;
 %]
index 1fb0eb5..fcf9e54 100644 (file)
@@ -157,15 +157,26 @@ 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;
         IF total_contents.size; "<br/>"; END;
+        FOREACH link880 IN graphics;
+            '<div class="graphic880"' _ link880.dir _ '>';
+            link880.value | html;
+            '</div>';
+        END;
     END;
 END 
 %]
index 52d9ac8..2ecd5ed 100644 (file)
         xpath = xpath || '//*[starts-with(@tag,"6")]';
         FOR node IN ctx.marc_xml.findnodes(xpath);
             all_terms = [];
+            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]');
                 IF code.match('[vxyz]'); " &gt; "; END;
                 # at this point, we actually have a partial term to use.
 <a href="[% mkurl(ctx.opac_root _ '/results', {qtype=>'subject', query=>total_term}, stop_parms); %]">[% single_term %]</a>
             [%- END;
             IF all_terms.size; "<br/>"; END;
+            FOREACH link880 IN graphics;
+                '<div class="graphic880"' _ link880.dir _ '>';
+                link880.value | html;
+                '</div>';
+            END;
         END;
     END 
 %]
index 62432ee..bf68f4a 100644 (file)
         </div>
         [%- END %]
         <h1 id='rdetail_title' itemprop="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>
@@ -146,6 +157,21 @@ IF num_uris > 0;
     <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.publisher %]
@@ -160,6 +186,23 @@ IF num_uris > 0;
         [%- IF attrs.pubdate; %]
             <span itemprop="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 %]
 </ul>
index 93e2e3d..29b9c56 100644 (file)
                                                         [% 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") %]"
                                                                         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">
                                                                 <td valign="top">
                                                                     <strong>[% l('Publisher:') %]</strong>
                                                                 </td>
-                                                                <td>[% attrs.pubinfo | html %]</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.isbns.size > 0 %]
                                                                 <td valign="top">
                                                                     <strong>[% l('Edition:') %]</strong>
                                                                 </td>
-                                                                <td>[% attrs.edition | html %]</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 %]