Add microdata for holdings via http://schema.org/Offer
authorDan Scott <dscott@laurentian.ca>
Tue, 9 Jul 2013 16:30:31 +0000 (12:30 -0400)
committerDan Scott <dscott@laurentian.ca>
Mon, 19 Aug 2013 14:36:04 +0000 (10:36 -0400)
Map library name to Offer/seller, shelving location to
Offer/availableAtOrFrom, call number to Offer/sku, barcode to
Offer/serialNumber, copy status to Offer/availability, and ISBN-13 to
gtin13. Use the additionalType of Product to give these offers an
obvious relationship.

Surface copy counts as AggregateOffer instances.

Signed-off-by: Dan Scott <dscott@laurentian.ca>
Open-ILS/src/perlmods/lib/OpenILS/Application/AppUtils.pm
Open-ILS/src/templates/opac/parts/misc_util.tt2
Open-ILS/src/templates/opac/parts/record/body.tt2
Open-ILS/src/templates/opac/parts/record/copy_counts.tt2
Open-ILS/src/templates/opac/parts/record/copy_table.tt2
Open-ILS/src/templates/opac/parts/record/summary.tt2

index 92f1daf..5c5074e 100644 (file)
@@ -1961,6 +1961,7 @@ sub basic_opac_copy_query {
                 {column => 'holdable', alias => 'location_holdable'}
             ],
             ccs => [
+                {column => 'id', alias => 'status_code'},
                 {column => 'name', alias => 'copy_status'},
                 {column => 'holdable', alias => 'status_holdable'}
             ],
index 5c18d60..697403a 100644 (file)
 
         # 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 = [];
                         location => loc.textContent,
                         library => circlib.textContent,
                         status => status.textContent,
+                        status_code => status.getAttribute('ident'),
                         barcode => copy.getAttribute('barcode'),
                         owner => volume.getAttribute('lib')
                     };
index 2e74d66..d334acc 100644 (file)
@@ -5,6 +5,7 @@
     ctx.record_attrs = attrs; # capture for JS
 %]
 <div id='canvas_main' class='canvas' itemscope itemtype='[% args.schema.itemtype %]'>
+    <link itemprop="additionalType" href="http://schema.org/Product" />
     [%- INCLUDE "opac/parts/record/navigation.tt2" %]
     [%- IF ctx.bib_is_dead %]
     <div id='rdetail_deleted_exp'>
index a400aad..e2a865a 100644 (file)
@@ -17,7 +17,9 @@
             ou_name = cp_org_unit.name;
             displayed_ous.$ou_name = 1;
     %]
-    <li>
+    <li itemprop="offers" itemscope itemtype="http://schema.org/AggregateOffer">
+        <meta itemprop="offerCount" content="[% ou_avail %]">
+        <meta itemprop="seller" content="[% ou_name | html %]">
     [% l('[quant,_1,copy,copies] at [_2].', ou_avail, ou_name) | html %]
     [%- this_depth = ctx.get_aou(ou_id).ou_type.depth;
         IF ou_avail > 0 && this_depth != ctx.copy_depth %]
         UNLESS depth < 0 || displayed_ous.exists(ou_name);
     %]
     [%- IF attrs.plib_copy_counts.$depth.count > 0; %]
-    <li class="preferred">[%
+    <li class="preferred" itemprop="offers" itemscope itemtype="http://schema.org/AggregateOffer">
+        <meta itemprop="offerCount" content="[% ou_avail %]">
+        <meta itemprop="seller" content="[% ou_name | html %]">
+    [%-
         l('[_1] of [quant,_2,copy,copies] available at [_3].',
             attrs.plib_copy_counts.$depth.available,
             attrs.plib_copy_counts.$depth.count,
index 9a71bce..be2ebec 100644 (file)
@@ -67,11 +67,11 @@ END;
                 callnum = callnum  _ " " _ callnum_suffix;
             END;
         -%]
-        <tr>
+        <tr itemprop="offers" itemscope itemtype="http://schema.org/Offer">
             [%- IF serial_holdings %]<td header='copy_header_holding_label' class='rdetail-issue-issue'>
                 [%- copy_info.holding_label | html; -%]
             </td>
-            [%- ELSE %]<td header='copy_header_library'>
+            [%- ELSE %]<td header='copy_header_library' itemprop="seller">
             [%-
                 org_name = ctx.get_aou(copy_info.circ_lib).name;
                 lib_url = ctx.get_org_setting(copy_info.circ_lib, 'lib.info_url');
@@ -80,16 +80,20 @@ END;
                 IF lib_url; '</a>'; END;
             -%]
             </td>[% END %]
-            <td header='copy_header_callnumber'>[% callnum | html %] [% 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 header='copy_header_callnumber'><span itemprop="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}) %]">Text</a>)[% END %]</td>
             [%- IF has_parts == 'true' %]
             <td header='copy_header_part'>[% copy_info.part_label | html %]</td>
             [%- END %]
-            <td header='copy_header_barcode'>
+            <td header='copy_header_barcode' itemprop="serialNumber">
                 [%- IF ctx.is_staff -%]
                     <a href="javascript:void(0)" onclick="xulG.new_tab(xulG.urls.XUL_COPY_STATUS, {}, {'from_item_details_new': true, 'barcodes': ['[%- copy_info.barcode | html | replace('\'', '\\\'') -%]']})">[% copy_info.barcode | html %]</a>
                 [%- ELSE -%][% copy_info.barcode | html %]
-                [%- END -%]</td>
-            <td header='copy_header_shelfloc'>[% copy_info.copy_location | html %]</td>
+                [%- END -%]
+                [%- IF attrs.gtin13;
+                    '<meta itemprop="gtin13" content="' _ attrs.gtin13 _ '" />';
+                END; -%]
+            </td>
+            <td header='copy_header_shelfloc' itemprop="availableAtOrFrom">[% copy_info.copy_location | html %]</td>
             [%- IF ctx.is_staff %]
             <td header='copy_header_age_hold'>
                 [% copy_info.age_protect ?
@@ -149,7 +153,19 @@ END;
                     l("Not holdable");
                 END %]</td>
             [%- END %]
-            <td header='copy_header_status'>[% copy_info.copy_status | html %]</td>
+            <td header='copy_header_status'>[%-
+                # Hard-coded to match defaults in config.copy_status
+                IF (copy_info.status_code == 0 OR copy_info.status_code == 7);
+                    '<link itemprop="availability" href="http://schema.org/InStock" />';
+                ELSIF copy_info.status_code == 1;
+                    '<link itemprop="availability" href="http://schema.org/OutOfStock" />';
+                ELSIF copy_info.status_code == 9;
+                    '<link itemprop="availability" href="http://schema.org/PreOrder" />';
+                ELSIF copy_info.status_code == 12;
+                    '<link itemprop="availability" href="http://schema.org/InStoreOnly" />';
+                END;
+                copy_info.copy_status | html;
+            -%]</td>
             <td header='due_date'>[%
                 IF copy_info.due_date;
                     date.format(
index a38bd54..db3f4ca 100644 (file)
@@ -108,8 +108,14 @@ IF num_uris > 0;
 <div class="rdetail_uris">
     [%- IF num_uris > 1 %]<ul>[% END %]
     [%- FOR uri IN merged_uris %]
-        [%- IF num_uris == 1 %]<p class="rdetail_uri">[% ELSE %]<li class="rdetail_uri">[% END %]
+        [%- IF num_uris == 1 -%]
+            <p class="rdetail_uri" itemprop="offers" itemscope itemtype="http://schema.org/Offer">
+        [%- ELSE -%]
+            <li class="rdetail_uri" itemprop="offers" itemscope itemtype="http://schema.org/Offer">
+        [%- END -%]
         <a href="[% uri.href %]">[% uri.link %]</a>[% ' - ' _ uri.note IF uri.note %]
+        <link itemprop="availability" href="http://schema.org/OnlineOnly" />
+        [%- IF attrs.gtin13; '<meta itemprop="gtin13" content="' _ attrs.gtin13 _ '" />'; END; %]
         [%- IF num_uris == 1 %]</p>[% ELSE %]</li>[% END %]
     [%- END %]
     [%- IF num_uris > 1 %]</ul>[% END %]