TPAC: Alternate graphic fields (880) display
authorDan Scott <dan@coffeecode.net>
Fri, 4 Jan 2013 21:26:30 +0000 (16:26 -0500)
committerBen Shum <bshum@biblio.org>
Sat, 19 Jan 2013 21:09:57 +0000 (16:09 -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 c188e97..9e2a054 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 448fdf8..b52aea3 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 = subfield.textContent | html;
             term = term _ ' ' _ sf;
@@ -52,7 +58,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 e92644d..9a1cf50 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 a5767a1..b705574 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 d53c8f2..e0f3f2a 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 %]