Bug 26890 - Add opac_biblio_tab and opac_biblio_enhancements_toolbar_button hooks
Summary: Add opac_biblio_tab and opac_biblio_enhancements_toolbar_button hooks
Status: NEW
Alias: None
Product: Koha
Classification: Unclassified
Component: Plugin architecture (show other bugs)
Version: unspecified
Hardware: All All
: P5 - low enhancement (vote)
Assignee: Bugs List
QA Contact: Testopia
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-11-01 21:26 UTC by Mark Hofstetter
Modified: 2023-12-29 14:40 UTC (History)
5 users (show)

See Also:
Change sponsored?: ---
Patch complexity: ---
Documentation contact:
Documentation submission:
Text to go in the release notes:
Version(s) released in:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Hofstetter 2020-11-01 21:26:06 UTC
enable opac-detail to use the same/similar plugin infrastructure as in

intranet/cgi-bin/catalogue/detail.pl

 68     my @plugins = Koha::Plugins->new()->GetPlugins({
 69         method => 'intranet_catalog_biblio_enhancements_toolbar_button'
 70     });
 71
 72     my @tab_plugins = Koha::Plugins->new()->GetPlugins({
 73         method => 'intranet_catalog_biblio_tab',
 74     });
 75     my @tabs;
 76     foreach my $tab_plugin (@tab_plugins) {
 77         my @biblio_tabs;
 78

to add a new tab in opac-detail.pl result page
Comment 1 Mark Hofstetter 2020-11-04 09:48:09 UTC
see 

https://github.com/HKS3/koha-plugin-subordinate-items

for a prove of concept implementation/why this makes sense for us
Comment 2 David Cook 2020-11-04 23:41:03 UTC
I'm not familiar with the plugin use on intranet/cgi-bin/catalogue/detail.pl, but would an alternative be to implement the plugin as an API route and then inject some Javascript into OpacUserJS to insert the tab?

I suppose the annoying part of doing that is injecting the Javascript though...
Comment 3 Fridolin Somers 2020-11-05 10:55:00 UTC
(In reply to David Cook from comment #2)
> I'm not familiar with the plugin use on
> intranet/cgi-bin/catalogue/detail.pl, but would an alternative be to
> implement the plugin as an API route and then inject some Javascript into
> OpacUserJS to insert the tab?
> 
> I suppose the annoying part of doing that is injecting the Javascript
> though...

No need to inject, there is a plugin hook opac_js :
https://github.com/bywatersolutions/dev-koha-plugin-kitchen-sink/blob/450b145a09c358b0dc3eaa0ee97151643c1bbda6/Koha/Plugin/Com/ByWaterSolutions/KitchenSink.pm#L252

And hook opac_head for CSS
Comment 4 Mark Hofstetter 2020-11-05 11:40:42 UTC
OK I really like the idea to expose the data via an API route

so would you change the opac-detail.tt file, or add the whole tab via the js?
Comment 5 David Cook 2020-11-05 22:46:31 UTC
(In reply to Fridolin SOMERS from comment #3)
> No need to inject, there is a plugin hook opac_js :
> https://github.com/bywatersolutions/dev-koha-plugin-kitchen-sink/blob/
> 450b145a09c358b0dc3eaa0ee97151643c1bbda6/Koha/Plugin/Com/ByWaterSolutions/
> KitchenSink.pm#L252
> 
> And hook opac_head for CSS

That's what I meant by inject, but thanks for providing those hooks. I was too lazy to look them up 😅.
Comment 6 David Cook 2020-11-05 22:56:36 UTC
(In reply to Mark Hofstetter from comment #4)
> OK I really like the idea to expose the data via an API route
> 
> so would you change the opac-detail.tt file, or add the whole tab via the js?

I would just add the whole tab via the JS. That way, you don't have to modify Koha at all, and all of your functionality is self-contained in the Koha Plugin.

(I did send an email out yesterday that suggested the Koha Community modify opac-detail.pl (or an underlying library function) to allow Koha Plugins to modify the $template variable.)

(Alternatively, it would be interesting to modify opac-detail.pl and opac-detail.tt to build the tabs using Javascript instead of Perl-generated HTML. But that's a separate development all together.)
Comment 7 Mark Hofstetter 2020-11-15 20:35:40 UTC
thanks so far, the idea seems to work but some minor and one major notes/questions_

+ compared to a normal perl script which returns JSON (eg opac-ratings-ajax.pl)
the API calls are extremly slow

+ using sub opac_js plugin hook puts the js on every page ...

one major gotcha remains

how do I access local script/template variables (like biblionumber) in the plugin hook

modifying opac-details.tt directly I'm able to write 

$.ajax({
    url: '/api/v1/contrib/subordinateitems/biblionumber/[% biblio.biblionumber | uri %]',
  

but how to handle this in the opac_js

thx
Mark
Comment 8 Mark Hofstetter 2020-11-15 21:17:48 UTC
this solution is "fragile", is there any defined place where to find/extract the biblionumber

var biblionumber = document.
   getElementsByClassName("unapi-id")[0].
   getAttribute("title").split(':')[2];
Comment 9 David Cook 2020-11-15 23:37:10 UTC
(In reply to Mark Hofstetter from comment #7)
> + compared to a normal perl script which returns JSON (eg
> opac-ratings-ajax.pl)
> the API calls are extremly slow
> 

Are you using CGI or PSGI/Plack for Koha? The REST API used by the plugins uses the Mojolicious framework; it should be fast for PSGI/Plack, but it would be extremely slow with CGI, as it would have to load and start code which expects to be in a persistent process.

> + using sub opac_js plugin hook puts the js on every page ...
> 

Yeah, it's a bit suboptimal, but you can be smart with your Javascript to minimize the functional impact of that. For instance, only run the Javascript you want to run if a very page-specific condition is met. There is probably a body tag or class for the page you want which should make this easy.

> one major gotcha remains
> 
> how do I access local script/template variables (like biblionumber) in the
> plugin hook
> 

You don't. The plugin hook doesn't take any arguments. It's just used for fetching data from plugins and then printing it out on the template. 

That's an interesting idea though...
Comment 10 David Cook 2020-11-16 00:05:17 UTC
(In reply to Mark Hofstetter from comment #7)
> modifying opac-details.tt directly I'm able to write 
> 
> $.ajax({
>     url: '/api/v1/contrib/subordinateitems/biblionumber/[%
> biblio.biblionumber | uri %]',
>   
> 
> but how to handle this in the opac_js
> 

(In reply to Mark Hofstetter from comment #8)
> this solution is "fragile", is there any defined place where to find/extract
> the biblionumber
> 
> var biblionumber = document.
>    getElementsByClassName("unapi-id")[0].
>    getAttribute("title").split(':')[2];

I think that the unapi-id that you found it probably your best bet, but that's a good point about there not being a great source of biblionumber on the detail page. 

I think there's an argument to be made for adding a data- attribute containing the biblionumber to the body on the detail page, or creating some kind of Javascript object via a template that provides access to the biblionumber. 

Or we could build on the RDFa data that we already have in the HTML and add an identifier (https://schema.org/identifier). 

I know that doesn't help you right now, but that would be a change that would be easy to make, get pushed, and backport. I'll open a Bugzilla issue report for it. I'd be curious to hear what Owen Leonard thinks is the best idea...
Comment 11 David Cook 2020-11-16 00:33:52 UTC
I think you could use the unapi-id for now, but if you want to test and sign off Bug 27029, it might be helpful to you in the long-run.
Comment 12 Mark Hofstetter 2020-11-18 20:58:52 UTC
ok everything works now without touching koha-core, plz see

https://github.com/HKS3/koha-plugin-subordinate-items/

thanks for the help, maybe close this bug, but a little more "plugability" would be great. I really do like the wordpress hook system - just pondering
Comment 13 David Cook 2020-11-19 02:55:34 UTC
(In reply to Mark Hofstetter from comment #12)
> thanks for the help, maybe close this bug

Can do.

>, but a little more "plugability"
> would be great. I really do like the wordpress hook system - just pondering

I'm not very familiar with the Wordpress hook system, but I think that's what originally inspired Kyle Hall to add Koha's plugin system. 

Feel free to suggest improvements to how Koha works. Even if you don't work on something, it might inspire someone else.
Comment 14 David Cook 2020-11-19 02:56:46 UTC
(In reply to Mark Hofstetter from comment #12)
>  maybe close this bug

Actually, I think that I'll keep this bug open, as I think that it's a valid request.

I just made my earlier comments as they provided a way of getting something working sooner rather than later.
Comment 15 Mark Hofstetter 2020-11-19 08:47:12 UTC
just slept over it, and maybe I'm getting an idea about what feels wrong.

The system is very explicit now, meaning you need a lot of code in specific places to use a plugin excactly "there"

I think a plugin system needs to be more implicit eg all cgi scripts should use the same plugin hook(s) (with the name of the script as a config parameter whether the plugin should actually run)

eg: plugin parameter rewrite 
add a parameter to all queries, or whenever a ISBN appears do a transformation

+ maybe could be doable by simply subclassing CGI 

+ or better an more generalised, derive all cgi scripts from a common base class, wrap the code in a sub run {} and everthing becomes possible, this may sound huge but should be in fact only a few lines per script

as I've said just thinking loud(ly)
Comment 16 David Cook 2020-11-20 03:18:23 UTC
(In reply to Mark Hofstetter from comment #15)
> The system is very explicit now, meaning you need a lot of code in specific
> places to use a plugin excactly "there"
> 
> I think a plugin system needs to be more implicit eg all cgi scripts should
> use the same plugin hook(s) (with the name of the script as a config
> parameter whether the plugin should actually run)
> 
> eg: plugin parameter rewrite 
> add a parameter to all queries, or whenever a ISBN appears do a
> transformation
> 
> + maybe could be doable by simply subclassing CGI 
> 
> + or better an more generalised, derive all cgi scripts from a common base
> class, wrap the code in a sub run {} and everthing becomes possible, this
> may sound huge but should be in fact only a few lines per script
> 

With the Plack-enabled Koha, all the CGI scripts actually are loaded and wrapped, but I'm not sure how that would make everything possible. It would let you play with input/output, but that could be a bit fragile. 

There are some plugin hooks that are run for all CGI scripts, but I think that we could use a few more.
Comment 17 David Cook 2020-12-03 00:48:51 UTC
After looking at Bug 27114 and Bug 27120, I reckon that it would be a good idea to get an "opac_catalog_biblio_tab" enhancement done. 

In fact, I just did a local customization recently which I could've done as a plugin instead, if an OPAC equivalent of those above bugs was completed.
Comment 18 Mark Hofstetter 2020-12-03 07:24:20 UTC
I still think plugabiltiy would be a good idea (even if it would be just for the sake of concistency)

but thanks to all your advice I was able to to todo it in a plugin (https://github.com/HKS3/koha-plugin-subordinate-items) just create the tab with js
Comment 19 David Cook 2020-12-04 02:32:17 UTC
(In reply to Mark Hofstetter from comment #18)
> I still think plugabiltiy would be a good idea (even if it would be just for
> the sake of concistency)
> 
> but thanks to all your advice I was able to to todo it in a plugin
> (https://github.com/HKS3/koha-plugin-subordinate-items) just create the tab
> with js

I'm glad that I was able to help! While I used to be worried about UIs built with Javascript, I think a lot of accessibility tools have advanced to the point where it is OK now. And as a result I think that we should actually be moving more work client-side. 

(One of the advantages of moving things client-side is also that we can make more robust reusable APIs and make calls to the same API from different places in the system or even from other systems. Koha is a big system so I'd love to see less replication and more reuse.)
Comment 20 Magnus Enger 2023-12-29 14:37:32 UTC
I have been thinking a bit about adding "things" to the OPAC in a flexible way. The idea I ended up with was something like this: 

Some JavaScript that can fetch "content" asynchronously from the REST API or some custom API/endpoint, so rendering the basic page is not slowed down by e.g. external APIs/datasources used for generating the extra content. 

The JS-call would tell the API what sort of page it is coming from: frontpage, results list, detail etc. 

The API/endpoint would call relevant plugins, gather data and return it. 

The returned data could identify different locations where it wants to be displayed, like "mainuserblock" for the front page, "tab" or "below the print/hold/etc links on the right side of the page" for detail view etc. 

Not sure if that makes sense.
Comment 21 Magnus Enger 2023-12-29 14:40:06 UTC
(In reply to Magnus Enger from comment #20)
> I have been thinking a bit about adding "things" to the OPAC in a flexible
> way. The idea I ended up with was something like this: 
> 
> Some JavaScript that can fetch "content" asynchronously from the REST API or
> some custom API/endpoint, so rendering the basic page is not slowed down by
> e.g. external APIs/datasources used for generating the extra content. 
> 
> The JS-call would tell the API what sort of page it is coming from:
> frontpage, results list, detail etc. 
> 
> The API/endpoint would call relevant plugins, gather data and return it. 
> 
> The returned data could identify different locations where it wants to be
> displayed, like "mainuserblock" for the front page, "tab" or "below the
> print/hold/etc links on the right side of the page" for detail view etc. 
> 
> Not sure if that makes sense.

A bit quick, there. I was thinking HTML would be generated server side and returned from the API/endpoint.