Last active
April 14, 2020 18:58
-
-
Save SummittDweller/de551b7583bf7022401e8b4a5320a201 to your computer and use it in GitHub Desktop.
File copy of the Twig template (Rev 17) from Digital_Grinnell_MODS_Master, a Google Sheet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
{# Digital_Grinnell_MODS_Master.twig Revision 17 | |
A copy of this file lives as a Gist at https://gist.github.com/SummittDweller/de551b7583bf7022401e8b4a5320a201 | |
This TWIG template for IMI import is intended to serve as a general-purpose | |
starting point for MODS import into Digital Grinnell. | |
The canonical copy of this Twig is part of a 4-tab Google Sheet named | |
Digital_Grinnell_MODS_Master. Its address is: https://docs.google.com/spreadsheets/d/1G_pQgKJwtgBZYDAHcMC7dCTOnwexIYGHjarHPFKaAOg | |
History -------------------- | |
Rev 17 | |
Significant changes include addition of Table_of_Contents, addition of ~AuthorityURI to some fields, and reorder of MASTER columns and Twig to better match module dg7's 'cleanup_mods_and_reorder.xslt' display order. | |
Rev 16 | |
Changed "Genre" column to "Genre~AuthorityURI" with default authority set to https://www.loc.gov/standards/valuelist/marcgt.html. Changed all 'isPartOf' references to 'host'. | |
Rev 15 | |
Added the Primary_Sort and Handle columns | |
Rev 14 | |
Added TRANSCRIPT and THUMBNAIL control columns from Oral Histories. Updating hook_form_islandora_multi_importer_form_alter() in dg7.module to match. | |
Rev 13 | |
Corrected "Private" note handling...now generates /mods/extension/note; added specific Citations (generates note[@type='citation']) column. | |
Rev 12 | |
Added Notes~Display_Label => note[@type='content'] to accomodate content notes with greater flexibility. | |
Rev 11 | |
Added Dates_As_Notes => note[@type='creation/production credits'] fields for non-discrete or otherwise invalid 'dates'. | |
Rev 10 | |
Changed semi-automatic imi_import_source_tracking to simple column heading of import_source. | |
Rev 9.1 | |
No structural changes. Multiple tabs eliminated by placing EVERYTHING in Column A with spaces for indent. | |
Rev 9.0 | |
Changed import_index and import_source behavior to use IMI's new imi_import_source_tracking feature and field | |
Rev. 8 | |
Corrected <physicalDescription> logic and indentation | |
Rev. 7 | |
Added the Import_Source column intended to store the URL of the worksheet (Google Sheet) the data was imported from. | |
Rev. 6 | |
Corrected primarySort to default value of 99 (was 1) | |
Rev. 5.1 | |
Sync DGAdmin where the Rev. 4 sheet was incorrectly identified as 5 | |
Rev. 5 | |
Added /mods/extension/hidden_creator support | |
Rev. 4 | |
Added Pull_Quotes column processing to create a /mods/extension/pull_quotes field. | |
Rev. 3 | |
Removed capitalization on default 'Creator' roleTerm, and removed the <dg_creators> element entirely. | |
Rev. 2 | |
Added ~Display_Label to the Other_Date field, '|trim' to all of the originInfo fields, and | |
if name is not null and name|trim is not empty' to all multi-value fields. | |
Rev. 1 | |
Initial MASTER saved on 28-July-2017 | |
Derived from CoC.twig | |
IMI twig template created for ingest of PHPP - Chamber of Commerce objects. MM 24-July-2017 | |
Derived from dg_base_mods_template.twig | |
Created 1-May-2017 from base_mods_template.twig that shipped with the IMI module. | |
Note that the order of MODS elements here is significant. It is the same order that our --reorder | |
self-transform produces. | |
-Mark M. | |
Use ---------------------------------------------- | |
This TWIG generally supports four field syntaxes… | |
value …for simple single-valued fields. The header on this field should be singular. | |
value~attr …for a single-valued field with an optional attribute. The header on this field should be singular but include a ‘~something’ suffix. | |
value1 | value2 | value3 …for simple multi-valued fields. The header on this field should be plural to indicate that it can be multivalued. | |
value1~attr1 | value2 | value3~attr3 …for multi-valued fields with attribute possibilities. This needs a plural header with a ‘~something’ suffix. | |
In the 2nd and 4th syntaxes a value may exist without an attribute, like ‘value2’ in the | |
line above. When no ~attribute is present a default will be assumed and that | |
default is defined in the Twig file. The default varies from field-to-field. | |
An example… | |
Personal_Names~Roles | |
—————————————————————————————————————— | |
Doe, Jane | Doe, John ~ spouse | Kong, King ~ gorilla | |
In the above example ‘Jane Doe’ would be identified as the ‘Creator’, since that | |
is the default personal name role in our Twig template. ‘John Doe’ and ‘King Kong’ | |
would be identified as contributors with roles of ‘spouse’ and ‘gorilla’, | |
respectively. The MODS from this field would look like this... | |
<name type=‘personal’> | |
<namePart>Doe, Jane</namePart> | |
<role> | |
<roleTerm type=‘text'>creator</roleTerm> | |
</role> | |
</name> | |
<name type=‘personal’> | |
<namePart>Doe, John</namePart> | |
<role> | |
<roleTerm type=‘text’>spouse</roleTerm> | |
</role> | |
</name> | |
<name type=‘personal’> | |
<namePart>Kong, King</namePart> | |
<role> | |
<roleTerm type=‘text’>gorilla</roleTerm> | |
</role> | |
</name> | |
-------------------------------------------------------- | |
The corresponding worksheet headers should be ordered and read like this... | |
PID, WORKSPACE, Import_Index, PARENT, CMODEL, SEQUENCE, OBJ, Title, | |
Alternative_Titles, Personal_Names~Roles, Corporate_Names~Roles, Abstract, | |
Index_Date, Date_Issued, Date_Captured, Other_Date~Display_Label, Publisher, | |
Place_Of_Publication, Public_Notes~Types, Notes~Display_Label, Dates_as_Notes~Display_Label, Citations, Table_of_Contents, | |
LCSH_Subjects, Subjects_Names~Types, Subjects_Geographic, Subjects_Temporal, Keywords, | |
Coordinate, Related_Items~Types, Type_of_Resource~AuthorityURI, Genre~AuthorityURI, Extent, Form~AuthorityURI, MIME_Type, Digital_Origin, | |
Classifications~Authorities, Language_Names~Codes, Local_Identifier, Handle, Physical_Location, Shelf_Locator, Access_Condition | |
Import_Source, Primary_Sort, Hidden_Creator, Pull_Quotes, Private_Notes~Types | |
#} | |
{% block content %} | |
{% autoescape false %} | |
<mods xmlns="http://www.loc.gov/mods/v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:mods="http://www.loc.gov/mods/v3" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-4.xsd"> | |
{# Title #} | |
<titleInfo> | |
<title>{{ data.title }}</title> | |
</titleInfo> | |
{# Alternative_Titles #} | |
{% if attribute(data, 'alternative_titles') %} | |
<titleInfo type='alternative'> | |
{% for title in attribute(data, 'alternative_titles')|split('|') %} | |
<title>{{ title|trim }}</title> | |
{% endfor %} | |
</titleInfo> | |
{% endif %} | |
{# Personal_Names~Roles #} | |
{# Creator/Contributor personal names logic of the form name1~role1|name2~role2|name3|name4~role4 #} | |
{# Note that when role is omitted, like name3 above, 'Creator' is assumed #} | |
{% if attribute(data, 'personal_names~roles') %} | |
{% for name in attribute(data, 'personal_names~roles')|split('|') %} | |
{% if name is not null and name|trim is not empty %} | |
<name type="personal"> | |
{% if '~' in name %} | |
{% set pcc_parts = name|split('~',2) %} | |
<namePart>{{ pcc_parts[0]|trim }}</namePart> | |
<role> | |
<roleTerm type="text">{{ pcc_parts[1]|trim }}</roleTerm> | |
</role> | |
{% else %} | |
<namePart>{{ name|trim }}</namePart> | |
<role> | |
<roleTerm type="text">creator</roleTerm> | |
</role> | |
{% endif %} | |
</name> | |
{% endif %} | |
{% endfor %} | |
{% endif %} | |
{# Corporate_Names~Roles #} | |
{# Creator/Contributor corporate names logic of the form name1~role1|name2~role2|name3|name4~role4 #} | |
{# Note that when role is omitted, like name3 above, 'Creator' is assumed #} | |
{% if attribute(data, 'corporate_names~roles') %} | |
{% for name in attribute(data, 'corporate_names~roles')|split('|') %} | |
{% if name is not null and name|trim is not empty %} | |
<name type="corporate"> | |
{% if '~' in name %} | |
{% set ccc_parts = name|split('~',2) %} | |
<namePart>{{ ccc_parts[0]|trim }}</namePart> | |
<role> | |
<roleTerm type="text">{{ ccc_parts[1]|trim }}</roleTerm> | |
</role> | |
{% else %} | |
<namePart>{{ name|trim }}</namePart> | |
<role> | |
<roleTerm type="text">creator</roleTerm> | |
</role> | |
{% endif %} | |
</name> | |
{% endif %} | |
{% endfor %} | |
{% endif %} | |
{# Abstract #} | |
<abstract>{{ data.abstract }}</abstract> | |
{# Index_Date, Date_Issued, Date_Captured, Other_Date~Display_Label, Publisher, Place_Of_Publication #} | |
{% if attribute(data, 'index_date') or attribute(data, 'other_date~display_label') or attribute(data, 'date_issued') or attribute(data, 'publisher') or attribute(data, 'place_of_publication') or attribute(data, 'date_captured') %} | |
<originInfo> | |
{% if attribute(data, 'index_date') %} | |
<dateCreated>{{ data.index_date|trim }}</dateCreated> | |
{% endif %} | |
{% if attribute(data, 'other_date~display_label') %} | |
{% set od_field = attribute(data, 'other_date~display_label') %} | |
{% if '~' in od_field %} | |
{% set od_parts = od_field|split('~',2) %} | |
<dateOther displayLabel='{{ od_parts[1]|trim }}'>{{ od_parts[0]|trim }}</dateOther> | |
{% else %} | |
<dateOther>{{ od_field|trim }}</dateOther> | |
{% endif %} | |
{% endif %} | |
{% if attribute(data, 'date_issued') %} | |
<dateIssued>{{ data.date_issued|trim }}</dateIssued> | |
{% endif %} | |
{% if attribute(data, 'date_captured') %} | |
<dateCaptured>{{ data.date_captured|trim }}</dateCaptured> | |
{% endif %} | |
{% if attribute(data, 'publisher') %} | |
<publisher>{{ data.publisher|trim }}</publisher> | |
{% endif %} | |
{% if attribute(data, 'place_of_publication') %} | |
<place> | |
<placeTerm type="text">{{ data.place_of_publication|trim }}</placeTerm> | |
</place> | |
{% endif %} | |
</originInfo> | |
{% endif %} | |
{# Public_Notes~Types #} | |
{# July 2017... Replacing the simple note1|note2 logic below with support for note1~type1|note2|note3~type3 logic #} | |
{% if attribute(data, 'public_notes~types') %} | |
{% for note in attribute(data, 'public_notes~types')|split('|') %} | |
{% if note is not null and note|trim is not empty %} | |
{% if '~' in note %} | |
{% set note_parts = note|split('~',2) %} | |
<note type='{{ note_parts[1]|trim }}'>{{ note_parts[0]|trim }}</note> | |
{% else %} | |
<note>{{ note|trim }}</note> | |
{% endif %} | |
{% endif %} | |
{% endfor %} | |
{% endif %} | |
{# Notes~Display_Label #} | |
{# August 2018... Adding Notes~Display_Label to create a place for notes with greater control over display. Implicitly @type='content' #} | |
{% if attribute(data, 'notes~display_label') %} | |
{% for note in attribute(data, 'notes~display_label')|split('|') %} | |
{% if note is not null and note|trim is not empty %} | |
{% if '~' in note %} | |
{% set note_parts = note|split('~',2) %} | |
<note type='content' displayLabel='{{ note_parts[1]|trim }}'>{{ note_parts[0]|trim }}</note> | |
{% else %} | |
<note type='content'>{{ note|trim }}</note> | |
{% endif %} | |
{% endif %} | |
{% endfor %} | |
{% endif %} | |
{# Dates_as_Notes~Display_Label #} | |
{# August 2018... Adding Dates_As_Notes~Display_Label to create a place for otherwise invalid date strings. Implicitly @type='creation/production credits' #} | |
{% if attribute(data, 'dates_as_notes~display_label') %} | |
{% for note in attribute(data, 'dates_as_notes~display_label')|split('|') %} | |
{% if note is not null and note|trim is not empty %} | |
{% if '~' in note %} | |
{% set note_parts = note|split('~',2) %} | |
<note type='creation/production credits' displayLabel='{{ note_parts[1]|trim }}'>{{ note_parts[0]|trim }}</note> | |
{% else %} | |
<note type='creation/production credits'>{{ note|trim }}</note> | |
{% endif %} | |
{% endif %} | |
{% endfor %} | |
{% endif %} | |
{# Citations #} | |
{% if attribute(data, 'citations') %} | |
{% for citation in attribute(data, 'citations')|split('|') %} | |
{% if citation is not null and citation|trim is not empty %} | |
<note type='citation'>{{ citation|trim }}</note> | |
{% endif %} | |
{% endfor %} | |
{% endif %} | |
{# Table_of_Contents #} | |
<tableOfContents>{{ data.tableOfContents }}</tableOfContents> | |
{# LCSH_Subjects #} | |
{% if attribute(data, 'lcsh_subjects') %} | |
<subject authority="lcsh"> | |
{% for topic in attribute(data, 'lcsh_subjects')|split('|') %} | |
{% if topic is not null and topic|trim is not empty %} | |
<topic>{{ topic|trim }}</topic> | |
{% endif %} | |
{% endfor %} | |
</subject> | |
{% endif %} | |
{# Subjects_Names~Types #} | |
{% if attribute(data, 'subjects_names~types') %} | |
{% for subjects_name in attribute(data, 'subjects_names~types')|split('|') %} | |
{% if subjects_name is not null and subjects_name|trim is not empty %} | |
<subject authority="lcsh"> | |
{% if '~' in subjects_name %} | |
{% set subjects_name_parts = subjects_name|split('~',2) %} | |
<name type='{{ subjects_name_parts[1]|trim }}'> | |
<namePart>{{ subjects_name_parts[0]|trim }}</namePart> | |
</name> | |
{% else %} | |
<name> | |
<namePart>{{ subjects_name|trim }}</namePart> | |
</name> | |
{% endif %} | |
</subject> | |
{% endif %} | |
{% endfor %} | |
{% endif %} | |
{# Subjects_Geographic #} | |
{% if attribute(data, 'subjects_geographic') %} | |
<subject authority="lcsh"> | |
{% for geographic in attribute(data, 'subjects_geographic')|split('|') %} | |
{% if geographic is not null and geographic|trim is not empty %} | |
<geographic>{{ geographic|trim }}</geographic> | |
{% endif %} | |
{% endfor %} | |
</subject> | |
{% endif %} | |
{# Subjects_Temporal #} | |
{% if attribute(data, 'subjects_temporal') %} | |
<subject authority="lcsh"> | |
{% for temporal in attribute(data, 'subjects_temporal')|split('|') %} | |
{% if temporal is not null and temporal|trim is not empty %} | |
<temporal>{{ temporal|trim }}</temporal> | |
{% endif %} | |
{% endfor %} | |
</subject> | |
{% endif %} | |
{# Keywords #} | |
{% if attribute(data, 'keywords') %} | |
<subject> | |
{% for keyword in attribute(data, 'keywords')|split('|') %} | |
{% if keyword is not null and keyword|trim is not empty %} | |
<topic>{{ keyword|trim }}</topic> | |
{% endif %} | |
{% endfor %} | |
</subject> | |
{% endif %} | |
{# Coordinate #} | |
{% if attribute(data, 'coordinate') %} | |
<subject> | |
<cartographics> | |
<coordinates>{{ data.coordinate }}</coordinates> | |
</cartographics> | |
</subject> | |
{% endif %} | |
{# Related_Items~Types #} | |
{# Supports relations of the form related_item1~type1 | related_item2 | related_item3~type3 #} | |
{# If ~type is omitted, as in related_item2 above, the type = 'host' is assumed #} | |
{% set foundDG = false %} | |
{% if attribute(data, 'related_items~types') %} | |
{% for relation in attribute(data, 'related_items~types')|split('|') %} | |
{% if relation is not null and relation|trim is not empty %} | |
{% if '~' in relation %} | |
{% set relation_parts = relation|split('~',2) %} | |
<relatedItem type='{{ relation_parts[1]|trim }}'> | |
<titleInfo> | |
<title>{{ relation_parts[0] }}</title> | |
</titleInfo> | |
{% if relation_parts[0] == 'Digital Grinnell' %} | |
{% set foundDG = true %} | |
{% endif %} | |
</relatedItem> | |
{% else %} | |
<relatedItem type='host'> | |
<titleInfo> | |
<title>{{ relation }}</title> | |
</titleInfo> | |
</relatedItem> | |
{% if relation == 'Digital Grinnell' %} | |
{% set foundDG = true %} | |
{% endif %} | |
{% endif %} | |
{% endif %} | |
{% endfor %} | |
{% endif %} | |
{# This block is CUSTOM and specific to Digital Grinnell. It ensures that ALL object have a relatedItem[@type='host'] with a value of 'Digital Grinnell' #} | |
{% if foundDG == false %} | |
<relatedItem type="host"> | |
<titleInfo> | |
<title>Digital Grinnell</title> | |
</titleInfo> | |
</relatedItem> | |
{% endif %} | |
{# Type_of_Resource~AuthorityURI #} | |
{% if attribute(data, 'type_of_resource') %} | |
<typeOfResource>{{ data.type_of_resource|trim }}</typeOfResource> | |
{% endif %} | |
{# Genre~AuthorityURI #} | |
{% if attribute(data, 'genre~authorityuri') %} | |
{% if '~' in data.genre~authorityuri %} | |
{% set genre_parts = data.genre~authorityuri|split('~',2) %} | |
<genre authorityuri='{{ genre_parts[1]|trim }}'>{{ genre_parts[0]|trim }}</genre> | |
{% else %} | |
<genre authorityuri='https://www.loc.gov/standards/valuelist/marcgt.html'>{{ data.genre~authorityuri }}</genre> | |
{% endif %} | |
{% endif %} | |
{# Extent, Form~AuthorityURI, MIME_Type, Digital_Origin #} | |
{% if attribute(data, 'extent') or attribute(data, 'form') or attribute(data, 'mime_type') or attribute(data, 'digital_origin') %} | |
<physicalDescription> | |
{% if attribute(data, 'extent') %} | |
<extent>{{ data.extent }}</extent> | |
{% endif %} | |
{% if attribute(data, 'form') %} | |
<form>{{ data.form }}</form> | |
{% endif %} | |
{% if attribute(data, 'mime_type') %} | |
<internetMediaType>{{ data.mime_type }}</internetMediaType> | |
{% endif %} | |
{% if attribute(data, 'digital_origin') %} | |
<digitalOrigin>{{ data.digital_origin }}</digitalOrigin> | |
{% endif %} | |
</physicalDescription> | |
{% endif %} | |
{# Classifications~Authorities #} | |
{% if attribute(data, 'classifications~authorities') %} | |
{% for classification in attribute(data, 'classifications~authorities')|split('|') %} | |
{% if classification is not null and classification|trim is not empty %} | |
{% if '~' in classification %} | |
{% set classification_parts = classification|split('~',2) %} | |
<classification authoritiy='{{ classification_parts[1]|trim }}' type='mixed'>{{ classification_parts[0]|trim }}</classification> | |
{% else %} | |
<classification type='mixed'>{{ classification|trim }}</classification> | |
{% endif %} | |
{% endif %} | |
{% endfor %} | |
{% endif %} | |
{# Language_Names~Codes #} | |
{% if attribute(data, 'language_names~codes') %} | |
<language> | |
{% for language in attribute(data, 'language_names~codes')|split('|') %} | |
{% if language is not null and language|trim is not empty %} | |
{% if '~' in language %} | |
{% set lparts = language|split('~',2) %} | |
<languageTerm type="text">{{ lparts[0]|trim }}</languageTerm> | |
<languageTerm type="code" authority="iso639-2b">{{ lparts[1]|trim }}</languageTerm> | |
{% else %} | |
<languageTerm type="text">{{ language|trim }}</languageTerm> | |
{% endif %} | |
{% endif %} | |
{% endfor %} | |
</language> | |
{% endif %} | |
{# Local_Identifier #} | |
{% if attribute(data, 'local_identifier') %} | |
<identifier type="local">{{ data.local_identifier|trim }}</identifier> | |
{% endif %} | |
{# Handle #} | |
{% if attribute(data, 'handle') %} | |
<identifier type="hdl">{{ data.handle|trim }}</identifier> | |
{% endif %} | |
{# Physical_Location, Shelf_Locator #}, Access_Condition | |
{% if attribute(data, 'physical_location') or attribute(data, 'shelf_locator') %} | |
<location> | |
{% if attribute(data, 'physical_location') %} | |
<physicalLocation>{{ data.physical_location }}</physicalLocation> | |
{% endif %} | |
{% if attribute(data, 'shelf_locator') %} | |
<shelfLocator>{{ data.shelf_locator }}</shelfLocator> | |
{% endif %} | |
</location> | |
{% endif %} | |
{# Access_Condition #} | |
{% if attribute(data, 'access_condition') %} | |
<accessCondition type="useAndReproduction">{{ data.access_condition }}</accessCondition> | |
{% else %} | |
<accessCondition type="useAndReporoduction">Copyright to this work is held by the author(s), in accordance with United States copyright law (USC 17). Readers of this work have certain rights as defined by the law, including but not limited to fair use (17 USC 107 et seq.).</accessCondition> | |
{% endif %} | |
{# Import_Index, Import_Source, Primary_Sort, Hidden_Creator, Pull_Quotes, Private_Notes~Types #} | |
{# The following MODS extension elements may be specific to Digital Grinnell! #} | |
<extension> | |
{% if attribute(data, 'import_index') %} | |
<dg_importIndex>{{ data.import_index }}</dg_importIndex> | |
{% endif %} | |
{% if attribute(data, 'import_source') %} | |
<dg_importSource>{{ data.import_source }}</dg_importSource> | |
{% endif %} | |
{% if attribute(data, 'primary_sort') %} | |
<primarySort>{{ data.primary_sort }}</primarySort> | |
{% else %} | |
<primarySort>99</primarySort> | |
{% endif %} | |
{% if attribute(data, 'hidden_creator') %} | |
<hidden_creator>{{ data.hidden_creator }}</hidden_creator> | |
{% endif %} | |
{% if attribute(data, 'pull_quotes') %} | |
{% for pull_quote in attribute(data, 'pull_quotes')|split('|') %} | |
{% if pull_quote is not null and pull_quote|trim is not empty %} | |
<pull_quote>{{ pull_quote|trim }}</pull_quote> | |
{% endif %} | |
{% endfor %} | |
{% endif %} | |
{% if attribute(data, 'private_notes~types') %} | |
{% for pr_note in attribute(data, 'private_notes~types')|split('|') %} | |
{% if pr_note is not null and pr_note|trim is not empty %} | |
{% if '~' in pr_note %} | |
{% set pr_note_parts = pr_note|split('~',2) %} | |
<note type='{{ pr_note_parts[1]|trim }}'>{{ pr_note_parts[0]|trim }}</note> | |
{% else %} | |
<note>{{ pr_note|trim }}</note> | |
{% endif %} | |
{% endif %} | |
{% endfor %} | |
{% endif %} | |
</extension> | |
</mods> | |
{% endautoescape %} | |
{% endblock %} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment