PKP 2017 Sprint Report: Making Metadata Fields Required
Special thanks to this group’s participants: Angus F., Sophy O., Alec S., and Ilyass T.
During the sprint event at the PKP 2017 International Scholarly Publishing Conference, we formed a small subgroup to introduce OJS 3.x coding by working on a small real-world feature addition. This also illustrates a typical way in which a feature gets added to our software organizationally based on a user request, beginning with our support forum.
Users within OJS 3.x are able to enable and disable metadata fields in OJS 3.0.2, so they can be either presented or hidden from the metadata form during submission (for the author) and later during the editing process (for authors, editors, etc). Setting up these fields looks like this:
This is useful for controlling whether or not metadata fields are available, but users on our support forum also wanted to be able to control whether metadata fields are required, i.e. controlling which fields the submission system would force authors to complete before accepting the submission. Here’s one such request:
PKP receives a lot of feature requests and need to decide how to manage them. Some feature requests are left until later, especially if they’re complex and do not align well with PKP’s roadmap or broader community. Sometimes we work with external groups to develop new features as plugins, which can be an ideal solution if an important subset of our community needs a feature. Sometimes groups with coding capabilities will maintain the change as a modification to their own installation.
The best outcome is for the feature to be groomed into a useful implementation for the entire community and released in a new version of OJS. Because this feature is broadly useful and its implementation isn’t complex, that outcome was possible for this request. The coding task was simple enough that it made a good candidate for a sprint group to tackle over the course of a 2-day event.
Where To Start
We decided to begin by adding a new column to the metadata checkboxes pictured above — but where to begin? One of the first challenges in working on software is finding out where to start coding, having identified the part of the system you wish to modify.
One good way to start is by looking at request URLs and using them to identify handling code. OJS 3.x uses subrequests to build a page, so a developer toolset in a browser is useful. We’ll use Firebug’s developer tools; other browsers will be similar. Enabling the tool and browsing to the settings area we wish to extend results in the following:
You’ll see several different kinds of URLs, notably:
- Component URLs (identified by $$$call$$$ appearing in the URL)
- API URLs (identified by /api/ appearing in the URL)
- Page URLs (not marked by either of the above telltales)
Here are a few words on each type of URL.
Component requests contain $$$page$$$ in their URLs to help OJS to distinguish them from other types of requests. Components are reusable controls that are typically JSON-encoded and may be reused in several parts of PKP software, e.g. the file listings (“grids”) that recur through the workflow and provide a consistent interface for working with files.
Here’s an example of a component URL:
In this example URL, publicknowledge identifies the journal (on a potentially multi-journal installation of OJS); and /grid/settings/metadata/metadata-grid/fetch-grid identifies the code that’s responsible for handling the request. Specifically, /grid/settings/metadata identifies the path to the handler class; metadata-grid tells OJS to load a PHP file called MetadataGridHandler.inc.php; and fetch-grid tells OJS to execute a function called fetchGrid implemented in that class. (OJS transforms hyphenated-names into lowerCamelCase in the last two cases.)
Controller code lives in the controllers and lib/pkp/controllers subdirectories. Putting this all together, we can find the handling code for this controller in lib/pkp/controllers/grid/settings/metadata/MetadataGridHandler.inc.php in the fetchGrid function. (This function is actually implemented in MetadataGridHandler’s parent class, GridHandler.)
API URLs are being added for the OJS 3.1 release, and we’ll be writing more thoroughly about the REST API offered by PKP applications like OJS soon.
Page URLs won’t include the telltale markers $$$call$$$ or /api/ and they tend to represent requests that present an entire page of content. (OJS 2.x was almost entirely built using page requests, as it did not tend to build pages dynamically using subrequests.) These are the sorts of URLs you’ll frequently see in the browser’s address bar, such as:
In this example, publicknowledge identifies the journal (as above), management identifies the handler class, settings identifies the function within that class, and publication (and anything beyond it) gets supplied to that function as an optional parameter.
In this case, you can look in pages/management/index.php to find a wrapper that may delegate to other classes. The settings function is delegated there to pages/management/SettingsHandler.inc.php, specifically the settings function there.
We want to add a new column to the list of checkboxes titled “Required”, permitting the user to check off which fields are to be require metadata during submission. Looking at the request URLs using the developer tool, we see several candidate URLs:
All but one of these contain $$$call$$$, thus are component URLs. Given that the area we’re looking to modify is called “Submission Metadata”, the last URL is the best candidate.
This URL is the same example we used to describe component URLs above, so we know that request handling is implemented in lib/pkp/controllers/grid/settings/metadata/MetadataGridHandler.inc.php.
MetadataGridHandler inherits from GridHandler, which is a complex and frequently-used component responsible for providing a listing of data along with tools to interact with it. There is detailed documentation in the PKP wiki and in our code self-documentation.
Our group wrote a few pages of code to implement the following changes:
- Add the checkboxes to the settings form, and save the setting states to the database
- Alter the submission form to check the settings and add checks to the relevant controls
The resulting settings form is barely changed, but an oft-requested new feature has been added to it:
This feature will be released in OJS 3.1 — and better still, its implementation lives entirely in the shared library that OMP also uses, so it’ll be released there too with no extra work.
Thanks again to all sprint participants for an engaging event!