2 developers!Developing a suite of library solutions.
Extending your GUIWorkshop at ELAG 2016
Who am I …?• User Experience Designer• Pragmatic programmer
DisclaimerSome of the examples for modifying may not be available in your system – or behave in a different way.But we are here to explore.
http://www.ng-newsletter.com/posts/angular-for-the-jquery-developer.html
Who are you?
EDS Integra Other Primo Summon VuFind2 (blank)
1 1
3
11
4
1
Total
Total
Who are you?
Not at all Minor changes
Minor changes
Not at all Minor changes
Not at all (blank) Huge changes /
rewrite
Minor changes
Not at all Not at all (blank)
EDS Integra Other Primo Summon VuFind2 (blank)
1 1 1
2
4
6
1 1
2
1
JavaScript addition/changes
Total
Who are you?
Not at all (blank)0
5
10
15
20
25
Changed programming code (not JavaScript) on the webserver
Total
Congratulations …
I’ll make that into a feature
requestUnfortunately that cannot be configured …
That is out of scope of the
product
We have not heard that from other customers
Forwarded to the new product manager
That is a Danish issue
Do you recognize this?
Goal of today and tomorrow
CC BY-SA 2.0 Michele M.F.https://www.flickr.com/photos/e-coli/15748320149
To give you an overview and insights in the possible building blocks, enabling you to do further exploration of the possibilities in your system.
The examples are for inspiration.
We need a reporter!
Discovery system Own server Helper External service
Server Client Server Client
Look’n’feel
Search experience
Record enrichment
+ push data from your discovery system into
other systems
Motivation for our Primo setup
Primo X-Service
Our own UI
Primo Native
AUB UIPrimo UI
jQuery
Primo Native UI
Custom Primo tiles
Primo Native UI
Customization through BE
Extending UI
http://en.wikipedia.org/wiki/File:Library_of_Congress,_Rosenwald_4,_Bl._5r.jpg
The native app challenge• Not about responsive design
• Building your own app is no problem
Webserver
Webserver
Server side vs client side
Webserver
Custom file
JavaScriptData
JavaScriptNo data
Custom tile Internal file
Custom tile External url
External service
Primo/SFX Helpers
The ”API” of the U.I.
The ”API” of the U.I.
<!DOCTYPE html><html><head></head><body> <div id="one"></div> <div class="two"> <div class=“two"> <p class="six"> <a href="go.html">Go</a> </p> </div> </div></body></html>
TagClassIdAttribute:stateTraverse…
ParentsChildrenSiblings
Triggers
jQuery is a cross-browser JavaScript library designed to simplify the client-side scripting of HTML.
As of 2015, jQuery remains the most widely used JavaScript library on the Web. According to JavaScript library analytics service, Libscore, jQuery is in use on over 63% of the top million most popular sites by traffic volume.
Source: en.wikipedia.org/wiki/Jquery
jQuery allows you to ....• Selection of item(s)
$(‘.EXLResult’)$(‘.EXLResult’).find(‘a’)
• Loops$(‘.EXLResult’).each(function() { do stuff });
• Manipulation$(‘.EXLResult’).hide();$(‘.EXLResult’).append(‘<div>This is a result</div>’);$(‘.EXLSignOut’).text(‘Get away from here’);
jQuery allows you to ....• Be used in if-then-else
if ($(this).find('.EXLResultFRBR').length != 0) …• Change the look and feel
$(‘.EXLResult’).addClass(‘niceresult’)• Get or post data
$.getJSON('ajax/test.json', function(data) { …• Trigger script on events
$(document).ready(function() { });$(document).ajaxComplete(function() { });$(‘.EXLResult’).click(function() { alert(‘click’); });
• Animate
27
Getting jQuery into PrimoAdd to the footer
<script type=”text/javascript”>$(document).ready(function) { alert(‘Let us do some jQuery’);});</script>
And link to external JS-files
jquery.PRIMO – the magic library for Primo
https://github.com/mehmetc/jQuery.PRIMO
Linking Open Data cloud diagram 2014, by Max Schmachtenberg, Christian Bizer, Anja Jentzsch and Richard Cyganiak. http://lod-cloud.net/
Data to and from external sources
Examples of sources• ILS (e.g. Aleph)• Discovery system itself• LinkResolver (e.g. the SFX RSI)• Google Books• Journal TOCs• Book Locator service• WordPress blog• Wikipedia• DBpedia
Getting data on-the-fly
Construct url
Fetch using Ajax.
Include relevant
parameters
Do the server stuff! Parse result Modify
accordingly
Or get the server to do the work
Getting data on-the-fly• Ajax (Asynchronous JavaScript and XML)
• Allows you to get or post data to the Primo server, or any other server.
• Same origin policy problem can be overcomed with JSONP.
• Alternative to enrichment (for good and bad).
One of the data exchange formatJSONPJavaScript Object Notation with padding.
jsonp1310982735388( { "total": "2142950", "online": "1190781“})
Explore your discovery system• F12 in Chrome is your friend!
Look’n’feel
Discovery system Own server Helper External service
Server Client Server Client
Look’n’feel
Search experience
Record enrichment
LOOK’N’FEEL
Backend configuration
LOOK’N’FEEL
JS No data
LOOK’N’FEEL
JS No data
if (jQuery.PRIMO.records.length == 1 && jQuery.PRIMO.records[0].id == '') {$('.EXLResult').append(‘You need to sign in to see this record');
};
Work time• How have you changed the look and feel of your discovery system?• What outstanding issues do you have?• What potential solutions could enhance the user experince?
• Explore with Developer Tools:• Elements on your page• CSS styles• Try some simple jQuery
Enhancing the search experience
Discovery system Own server Helper External service
Server Client Server Client
Look’n’feel
Search experience
Record enrichment
BETTER SEARCH EXPERIECE
JS No data
BETTER SEARCH EXPERIECE
Custom tiles External
BETTER SEARCH EXPERIECE
Custom tiles External
PHP Code:
function getWordPermutations($inStr) { $outArr = Array(); $tokenArr = explode(" ", $inStr); $pointer = 0; for ($i=0; $i<count($tokenArr); $i++) { $outArr[$pointer] = $tokenArr[$i]; $tokenString = $tokenArr[$i]; $pointer++; for ($j=$i+1; $j<count($tokenArr); $j++) { $tokenString .= " " . $tokenArr[$j]; $outArr[$pointer] = $tokenString; $pointer++; } } return $outArr;}
Custom file Internal
External service
Primo/SFX Helpers
JavaScriptData
PresentationUI logic
Logic glueService brokerCustom PDS: User info with secret key
Any (API providing) service
PDS user info as JSONP
Request patron id and secret value from PDS session in JSON
Collect data in the user interface to
save
Send JSONP request to store data in
external service.Include patron id and secret value
Verify patron id and secret value
PDS+ jQuery.PrimoFile on server
External new servicePDS+Custom JavaScript
Primo Helper
BETTER SEARCH EXPERIECE
Primo Helper
External service
Custom file Internal
JS Data
Work time• How have you changed the search experience of your discovery
system?• What outstanding issues do you have? • What potential solutions could enhance the search experince?
• What data could enhance the search experience, e.g. by parsing the query.
Record enrichment
Discovery system Own server Helper External service
Server Client Server Client
Look’n’feel
Search experience
Record enrichment
ENRICHING THE RECORD WITH FUNCTIONALITY
External service
JS No data
ENRICHMENT OF THE RECORD
Sources:• Primo itself• Aleph• Google Books• Journal TOCs
External service
PREAS
JS Data
CC BY 3.0 Brady Holt https://commons.wikimedia.org/wiki/File:IIHS_Hyundai_Tucson_crash_test.jpg
RSI ServicePNX display JournalTOC
Primo JS
Primo Result Extender Aggregator Service (PREAS)
Loop through each record and get PNX
Get additional data for each
record
Modify each record
accordingly
Time consumingFragileExpensive to extendSimple engine (JS)
Primo Result Extender Aggregator Service (PREAS)
Loop through each record and get PNX
Request additional data
for each record
Modify each record
accordingly
Loop through each record to create url
(incl FRBR)
Request additional data for all records
in aggregator
Modify each record accordingly
AUB01_ALEPH001710473 dedupmrg273746312 AUB_VBNpublications6…AUB01_ALEPH001280012 frbg261592298
Input id Primo X-service Aleph X-service RSI + Google JournalTOC
<ALEPH><ALEPH> <PNX><PNX>
ISBN / ISSN ISSN
<PNX>
ISBN / ISSN ISSN ISBN / ISSN ISSN
JSONP
Cache on all responses
Fast parallel processingNot so fragileCheap to extendComplex engine (Perl)
JSONP Responsejsonp1314904858441({ "items": [
{
"id": "AUB01_ALEPH001710473",
"isbn": "9781607320241",
"rsi": 1,
"openurl": "http://sfx.aub.aau.dk/sfxaub?..."
},
{
"id": "AUB01_ALEPH001449322",
"isbn": "9780691130422",
"gbs": 1,
"previewLink": "http://books.google.com/books?id=...",
"viewability": "PARTIAL"
},
{ "id": "frbg261592298", "httpStatus": "CACHE_HIT", "years": "1988, 1991…", "yearsRange": "1988,, 1995-2000, …" }]);
ENRICHMENT OF THE RECORD
External service
JS No data
ENRICHMENT OF THE RECORD
External service
JS Data
ENRICHMENT OF THE RECORD
External service
WP2PRIMO
JS No data
WORDPRESS SETUP• Self hosted version 4.4.2
• Relevant plug-ins:
• Disable Comments• JSON API• Post Expirator• RSS Custom Fields• Simple Content Templates• Theme Switcher
3 million requests per year
CUSTOM TAGS
• Current bugs and scheduled downtime• Mobile and tablet
• Old and/or deprecated stuff (trash)
CATEGORIES
System numberUrl
TN_
GETTING EXTERNAL DATA
Primo page rendered
JSONP call to external page
Get RSS feed from
WordPress
Convert RSS feed to JSONP
Parse JSONP to
tabs/messages
Custom PHP script
WordPress RSS=>
JSON(P)
Task:Reorder the elementsJoin post accoding to
custom fields
WordPress
Blog posts
Custom fields:url
system numberpci prefix (TN_)
CategoryTags
RSS JSON(P)
PHP SCRIPT$rawFeed = file_get_contents($feedUrl);$xml = new SimpleXmlElement($rawFeed);
$urls_incidents = array();
foreach ($xml->channel->item as $item){ if ($item->custom_fields->url != null && $item->custom_fields->url != "") { $urlsinloop = explode(' ', $item->custom_fields->url); }}
$returnarray['incidents']['urls'] = $urls_incidents;$json = json_encode($returnarray);
Caching etc. to improve(if needed)
http://blog.aub.aau.dk/operation/tag/safari-tech-books/?cat=138
ENRICHING BASED ON SELECTORS$('.EXLResultTitle > a[href*="' + key + '"]’);$('#AUB01_ALEPH' + key);
$.each(data.tips.urls, function(key,value) {var urlselector = '.EXLResultTitle > a[href*="' + key + '"]';var url2blog = baseurl + 'tag/' + value + '?cat=' + tipscatnumber;$(urlselector).parents('.EXLResult').find('.EXLResultRecordId').attr('tips', '1').attr('tipstags', value).attr('tipsblogurl', url2blog);});
EXLTA_addTab('Announcements','incidentTab','#',incidentTabHandler,false,incidentEvaluator);
ADDING THE TABvar incidentTabHandler = EXLTA_createWidgetTabHandler(function(element){ var recordId = EXLTA_recordId(element); var bloglink = $('.EXLResultRecordId[id="' + recordId + '"]').attr('incidentblogurl') + '&wptheme=PrimoTab'; return '<iframe src="' + bloglink + '"></iframe>';},true);
var incidentEvaluator = function(element){ var recordId = EXLTA_recordId(element); if ($('.EXLResultRecordId[id="' + recordId + '"]').attr('incidents') != undefined) { return true; } else { return false; }};
ENRICHMENT OF THE RECORD
External service
ERMS2PRIMO
JS Data
Work time• How have you enriched the records with either …
• Functionality• Extra data
• What outstanding issues do you have? • What potential solutions and data sources could enhance the record?
• Explore with Developer Tools:• Data available in the D.O.M.• Data streams in network
Wrap up• Pros and cons of various solutions
Top Related