]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/templates/opac/parts/misc_util.tt2
Merge branch 'master' of git.evergreen-ils.org:Evergreen-DocBook into doc_consolidati...
[working/Evergreen.git] / Open-ILS / src / templates / opac / parts / misc_util.tt2
1 [% 
2     # Extract MARC fields from XML
3     #   get_marc_attrs( { marc_xml => doc } )
4     BLOCK get_marc_attrs;
5         xml = args.marc_xml;
6
7         # Map item types to schema.org types; impedance mismatch :(
8         args.schema.itemtype = {};
9         schema_typemap = {};
10         schema_typemap.a = 'http://schema.org/Book';
11         schema_typemap.j = 'http://schema.org/MusicRecording';
12
13         args.isbns = [];
14         FOR isbn IN xml.findnodes('//*[@tag="020"]/*[@code="a"]');
15             args.isbns.push(isbn.textContent);
16         END;
17         args.upcs = [];
18         FOR upc IN xml.findnodes('//*[@tag="024"]/*[@code="a"]');
19             args.upcs.push(upc.textContent);
20         END;
21         args.upc = args.upcs.0; # use first UPC as the default
22         args.issn = xml.findnodes('//*[@tag="022"]/*[@code="a"]').textContent;
23         args.author = xml.findnodes('//*[@tag="100"]/*[@code="a"]').textContent;
24
25         # Include subfields 'abnp' to generate a more comprehensive title display in search results
26         titresults = xml.findnodes('//*[@tag="245"]/*[@code="a" or @code="b" or @code="n" or @code="p"]');
27         titresults_content = [];
28             FOR sub IN titresults; titresults_content.push(sub.textContent); END;
29         args.title = titresults_content.join(" ");
30         # Avoid ugly trailing syntax on brief titles
31         args.title = args.title | replace('[:;/]$', '');
32
33         # Provide correct spacing between the subfields
34         titsubs = xml.findnodes('//*[@tag="245"]/*[@code]');
35         titsubs_content = [];
36             FOR sub IN titsubs; titsubs_content.push(sub.textContent); END;
37         args.title_extended = titsubs_content.join(" ");
38
39         args.publisher = xml.findnodes('//*[@tag="260"]/*[@code="b"]').textContent;
40         args.pubdate = xml.findnodes('//*[@tag="260"]/*[@code="c"]').textContent;
41         args.summary = xml.findnodes('//*[@tag="520"]/*[@code="a"]').textContent;
42         args.edition = xml.findnodes('//*[@tag="250"]/*[@code="a"]').textContent ||
43             xml.findnodes('//*[@tag="534"]/*[@code="b"]').textContent ||
44             xml.findnodes('//*[@tag="775"]/*[@code="b"]').textContent;
45         phys = xml.findnodes(
46             '//*[@tag="300"]/*[@code="a" or @code="b" or @code="c" or @code="e"]'
47         );
48         phys_content = [];
49         FOR p IN phys; phys_content.push(p.textContent); END;
50         args.phys_desc = phys_content.join("");
51
52         args.contents = xml.findnodes('//*[@tag="505"]').textContent;
53
54         # MARC Callnumber
55         args.marc_cn = xml.findnodes('//*[@tag="092" or @tag="099"]/*').textContent;
56
57         # clean up the ISBN
58         args.isbn_clean = args.isbns.0.replace('\ .*', '');
59
60         # Extract the 856 URLs that are not otherwise represented by asset.uri's
61         args.online_res = [];
62         FOR node IN xml.findnodes('//*[@tag="856" and @ind1="4" and (@ind2="0" or @ind2="1")]');
63             IF node.findnodes('./*[@code="9" or @code="w" or @code="n"]'); NEXT; END; # asset.uri's
64             label = node.findnodes('./*[@code="y"]');
65             notes = node.findnodes('./*[@code="z" or @code="3"]');
66             FOR href IN node.findnodes('./*[@code="u"]');
67                 NEXT UNLESS href;
68                 # it's possible for multiple $u's to exist within 1 856 tag.
69                 # in that case, honor the label/notes data for the first $u, but
70                 # leave any subsequent $u's as unadorned href's. 
71                 # use href/link/note keys to be consistent with args.uri's
72                 args.online_res.push({
73                     href => href.textContent, 
74                     link => (loop.first AND label) ? label.textContent : href.textContent,
75                     note => (loop.first) ? notes.textContent : ''
76                 });
77             END;
78         END;
79  
80         args.holdings = [];
81         args.uris = [];
82         args.issns = [];
83         args.resolver_isbns = [];
84         args.resolver_issns = [];
85
86         # we use $9 of ISBN and ISSN as a flag for e-version
87         FOR resolver_isbn IN xml.findnodes('//*[@tag="020"]/*[@code="9"]');
88             IF resolver_isbn.textContent == "SFX" || resolver_isbn.textContent == "CUFTS";
89                 my_parent = resolver_isbn.parentNode();
90                 FOR resolver_isbn_val IN my_parent.findnodes('./*[@code="a"]');
91                     args.resolver_isbns.push(
92                         resolver_isbn_val.textContent.replace('-', '').replace('\ .*', '')
93                     );
94                 END;
95             END;
96         END;
97
98         FOR resolver_issn IN xml.findnodes('//*[@tag="022"]/*[@code="9"]');
99             IF resolver_issn.textContent == "SFX" || resolver_issn.textContent == "CUFTS";
100                 my_parent = resolver_issn.parentNode();
101                 FOR resolver_issn_val IN my_parent.findnodes('./*[@code="a"]');
102                     args.resolver_issns.push(
103                         resolver_issn_val.textContent.replace('[^\d\-X]', '')
104                     );
105                 END;
106             END;
107         END;
108
109         # now snag all issns 
110         FOR rawissn IN xml.findnodes('//*[@tag="022"]/*[@code="a"]');
111             args.issns.push(
112                 rawissn.textContent.replace('[^\d\-X]', '')
113             );
114         END;
115
116         FOR volume IN xml.findnodes('//*[local-name()="volumes"]/*[local-name()="volume"]');
117
118             # Check volume visibility - could push this into XPath
119             vol.label = volume.getAttribute('label');
120
121             # Prepend prefix, if any
122             prefix = volume.findnodes('./*[local-name()="call_number_prefix"][@ident!="-1"]');
123             IF prefix.getAttribute('label') != '';
124                 vol.label = prefix.getAttribute('label') _ " " _ vol.label;
125             END;
126
127             # Append prefix, if any
128             suffix = volume.findnodes('./*[local-name()="call_number_suffix"][@ident!="-1"]');
129             IF suffix.getAttribute('label') != '';
130                 vol.label = vol.label _ " " _ suffix.getAttribute('label');
131             END;
132
133             vol.id = volume.getAttribute('id');
134             NEXT IF volume.getAttribute('opac_visible') == 'false';
135             NEXT IF volume.getAttribute('deleted') == 'true';
136
137             IF vol.label == '##URI##';
138                 FOR uri IN volume.findnodes('./*[local-name()="uris"]/*[local-name()="uri"]');
139                     res = {};
140                     res.href = uri.getAttribute('href');
141                     res.link = uri.getAttribute('label');
142                     res.note = uri.getAttribute('use_restriction');
143                     args.uris.push(res);
144                 END;
145                 NEXT;
146             ELSE;
147                 copies = volume.findnodes('./*[local-name()="copies"]/*[local-name()="copy"]');
148                 FOR copy IN copies;
149                     parts = copy.findnodes('./*[local-name()="monograph_parts"]/*[local-name()="monograph_part"]');
150                     FOREACH part IN parts;
151                         part_label = part.getAttribute('label');
152                         LAST IF part_label != '';
153                     END;
154                     # Check copy visibility
155                     cp.deleted = copy.getAttribute('deleted');    
156                     cp.visible = copy.getAttribute('opac_visible');
157                     NEXT IF (cp.deleted == 'true' OR cp.visible == 'false');
158
159                     # Iterate through all of the children to determine visibility
160                     FOR node IN cp.childNodes;
161                         NEXT IF cp.visible == 'false';
162                         vis = node.getAttribute('opac_visible');
163                         del = node.getAttribute('deleted');
164                         IF vis == 'false' or del == 'true';
165                             cp.visible = 'false';
166                         END;
167                     END;
168
169                     NEXT IF cp.visible == 'false';
170                     
171                     loc = copy.findnodes('./*[local-name()="location"]');
172                     circlib = copy.findnodes('./*[local-name()="circlib"]');
173                     status = copy.findnodes('./*[local-name()="status"]');
174
175                     holding = {
176                         label => vol.label,
177                         part_label => part_label,
178                         location => loc.textContent,
179                         library => circlib.textContent,
180                         status => status.textContent
181                         barcode => copy.getAttribute('barcode')
182                     };
183                     args.holdings.push(holding);
184                     part_label = '';
185                 END;
186             END;
187         END;
188
189         # Extract the copy count summary
190         count_type = (ctx.is_staff) ? 'staff' : 'public';
191
192         # Consortial copy count summary first
193         xpath = '//*[local-name()="counts"]/*[local-name()="count"][@type="' _ count_type _ '"]';
194         args.copy_counts = {};
195         FOR node IN xml.findnodes(xpath);
196             FOR attr IN ['count', 'available', 'unshadow', 'transcendant', 'org_unit']; 
197                 depth = node.getAttribute('depth');
198                 args.copy_counts.$depth.$attr = node.getAttribute(attr);
199             END;
200         END;
201         
202         # Get preferred library copy count
203         args.plib_copy_counts = {};
204         count_type = 'pref_lib';
205         xpath = '//*[local-name()="counts"]/*[local-name()="count"][@type="' _ count_type _ '"]';
206         FOR node IN xml.findnodes(xpath);
207             FOR attr IN ['count', 'available', 'unshadow', 'transcendant', 'org_unit']; 
208                 depth = node.getAttribute('depth');
209                 args.plib_copy_counts.$depth.$attr = node.getAttribute(attr);
210             END;
211         END;
212
213         # "mattype" == "custom marc format specifier"
214         FOR icon_style IN ['mattype', 'item_type']; 
215             node = xml.findnodes(
216                 '//*[local-name()="attributes"]/*[local-name()="field"][@name="' _ icon_style _ '"]');
217             IF node AND node.textContent;
218                 type = node.textContent;
219                 args.format_label = node.getAttribute('coded-value')
220                 args.schema.itemtype = schema_typemap.$type;
221                 args.format_icon = ctx.media_prefix _ '/images/format_icons/' _ icon_style _ '/' _ type _ '.png';
222                 LAST;
223             END;
224         END;
225
226     END;
227 %]