Is it possible to call up a modal from plugin

I have restarted looking into some projects involving plugins: one is the possibility to move a submission from one journal to another on a multi-journal site.

So far, I am in the planning phase, with most of the background work panned out.

However, I am still not sure how to call up a modal form from a plugin: i somewhat seem to understand this involves linkaction, which redirects to an AJAX modal form.

does anyone have an example?



For OJS 3.1.1-4, the Akismet plugin uses the TemplateManager's fetch() callback to examine each template displayed. If the template is a gridRow, and if the data within the grid is a User, it adds a new LinkAction to the row:

The LinkAction's URL is handled by the LoadComponentHandler hook:

This is setup via hooks callback:

And implemented as a hander file in the plugin:

The LinkAction constructor is documented here:

Available LinkActionRequests can be found here:

We are generally moving away from using the “grids” in order to use vue.js instead, so the initial logic of examining the “gridRow” is short lived (and may already be obsolete for Submissions, depending on your version of OJS).

Can you describe where within the workflow you picture this action appearing in the interface?

wow… i am going through it slowly… it seems that I was somewhat on the right lines…

I am playing around with the interface so far, but my simpler and most consistent choice would be to include a link on the submission main page, in the submission header.

The following is a small edit of the submission header tpl: i would need to override this once the plugin is ready.

Once the user clicks on this, I would open up a modal, with a list of Journals to choose from, and its respective sections.

 * templates/workflow/submissionHeader.tpl
 * Copyright (c) 2014-2018 Simon Fraser University
 * Copyright (c) 2003-2018 John Willinsky
 * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
 * Include the submission progress bar
<div class="pkp_page_title">
  <div style="width: 75%; float: left;">
  	<h1 class="pkp_submission_title">
  		<span class="pkp_screen_reader">{translate key="submission.submissionTitle"}</span>
  	<div class="pkp_submission_author">
  		<span class="pkp_screen_reader">{translate key="user.role.author_s"}</span>
  <div style="width: 24%; float: right">
    Choose Journal
  <div style="clear: both"> </div>

I had experimented in the past with vue.js, but my build.js never really worked.


In 3.1.1 stable, this file (lib/pkp/templates/workflow/submissionHeader.tpl) includes several linkAction directives:

If you add a new <li> within the ul.pkp_submission_actions, I think you’ll get exactly what you want. (And no worries about grids vs. vue.js!)

To add content to the display from a plugin, use the TemplateManager::display hook, as:

Then, create a callback function which examines which template is being displayed, and if you want to modify that template, register an output filter:

The output filter searches and replaces within the output to modify the content, and then de-registers the output filter:

But what content are you adding? It will be similar to the output of the line: <li>{include file="linkAction/linkAction.tpl" action=$submissionEntryAction}</li>

The variable $submissionEntryAction currently gets assigned here:

The example uses a SubmissionEntryLinkAction. I’m not sure if there is a way to directly use a Modal or AjaxModal for form this kind of interaction, or if you need to create a new subclass of the LinkAction to implement this. @NateWr or @asmecher might have advice and an example there.

Alternately, this might also make sense as a new editorial action:

Just one more thing to consider!

1 Like


Am working on it, but first snag: submission header is loaded, so I cannot match it through the TemplateManger::display hook.

Will see if i can catch it through loadhandler.

If this takes too long, i will work on the details of the backend first, then move to the interface…


Were you trying to check if ($template === 'workflow/submissionHeader.tpl')?

I think the TemplateManager::display hook will actually be called on workflow/workflow.tpl, with submissionHeader.tpl processed as an include.

I haven’t actually tested to confirm, but I’m pretty sure if you hook TemplateManager::display, conditionally select the template workflow/workflow.tpl, and search for /<div[^>]+class="pkp_submission_actions"[^>]+>/, you’ll get the div you are looking for.

Dear @ctgraham,

You are correct: i had tried checking for “workflow/submission.tpl”, but realised that it is not called directly. I did try checking against “workflow/workflow.tpl”, and this does initiate the callback, however, the param[1] does not contain the matching submissionheader html:

// Initialise JS handler.
$(function() {
sourceUrl: "http:\\/\\/[](				\\/index.php\\/test\\/workflow\\/submissionHeader?submissionId=193&stageId=1&contextId=submission",
refreshOn: null
<div id="submissionHeaderDiv" class="pkp_page_header">
<div class="pkp_loading">
<span class="pkp_spinner"></span>
<span class="message">Loading</span>

I believe that this is loaded by AJAX after loading the html. I am managing to get this event through the

HookRegistry::register(‘LoadHandler’,array(&$this, ‘callbackHandleDisplay’));

but the params only include the calling page, so now I do not think that the filtering option will actually work.

It might be easier for me to modify the tpl for the time being, then address this issue after I know the plugin works.


By chance, how do I set up a link in a tpl, to call my plugin?

I have tried:

{url|assign:submissionURL router=$smarty.const.ROUTE_COMPONENT component="plugins.generic.choosejournal.handler" op="change" submissionId=$submission->getId() escape=false}
    <a href='{$submissionURL}'> test </a>

but the anchor then does not link to choosejournal/

I know I am missing something very basic, but some tips would help.

Thanks again

There is an example using the Router’s url() method here:


Am working on it