CINXE.COM
Contributor's Guide - OJS|OMP|OPS
<!DOCTYPE html> <html lang="en-US"> <title>Contributor's Guide - OJS|OMP|OPS</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta property="og:title" content="Contributor's Guide - OJS|OMP|OPS" /> <meta property="og:site_name" content="PKP Docs"> <meta name="description" content="A guide for coders who want to contribute to Open Journal Systems, Open Monograph Press and Open Preprint Systems."> <meta property="og:description" content="A guide for coders who want to contribute to Open Journal Systems, Open Monograph Press and Open Preprint Systems."> <meta property="og:url" content="https://docs.pkp.sfu.ca/dev/contributors/"> <link type="text/css" href="/css/book.css" rel="stylesheet" media="all"> <script defer src="/assets/js/smooth-scroll.polyfills.min.js"></script> <script defer src="/assets/js/fontawesome.min.js"></script> <body class="body--withSidebar"> <div class="bookHeader"> <button id="sidebarControl" class="bookHeader__sidebarControl"> <span class="fa fa-bars" aria-hidden="true"></span> <span class="fa fa-times" aria-hidden="true"></span> <span class="-screenReader">Toggle Menu</span> </button> <a class="bookHeader__logo" href="/"> <img src="/img/logo-on-white.png" alt="PKP Docs" class="bookHeader__logoImage"> </a> <div class="bookHeaderTools"> </div> </div> <div class="book"> <a href="#sidebar" class="-screenReader"> Jump to table of contents </a> <div class="book__page"> <div class="book__content"> <div class="book__improve"> <a href="https://github.com/pkp/pkp-docs/edit/main/dev/contributors/index.md"> Edit this page </a> or <a href="https://pkp.sfu.ca/documentation-feedback/"> make a suggestion </a> </div> <h1 id="contributors-guide"> Contributor’s Guide </h1> <p>This document will help you learn how to contribute to Open Journal Systems, Open Monograph Press, and Open Preprint Systems. It is written for coders who are interested in contributing to the software’s code. But some parts of this guide may be useful for anyone who wants to understand how we propose new features, discuss contributions and coordinate the development of the software.</p> <blockquote class="notice"> <p>Not what you’re looking for? Try the <a href="https://docs.pkp.sfu.ca/translating-guide/en">translation guide</a> to become a translator or learn how to <a href="https://docs.pkp.sfu.ca/contributing/en/">contribute to this documentation</a>. If that’s not right for you, you may want to seek help on the <a href="https://forum.pkp.sfu.ca/">community forum</a>.</p> </blockquote> <h2 id="report-a-problem"> Report a Problem <a href="#report-a-problem" class="book_heading_anchor" title="Link to Report a Problem section">#</a> </h2> <p>Input from our community helps us improve the software. We welcome bug reports and suggestions from anyone, even if they have never worked on software before. However, we ask that everyone follow some guidelines to help us manage the work.</p> <p>You can <strong>report a bug</strong> whenever you encounter an error in the software. For example, if the software says an article is published but it is not appearing with other published articles, that is probably a bug. Before reporting a bug, search our <a href="https://forum.pkp.sfu.ca/c/questions/5">support forum</a> to see if anyone has already reported it. If not, open a new topic or draft. You may need to create an account or log into your account on the forum first.</p> <blockquote class="notice"> <p>You can open a bug report in our <a href="https://github.com/pkp/pkp-lib/issues/">GitHub repository</a>. However, we recommend starting with the support forum because you are more likely to receive help there. When you open an issue in our GitHub repository you will be expected to respond knowledgeably to technical questions. GitHub is not a good place to ask for user support.</p> </blockquote> <p>You can <strong>suggest an enhancement</strong> whenever you encounter something in the software that doesn’t work the way that you expect it to. For example, if you think a user should be notified by email about something but they are not. Before suggesting an enhancement, search our <a href="https://forum.pkp.sfu.ca/c/questions/feature-requests/8">feature request forum</a> to see if anyone has already requested it. If not, open a new thread.</p> <p>Software developers and system administrators can <strong>propose technical changes</strong>, such as the adoption of a new library, tool or development technique, in our <a href="https://github.com/pkp/pkp-lib/discussions">GitHub Discussions</a>. Discussions are only appropriate for highly technical and detailed conversations about the code’s architecture and deployment tools.</p> <h2 id="teams"> Teams <a href="#teams" class="book_heading_anchor" title="Link to Teams section">#</a> </h2> <p>PKP’s developers work collaboratively across all parts of the software. However, we have appointed three leads who focus on different parts of the software.</p> <table> <thead> <tr> <th>Team</th> <th>Lead</th> <th>Responsibilities</th> </tr> </thead> <tbody> <tr> <td><strong>Infrastructure</strong></td> <td>Alec (@asmecher)</td> <td>Software architecture and development tools: routing, localization, caching, tests, upgrades, dependencies, deployment and performance.</td> </tr> <tr> <td><strong>Distribution and Metadata</strong></td> <td>Bozana (@bozana)</td> <td>Metadata, deposits, and Library Information Science (LIS) protocols: DOIs, OAI-PMH, Crossref, statistics, themes, versioning and retraction.</td> </tr> <tr> <td><strong>Workflow</strong></td> <td>Vitaliy (@Vitaliy-1)</td> <td>Editorial workflow: submission lists, the submission wizard, editorial decisions, stage assignments, submission files, and the author and reviewer workflows.</td> </tr> </tbody> </table> <p>Large projects will be broken down into issues that can be distributed to different teams. For example, work on JATS XML support may include one issue to adapt the editorial workflow and another issue to adapt Crossref deposits, each assigned to different teams.</p> <h2 id="issue-management"> Issue Management <a href="#issue-management" class="book_heading_anchor" title="Link to Issue Management section">#</a> </h2> <p>The issues in our <a href="https://github.com/pkp/pkp-lib/issues/">GitHub repository</a> help our development team to track, discuss, prioritize and assign work. All issues are assigned to the appropriate labels, projects and milestone.</p> <ul> <li><a href="https://github.com/pkp/pkp-lib/labels">Labels</a> help us track track the priority and complexity of an issue.</li> <li><a href="https://github.com/orgs/pkp/projects?type=beta">Projects</a> help us organize issues into topics like <a href="https://github.com/orgs/pkp/projects/3">Peer Review</a> and <a href="https://github.com/orgs/pkp/projects/5">Statistics</a>.</li> <li><a href="https://github.com/pkp/pkp-lib/milestones">Milestones</a> help us plan when work will be completed and released.</li> </ul> <blockquote class="warning"> <p>You may find issues that aren’t assigned to labels or projects. These should be considered <em>unconfirmed</em> and may be closed at any time.</p> </blockquote> <p>Every issue will follow a similar lifecycle:</p> <ul> <li><a href="#triage">Triage</a> - Assign the issue to a <a href="#development-teams-and-contributors">development team</a>.</li> <li><a href="#investigation">Investigation</a> - Confirm or close the issue.</li> <li><a href="#todo">Todo</a> - Work is planned but not yet started.</li> <li><a href="#under-research">Under Research</a> - We are working to understand what needs to be done.</li> <li><a href="#under-development">Under Development</a> - A developer is implementing this issue.</li> <li><a href="#done">Done</a> - Work on this issue is complete.</li> </ul> <p>Each of these stages is described in more detail below. Community members are invited to discuss issues at any stage of the lifecycle. But the development team may not respond to or engage with comments until they are ready to begin work on the issue.</p> <h3 id="triage"> Triage <a href="#triage" class="book_heading_anchor" title="Link to Triage section">#</a> </h3> <p>When a new issue is filed, a PKP developer will review the issue and assign it to one of our three <a href="#development-teams-and-contributors">development teams</a>.</p> <p>No labels, projects or milestones are assigned at this stage.</p> <h3 id="investigation"> Investigation <a href="#investigation" class="book_heading_anchor" title="Link to Investigation section">#</a> </h3> <p>A member of the assigned development team will briefly investigate the issue and confirm or close it.</p> <ul> <li>For <strong>bugs</strong>, follow the reproduction steps or request reproduction steps when none have been provided. Request better reproduction steps or close the issue when unable to reproduce it.</li> <li>For <strong>enhancements</strong>, ask questions to gather all the information necessary to understand the request. Close the issue and ask the reporter to post in the <a href="https://forum.pkp.sfu.ca/c/questions/5">feature requests forum</a> when more discussion is needed to reach consensus or assess its priority.</li> </ul> <p>Allow two weeks for the person who filed the issue to respond to any requests for reproduction steps or more information. If they don’t reply after two weeks, close the issue.</p> <p>When an issue is confirmed, assign the appropriate labels and projects. Assign a milestone to bugs in the stable version, but not to other issues.</p> <h3 id="todo"> Todo <a href="#todo" class="book_heading_anchor" title="Link to Todo section">#</a> </h3> <p>Assign a milestone to the issue when the assigned team plans to complete work on it for a future version. Work may not have begun yet on the issue, but it has been scheduled to be completed at some point.</p> <h3 id="under-research"> Under Research <a href="#under-research" class="book_heading_anchor" title="Link to Under Research section">#</a> </h3> <p>An issue is under research when the assigned team begins work on the issue. Every issue is different, but this phase may include the following:</p> <ul> <li>Ask questions or conduct UX research to discover how an enhancement should work.</li> <li>Consult schemas, standards or partners to identify technical requirements.</li> <li>Discuss the impact of a change, such as how far back a bug fix should be ported.</li> </ul> <h3 id="under-development"> Under Development <a href="#under-development" class="book_heading_anchor" title="Link to Under Development section">#</a> </h3> <p>An issue is under development when a developer begins implementing the issue. In most cases, the research phase should have been completed. But it may be necessary for the developer to continue to ask questions or conduct research as they work on the issue.</p> <h3 id="done"> Done <a href="#done" class="book_heading_anchor" title="Link to Done section">#</a> </h3> <p>Work on the issue has been completed and all code has been merged. Close the issue.</p> <h2 id="code-contributions"> Code Contributions <a href="#code-contributions" class="book_heading_anchor" title="Link to Code Contributions section">#</a> </h2> <p>This section will describe everything you need to know to get your changes committed to our software. We assume that you are familiar with git, version control, pull requests and integration testing.</p> <h3 id="before-you-begin"> Before you Begin <a href="#before-you-begin" class="book_heading_anchor" title="Link to Before you Begin section">#</a> </h3> <p>We almost never merge code from a contributor when it hasn’t been discussed with us in advance. Before you start writing code, please discuss your plans with the development team. We are happy to talk through your proposals in the <a href="https://forum.pkp.sfu.ca/c/questions/feature-requests/8">feature request forum</a> or an appropriate <a href="https://github.com/pkp/pkp-lib/issues/">GitHub issue</a>.</p> <blockquote class="tip"> <p>If you want to draw our attention to your proposal on the forum, let us know that you plan to contribute the code. We are overwhelmed with requests but always have time for contributors.</p> </blockquote> <h3 id="source-code"> Source Code <a href="#source-code" class="book_heading_anchor" title="Link to Source Code section">#</a> </h3> <p>In order to contribute code, you must run the applications from the source code. Learn how to <a href="/dev/documentation/en/getting-started">install the applications from source</a> in your local development environment.</p> <h3 id="branches"> Branches <a href="#branches" class="book_heading_anchor" title="Link to Branches section">#</a> </h3> <p>Before you begin work, ask in the appropriate GitHub issue what branch you should work against. We are usually working against one of these branches:</p> <ul> <li>The <code class="language-plaintext highlighter-rouge">main</code> branch is where all work on future releases is done. All new features are contributed to this branch.</li> <li>There are <code class="language-plaintext highlighter-rouge">stable-*_*_*</code> branches for each of our stable versions. For example <code class="language-plaintext highlighter-rouge">stable-3_3_0</code> for the 3.3 LTS (Long-Term Support) version. We only accept bug fixes in the most recent stable branch or the LTS branch.</li> </ul> <h3 id="commits"> Commits <a href="#commits" class="book_heading_anchor" title="Link to Commits section">#</a> </h3> <p>All commits must include a reference to the GitHub issue that they address. For example, if your pull request fixes a bug for GitHub issue 1572, your commit message should look like the following.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pkp/pkp-lib#1572 Fix wrong stage assignments during submission </code></pre></div></div> <p>Commit messages should contain a brief description of what was changed. A good commit message says what was changed <em>and why</em>.</p> <table> <thead> <tr> <th>BAD</th> <th>GOOD</th> </tr> </thead> <tbody> <tr> <td>pkp/pkp-lib#1572 Fix assignments</td> <td>pkp/pkp-lib#1572 Fix wrong stage assignments during submission</td> </tr> <tr> <td>pkp/pkp-lib#1572 Fix signature email</td> <td>pkp/pkp-lib#1572 Fix broken user signature in review assignment email</td> </tr> <tr> <td>pkp/pkp-lib#1572 Change class name</td> <td>pkp/pkp-lib#1572 Rename Article class to Submission to improve align all apps</td> </tr> </tbody> </table> <p>If you commit frequently, please squash your commits before opening a pull request. Large commits can use multi-line commit messages.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pkp/pkp-lib#1572 Added support for withdrawing submissions - Added Withdraw decision to each stage - Added UI button to editorial workflow - Added email templates for withdrawal requests </code></pre></div></div> <h3 id="pull-requests"> Pull Requests <a href="#pull-requests" class="book_heading_anchor" title="Link to Pull Requests section">#</a> </h3> <p>A pull request must pass our integration tests before it will be merged. Special commits are required to run the integration tests when changes are made against more than one repository. Read about how to <a href="https://docs.pkp.sfu.ca/dev/testing/en/continuous-integration">prepare your pull requests</a> for continuous testing.</p> <h4 id="code-review"> Code Review <a href="#code-review" class="book_heading_anchor" title="Link to Code Review section">#</a> </h4> <p>All code for our applications should be reviewed before it is merged. Code reviews help us:</p> <ul> <li>Improve the quality of our code and catch unexpected bugs</li> <li>Share knowledge and expertise among the team</li> <li>Spread awareness of how new features work</li> <li>Teach us about previous coding choices we have made that led to bugs</li> <li>Maintain consistency in coding style and syntax, so that the code remains easy to read</li> </ul> <p>Code reviews work best when they spark discussion between the coder and the reviewer. Sometimes, going directly to a code review is the easiest way for another developer to understand how and why you’ve chosen to solve a problem in a particular way.</p> <p>Some comments in code review are straightforward — for example, syntax and whitespace issues. But others are an opportunity to learn for both the coder and the reviewer. If you don’t understand a comment or disagree with a suggested change, a code review is a great place to discuss it.</p> <h4 id="what-to-expect-from-a-code-review"> What to expect from a code review <a href="#what-to-expect-from-a-code-review" class="book_heading_anchor" title="Link to What to expect from a code review section">#</a> </h4> <p>A good code review is an opportunity to reach a consensus. When a consensus between the coder and the reviewer can not be reached, a senior developer will make the decision. A code review is <strong>not</strong> an opportunity to disparage your code or criticize your coding ability.</p> <p>The <strong>coder</strong> should expect:</p> <ul> <li>To be treated with respect.</li> <li>To have mistakes or errors pointed out in a friendly, constructive manner.</li> <li>To be asked to explain how their code works or why a coding choice was made.</li> <li>To be asked to investigate any concerns highlighted by the reviewer.</li> </ul> <p>The <strong>reviewer</strong> should expect:</p> <ul> <li>To ask for clarification if there is anything about the code they do not understand.</li> <li>To be corrected in a friendly, constructive manner if they have misunderstood the purpose or function of the code.</li> <li>To be updated by the coder when any concerns have been addressed.</li> <li>To be able to call on other reviewers if their expertise is needed.</li> </ul> <h4 id="how-to-ask-for-a-code-review"> How to ask for a code review <a href="#how-to-ask-for-a-code-review" class="book_heading_anchor" title="Link to How to ask for a code review section">#</a> </h4> <p>Typically, the tests should pass for your pull request before asking for a code review. However, in some cases, you may be asked to open a draft pull request for code review even before it is ready for merge.</p> <p>To ask for a code review, post a description of the changes in the GitHub issue you are working on and list all of the related PRs. Here is an example.</p> <blockquote> <p>Here is the work that I’ve done on the new email notification. These changes add a new email template and modify the submission wizard to send the notification when it is submitted.</p> <p>Can someone review this?</p> <p>PRs:</p> <ul> <li>http://…</li> <li>http://…</li> <li>http://…</li> </ul> </blockquote> <p>Please do not try to assign a reviewer using GitHub’s assign review tool. Our team will select an appropriate reviewer.</p> <p>When you have updated your code in response to a code review, post another comment in the issue to let the reviewer know that you are ready for a second round of review.</p> <h4 id="how-to-make-a-good-pull-request"> How to make a good pull request <a href="#how-to-make-a-good-pull-request" class="book_heading_anchor" title="Link to How to make a good pull request section">#</a> </h4> <p>Remember that your pull request and code review creates work for someone else. The following will make it as easy as possible to review your code.</p> <ol> <li>Only include changes in your pull request that are required to complete the task. It is tempting to clean up type hinting, syntax or code organisation as you go. But it can be very difficult for the reviewer to look through 100 lines of code changes to find the 5 lines that fixed the bug. When possible, implement these changes in a separate PR.</li> <li>Be as clear and concise as possible in your description. The reviewer may not understand the bug or feature that the pull request addresses. A clear description of the problem and the approach you took to solve it will help your reviewer give a better review. If user interactions are involved, screenshots or videos can be very helpful!</li> <li>Open your pull request against the correct branch. Bug fixes are usually opened against a stable branch while new features are usually opened against the <code class="language-plaintext highlighter-rouge">main</code> branch.</li> </ol> <h2 id="code-style"> Code Style <a href="#code-style" class="book_heading_anchor" title="Link to Code Style section">#</a> </h2> <p>We use automated code formatting to ensure that code follows a consistent style. Our code repositories are configured with pre-commit hooks. Every time you make a commit, your changes should be automatically formatted with <a href="https://github.com/squizlabs/PHP_CodeSniffer">PHP CodeSniffer</a> (PSR-12) and <a href="https://cli.vuejs.org/">Vue CLI</a>.</p> <p>When committing to one of the application repositories, you should see this:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>git commit <span class="nt">-m</span> <span class="s2">"pkp/pkp-lib#1234 Example commit"</span> husky <span class="o">></span> pre-commit <span class="o">(</span>node v14.17.3<span class="o">)</span> ✔ Preparing... ✔ Running tasks... ✔ Applying modifications... ✔ Cleaning up... <span class="o">[</span>main 1abc72ca2a] pkp/pkp-lib#1234 Example commit 1 file changed, 0 insertions<span class="o">(</span>+<span class="o">)</span>, 0 deletions<span class="o">(</span>-<span class="o">)</span> create mode 100644 example.php </code></pre></div></div> <p>When committing to <a href="https://github.com/pkp/pkp-lib"><code class="language-plaintext highlighter-rouge">pkp-lib</code></a>, you should see this:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>git commit <span class="nt">-m</span> <span class="s2">"pkp/pkp-lib#1234 Example commit"</span> Loaded config default from <span class="s2">".php-cs-fixer.php"</span><span class="nb">.</span> Using cache file <span class="s2">".php-cs-fixer.cache"</span><span class="nb">.</span> Checked all files <span class="k">in </span>0.058 seconds, 14.000 MB memory used ✔ Files formatted successfully. <span class="o">[</span>i7191_submission_wizard ecb92171e] pkp/pkp-lib#1234 Example commit 1 file changed, 0 insertions<span class="o">(</span>+<span class="o">)</span>, 0 deletions<span class="o">(</span>-<span class="o">)</span> create mode 100644 example.php </code></pre></div></div> <p>When committing to the <a href="https://github.com/pkp/ui-library"><code class="language-plaintext highlighter-rouge">ui-library</code></a>, you should see this:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>git commit <span class="nt">-m</span> <span class="s2">"pkp/pkp-lib#1234 Example commit"</span> <span class="o">></span> running pre-commit hook: lint-staged ✔ Preparing... ✔ Running tasks... ✔ Applying modifications... ✔ Cleaning up... <span class="o">[</span>i7191_submission_wizard 8f35a50] pkp/pkp-lib#1234 Example commit 1 file changed, 0 insertions<span class="o">(</span>+<span class="o">)</span>, 0 deletions<span class="o">(</span>-<span class="o">)</span> create mode 100644 example.js </code></pre></div></div> <p>If these actions are not run when you make a commit, please stop and troubleshoot these tools before continuing. If you open a pull request without formatted code, you may be asked to go back and restage your work.</p> <h3 id="php"> PHP <a href="#php" class="book_heading_anchor" title="Link to PHP section">#</a> </h3> <p>In addition to the code formatter, we prefer PHP code that follows the conventions below.</p> <h4 id="pascalcase-and-camelcase"> PascalCase and camelCase <a href="#pascalcase-and-camelcase" class="book_heading_anchor" title="Link to PascalCase and camelCase section">#</a> </h4> <p>Use <a href="https://techterms.com/definition/pascalcase">PascalCase</a> for class names and <a href="https://en.wikipedia.org/wiki/Camel_case">camelCase</a> for function names and variables.</p> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">use</span> <span class="nc">PKP\user\UserCache</span><span class="p">;</span> <span class="kd">class</span> <span class="nc">UserIdentityRecord</span> <span class="p">{</span> <span class="k">public</span> <span class="k">function</span> <span class="n">getUser</span><span class="p">(</span><span class="kt">int</span> <span class="nv">$userId</span><span class="p">):</span> <span class="kt">User</span> <span class="p">{</span> <span class="nv">$userCache</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="nf">getFromCache</span><span class="p">(</span><span class="nc">UserCache</span><span class="o">::</span><span class="n">class</span><span class="p">,</span> <span class="nv">$userId</span><span class="p">);</span> <span class="k">if</span> <span class="p">(</span><span class="nv">$userCache</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$userCache</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="nc">Repo</span><span class="o">::</span><span class="nf">user</span><span class="p">()</span><span class="o">-></span><span class="nf">get</span><span class="p">(</span><span class="nv">$userId</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <h4 id="type-hints"> Type Hints <a href="#type-hints" class="book_heading_anchor" title="Link to Type Hints section">#</a> </h4> <p>Use type hints.</p> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">use</span> <span class="nc">APP\user\User</span><span class="p">;</span> <span class="kd">class</span> <span class="nc">Example</span> <span class="p">{</span> <span class="k">public</span> <span class="k">function</span> <span class="n">getUser</span><span class="p">(</span><span class="kt">int</span> <span class="nv">$id</span><span class="p">):</span> <span class="kt">User</span> <span class="p">{</span> <span class="c1">//</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>Annotate nullable types with <code class="language-plaintext highlighter-rouge">?</code>.</p> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">use</span> <span class="nc">APP\user\User</span><span class="p">;</span> <span class="kd">class</span> <span class="nc">Example</span> <span class="p">{</span> <span class="k">public</span> <span class="k">function</span> <span class="n">getUser</span><span class="p">(</span><span class="kt">int</span> <span class="nv">$id</span><span class="p">):</span> <span class="kt">?User</span> <span class="p">{</span> <span class="c1">//</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>Add a <code class="language-plaintext highlighter-rouge">void</code> return type when functions return null.</p> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">class</span> <span class="nc">Submission</span> <span class="p">{</span> <span class="k">public</span> <span class="k">function</span> <span class="n">recordDecision</span><span class="p">():</span> <span class="kt">void</span> <span class="p">{</span> <span class="nv">$this</span><span class="o">-></span><span class="nf">record</span><span class="p">();</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>Avoid <a href="https://www.geeksforgeeks.org/php-8-union-types/">union types</a>.</p> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">use</span> <span class="nc">APP\user\User</span><span class="p">;</span> <span class="kd">class</span> <span class="nc">Example</span> <span class="p">{</span> <span class="k">public</span> <span class="k">function</span> <span class="n">getUser</span><span class="p">(</span><span class="kt">int</span><span class="o">|</span><span class="n">string</span> <span class="nv">$id</span><span class="p">):</span> <span class="kt">User</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="nb">is_int</span><span class="p">(</span><span class="nv">$id</span><span class="p">))</span> <span class="p">{</span> <span class="c1">//</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="c1">//</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>Except when a union type uses well-defined, compatible types.</p> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">use</span> <span class="nc">APP\decision\Accept</span><span class="p">;</span> <span class="kn">use</span> <span class="nc">APP\decision\Decline</span><span class="p">;</span> <span class="kd">class</span> <span class="nc">Submission</span> <span class="p">{</span> <span class="k">public</span> <span class="k">function</span> <span class="n">recordDecision</span><span class="p">(</span><span class="kt">Accept</span><span class="o">|</span><span class="nc">Decline</span> <span class="nv">$decision</span><span class="p">):</span> <span class="kt">void</span> <span class="p">{</span> <span class="nv">$decision</span><span class="o">-></span><span class="nf">record</span><span class="p">();</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>Consider type-hinting against an <a href="https://www.zend.com/blog/what-interface-php">interface</a> when union types are necessary.</p> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">namespace</span> <span class="nn">PKP\decision\interface</span><span class="p">;</span> <span class="kd">interface</span> <span class="nc">AcceptOrDecline</span> <span class="p">{</span> <span class="k">public</span> <span class="k">function</span> <span class="n">record</span><span class="p">():</span> <span class="kt">void</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">namespace</span> <span class="nn">APP\decision</span><span class="p">;</span> <span class="kn">use</span> <span class="nc">PKP\decision\interface\AcceptOrDecline</span><span class="p">;</span> <span class="kd">class</span> <span class="nc">Accept</span> <span class="kd">implements</span> <span class="nc">AcceptOrDecline</span> <span class="p">{</span> <span class="k">public</span> <span class="k">function</span> <span class="n">record</span><span class="p">():</span> <span class="kt">void</span> <span class="p">{</span> <span class="c1">//</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">use</span> <span class="nc">PKP\decision\interface\AcceptOrDecline</span><span class="p">;</span> <span class="kd">class</span> <span class="nc">Submission</span> <span class="p">{</span> <span class="k">public</span> <span class="k">function</span> <span class="n">recordDecision</span><span class="p">(</span><span class="kt">AcceptOrDecline</span> <span class="nv">$decision</span><span class="p">):</span> <span class="kt">void</span> <span class="p">{</span> <span class="nv">$decision</span><span class="o">-></span><span class="nf">record</span><span class="p">();</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <h4 id="docblocks"> Docblocks <a href="#docblocks" class="book_heading_anchor" title="Link to Docblocks section">#</a> </h4> <p>Add a docblock to every method. A good docblock will say what the method does and how it is intended to be used.</p> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Submission</span> <span class="p">{</span> <span class="cd">/** * Record an editorial decision for this submission */</span> <span class="k">public</span> <span class="k">function</span> <span class="n">recordDecision</span><span class="p">(</span><span class="kt">AcceptOrDecline</span> <span class="nv">$decision</span><span class="p">):</span> <span class="kt">void</span> <span class="p">{</span> <span class="nv">$decision</span><span class="o">-></span><span class="nf">record</span><span class="p">();</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>Don’t add <code class="language-plaintext highlighter-rouge">@param</code> statements unless the type hint needs further explanation.</p> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Submission</span> <span class="p">{</span> <span class="cd">/** * Record an editorial decision for this submission */</span> <span class="k">public</span> <span class="k">function</span> <span class="n">recordDecision</span><span class="p">(</span><span class="kt">AcceptOrDecline</span> <span class="nv">$decision</span><span class="p">):</span> <span class="kt">void</span> <span class="p">{</span> <span class="nv">$decision</span><span class="o">-></span><span class="nf">record</span><span class="p">();</span> <span class="p">}</span> <span class="cd">/** * Get all of this submission's publications with the * provided status * * @param string $status One of the Submission::STATUS_ constants. */</span> <span class="k">public</span> <span class="k">function</span> <span class="n">getPublicationsWithStatus</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$status</span><span class="p">):</span> <span class="kt">array</span> <span class="p">{</span> <span class="k">return</span> <span class="p">[</span><span class="mf">...</span><span class="p">];</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>Use the <code class="language-plaintext highlighter-rouge">[]</code> syntax to type hint arrays.</p> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">use</span> <span class="nc">APP\publication\Publication</span><span class="p">;</span> <span class="kd">class</span> <span class="nc">Submission</span> <span class="p">{</span> <span class="cd">/** * Get all of this submission's publications with the * provided status * * @param string[] $statuses One or more of the Submission::STATUS_ constants. * @return Publication[] */</span> <span class="k">public</span> <span class="k">function</span> <span class="n">getPublicationsWithStatus</span><span class="p">(</span><span class="kt">array</span> <span class="nv">$status</span><span class="p">):</span> <span class="kt">array</span> <span class="p">{</span> <span class="k">return</span> <span class="p">[</span><span class="mf">...</span><span class="p">];</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>Don’t use <code class="language-plaintext highlighter-rouge">@copydoc</code> to refer to a parent method.</p> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">namespace</span> <span class="nn">PKP\submission</span><span class="p">;</span> <span class="kn">use</span> <span class="nc">APP\publication\Publication</span><span class="p">;</span> <span class="kd">class</span> <span class="nc">Submission</span> <span class="p">{</span> <span class="cd">/** * Get the current publication */</span> <span class="k">public</span> <span class="k">function</span> <span class="n">getCurrentPublication</span><span class="p">():</span> <span class="kt">?Publication</span> <span class="p">{</span> <span class="c1">//</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">namespace</span> <span class="nn">APP\submission</span><span class="p">;</span> <span class="kn">use</span> <span class="nc">APP\publication\Publication</span><span class="p">;</span> <span class="kn">use</span> <span class="nc">PKP\submission\Submission</span> <span class="k">as</span> <span class="nc">BaseSubmission</span><span class="p">;</span> <span class="kd">class</span> <span class="nc">Submission</span> <span class="kd">extends</span> <span class="nc">BaseSubmission</span><span class="p">;</span> <span class="p">{</span> <span class="k">public</span> <span class="k">function</span> <span class="n">getCurrentPublication</span><span class="p">():</span> <span class="kt">?Publication</span> <span class="p">{</span> <span class="k">return</span> <span class="k">parent</span><span class="o">::</span><span class="nf">getCurrentPublication</span><span class="p">();</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>Don’t use inline comments to explain how a method works.</p> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">use</span> <span class="nc">APP\submission\Submission</span><span class="p">;</span> <span class="kd">class</span> <span class="nc">DOIRepository</span> <span class="p">{</span> <span class="cd">/** * Get the DOI pattern for a submission */</span> <span class="k">public</span> <span class="k">function</span> <span class="n">getSubmissionDoiPattern</span><span class="p">(</span><span class="kt">Submission</span> <span class="nv">$submission</span><span class="p">):</span> <span class="kt">void</span> <span class="p">{</span> <span class="nv">$doiPattern</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="nf">getDoiPattern</span><span class="p">();</span> <span class="c1">// Add the issue ID to the DOI pattern if</span> <span class="c1">// the submission is assigned to an issue</span> <span class="k">if</span> <span class="p">(</span><span class="nv">$submission</span><span class="o">-></span><span class="nf">getData</span><span class="p">(</span><span class="s1">'issueId'</span><span class="p">))</span> <span class="p">{</span> <span class="nv">$doiPattern</span> <span class="o">=</span> <span class="nb">str_replace</span><span class="p">(</span> <span class="nv">$doiPattern</span><span class="p">,</span> <span class="s1">'%i'</span><span class="p">,</span> <span class="nv">$submission</span><span class="o">-></span><span class="nf">getData</span><span class="p">(</span><span class="s1">'issueId'</span><span class="p">)</span> <span class="p">);</span> <span class="p">}</span> <span class="k">return</span> <span class="nv">$doiPattern</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>Move inline comments that explain the method to the docblock.</p> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">use</span> <span class="nc">APP\submission\Submission</span><span class="p">;</span> <span class="kd">class</span> <span class="nc">DOIRepository</span> <span class="p">{</span> <span class="cd">/** * Get the DOI pattern for a submission * * If a submission is not assigned to an issue, any * DOI pattern containing %i will not be converted. */</span> <span class="k">public</span> <span class="k">function</span> <span class="n">getSubmissionDoiPattern</span><span class="p">(</span><span class="kt">Submission</span> <span class="nv">$submission</span><span class="p">):</span> <span class="kt">void</span> <span class="p">{</span> <span class="nv">$doiPattern</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="nf">getDoiPattern</span><span class="p">();</span> <span class="k">if</span> <span class="p">(</span><span class="nv">$submission</span><span class="o">-></span><span class="nf">getData</span><span class="p">(</span><span class="s1">'issueId'</span><span class="p">))</span> <span class="p">{</span> <span class="nv">$doiPattern</span> <span class="o">=</span> <span class="nb">str_replace</span><span class="p">(</span> <span class="nv">$doiPattern</span><span class="p">,</span> <span class="s1">'%i'</span><span class="p">,</span> <span class="nv">$submission</span><span class="o">-></span><span class="nf">getData</span><span class="p">(</span><span class="s1">'issueId'</span><span class="p">)</span> <span class="p">);</span> <span class="p">}</span> <span class="k">return</span> <span class="nv">$doiPattern</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>Avoid inline comments when you need to clarify ambiguous variable names.</p> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Check all submissions</span> <span class="k">foreach</span> <span class="p">(</span><span class="nv">$items</span> <span class="k">as</span> <span class="nv">$item</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span> </code></pre></div></div> <p>Use variable names instead.</p> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">foreach</span> <span class="p">(</span><span class="nv">$items</span> <span class="k">as</span> <span class="nv">$submission</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span> </code></pre></div></div> <h4 id="constants"> Constants <a href="#constants" class="book_heading_anchor" title="Link to Constants section">#</a> </h4> <p>Avoid using numbers or strings to represent states or properties.</p> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// AVOID</span> <span class="k">if</span> <span class="p">(</span><span class="nv">$status</span> <span class="o">===</span> <span class="s1">'published'</span><span class="p">)</span> <span class="p">{</span> <span class="c1">//</span> <span class="p">}</span> <span class="k">elseif</span> <span class="p">(</span><span class="nv">$status</span> <span class="o">===</span> <span class="s1">'scheduled'</span><span class="p">)</span> <span class="p">{</span> <span class="c1">//</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="c1">//</span> <span class="p">}</span> </code></pre></div></div> <p>Use constants instead.</p> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Status</span> <span class="p">{</span> <span class="k">const</span> <span class="no">PUBLISHED</span> <span class="o">=</span> <span class="s1">'published'</span><span class="p">;</span> <span class="k">const</span> <span class="no">SCHEDULED</span> <span class="o">=</span> <span class="s1">'scheduled'</span><span class="p">;</span> <span class="k">const</span> <span class="no">QUEUED</span> <span class="o">=</span> <span class="s1">'queued'</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="p">(</span><span class="nv">$status</span> <span class="o">===</span> <span class="nc">Status</span><span class="o">::</span><span class="no">PUBLISHED</span><span class="p">)</span> <span class="p">{</span> <span class="c1">//</span> <span class="p">}</span> <span class="k">elseif</span> <span class="p">(</span><span class="nv">$status</span> <span class="o">===</span> <span class="nc">Status</span><span class="o">::</span><span class="no">SCHEDULED</span><span class="p">)</span> <span class="p">{</span> <span class="c1">//</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="c1">//</span> <span class="p">}</span> </code></pre></div></div> <h4 id="flatten-conditional-blocks"> Flatten Conditional Blocks <a href="#flatten-conditional-blocks" class="book_heading_anchor" title="Link to Flatten Conditional Blocks section">#</a> </h4> <p>Avoid deeply nested conditional blocks.</p> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// AVOID</span> <span class="k">function</span> <span class="n">show</span><span class="p">(</span><span class="nv">$status</span><span class="p">,</span> <span class="nv">$active</span><span class="p">,</span> <span class="nv">$item</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="nv">$status</span> <span class="o">===</span> <span class="nc">Status</span><span class="o">::</span><span class="no">PUBLISHED</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="nv">$active</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$item</span><span class="o">-></span><span class="nf">show</span><span class="p">();</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="nv">$item</span><span class="o">-></span><span class="nf">showPreview</span><span class="p">();</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="nv">$page</span><span class="o">-></span><span class="nf">hidden</span><span class="p">();</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>Return early to “flatten” the logic.</p> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span> <span class="n">show</span><span class="p">(</span><span class="nv">$status</span><span class="p">,</span> <span class="nv">$active</span><span class="p">,</span> <span class="nv">$item</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="nv">$status</span> <span class="o">!===</span> <span class="nc">Status</span><span class="o">::</span><span class="no">PUBLISHED</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$page</span><span class="o">-></span><span class="nf">hidden</span><span class="p">();</span> <span class="k">return</span><span class="p">;</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="nv">$active</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$item</span><span class="o">-></span><span class="nf">show</span><span class="p">();</span> <span class="k">return</span><span class="p">;</span> <span class="p">}</span> <span class="nv">$item</span><span class="o">-></span><span class="nf">showPreview</span><span class="p">();</span> <span class="p">}</span> </code></pre></div></div> <h4 id="variable-assignment"> Variable Assignment <a href="#variable-assignment" class="book_heading_anchor" title="Link to Variable Assignment section">#</a> </h4> <p>Avoid nested conditional blocks when assigning or returning values.</p> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// AVOID</span> <span class="k">function</span> <span class="n">getStatus</span><span class="p">(</span><span class="nv">$object</span><span class="p">):</span> <span class="kt">?int</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="nv">$object</span><span class="o">-></span><span class="nf">isA</span><span class="p">())</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$a</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$b</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>Use ternary operators when a variable is being assigned or returned.</p> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span> <span class="n">getStatus</span><span class="p">(</span><span class="nv">$object</span><span class="p">):</span> <span class="kt">?int</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$object</span><span class="o">-></span><span class="nf">isA</span><span class="p">()</span> <span class="o">?</span> <span class="nv">$a</span> <span class="o">:</span> <span class="nv">$b</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> <p>Use your judgement when working with complex conditions. Sometimes a conditional block is ok.</p> <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// This would be confusing if it only</span> <span class="c1">// used ternary operators.</span> <span class="k">function</span> <span class="n">getStatus</span><span class="p">(</span><span class="nv">$object</span><span class="p">):</span> <span class="kt">?int</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="nv">$object</span><span class="o">-></span><span class="nf">isA</span><span class="p">()</span> <span class="o">&&</span> <span class="nv">$object</span><span class="o">-></span><span class="nf">otherCondition</span><span class="p">())</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$object</span><span class="o">-></span><span class="nf">hasC</span><span class="p">()</span> <span class="o">?</span> <span class="nv">$a</span> <span class="o">:</span> <span class="nv">$b</span><span class="p">;</span> <span class="p">}</span> <span class="k">elseif</span> <span class="p">(</span><span class="nv">$d</span> <span class="o">===</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$f</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="nv">$g</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> <h3 id="vuejavascript"> Vue/JavaScript <a href="#vuejavascript" class="book_heading_anchor" title="Link to Vue/JavaScript section">#</a> </h3> <p>Our <a href="/dev/ui-library/dev">UI Library</a> uses <a href="https://vuejs.org/">Vue</a>, a component-based JavaScript framework. When receiving contributions to the UI Library, we prefer code that follows the conventions below.</p> <h4 id="follow-the-guidance"> Follow the Guidance <a href="#follow-the-guidance" class="book_heading_anchor" title="Link to Follow the Guidance section">#</a> </h4> <p>The <a href="/dev/ui-library/dev">UI Library</a> is also a usage guide. Before writing code for the UI Library, please read about accessibility, learn about the utilities, and read the guidance for the components you want to use.</p> <p>Always try to use a component in the way that it was intended.</p> <h4 id="props"> Props <a href="#props" class="book_heading_anchor" title="Link to Props section">#</a> </h4> <p>Declare the type of a component’s props.</p> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="k">default</span> <span class="p">{</span> <span class="na">props</span><span class="p">:</span> <span class="p">{</span> <span class="na">currentPage</span><span class="p">:</span> <span class="p">{</span> <span class="na">type</span><span class="p">:</span> <span class="nb">Number</span><span class="p">,</span> <span class="na">required</span><span class="p">:</span> <span class="kc">true</span> <span class="p">},</span> <span class="na">isLoading</span><span class="p">:</span> <span class="p">{</span> <span class="na">type</span><span class="p">:</span> <span class="nb">Boolean</span><span class="p">,</span> <span class="na">default</span><span class="p">:</span> <span class="kc">false</span> <span class="p">},</span> <span class="na">lastPage</span><span class="p">:</span> <span class="p">{</span> <span class="na">type</span><span class="p">:</span> <span class="nb">Number</span><span class="p">,</span> <span class="na">required</span><span class="p">:</span> <span class="kc">true</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>List props, computed properties, and methods in alphabetical order.</p> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="k">default</span> <span class="p">{</span> <span class="na">props</span><span class="p">:</span> <span class="p">{</span> <span class="na">ant</span><span class="p">:</span> <span class="p">{</span> <span class="na">type</span><span class="p">:</span> <span class="nb">Number</span><span class="p">,</span> <span class="na">required</span><span class="p">:</span> <span class="kc">true</span> <span class="p">},</span> <span class="na">beetle</span><span class="p">:</span> <span class="p">{</span> <span class="na">type</span><span class="p">:</span> <span class="nb">Boolean</span><span class="p">,</span> <span class="na">default</span><span class="p">:</span> <span class="kc">false</span> <span class="p">},</span> <span class="na">cat</span><span class="p">:</span> <span class="p">{</span> <span class="na">type</span><span class="p">:</span> <span class="nb">Number</span><span class="p">,</span> <span class="na">required</span><span class="p">:</span> <span class="kc">true</span> <span class="p">}</span> <span class="p">},</span> <span class="na">computed</span><span class="p">:</span> <span class="p">{</span> <span class="nx">blue</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="dl">''</span><span class="p">;</span> <span class="p">},</span> <span class="nx">red</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="dl">''</span><span class="p">;</span> <span class="p">}</span> <span class="nx">yellow</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="dl">''</span><span class="p">;</span> <span class="p">}</span> <span class="p">},</span> <span class="na">methods</span><span class="p">:</span> <span class="p">{</span> <span class="nx">arm</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="dl">''</span><span class="p">;</span> <span class="p">},</span> <span class="nx">head</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="dl">''</span><span class="p">;</span> <span class="p">}</span> <span class="nx">leg</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="dl">''</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <h4 id="computed-properties"> Computed Properties <a href="#computed-properties" class="book_heading_anchor" title="Link to Computed Properties section">#</a> </h4> <p>Use computed properties instead of methods when you need to get information from a bigger set of data.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><template> <div> Don't do this: {{ getVersionCount(submission) }} Do this: {{ versionCount }} </div> </template> </code></pre></div></div> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="k">default</span> <span class="p">{</span> <span class="na">props</span><span class="p">:</span> <span class="p">{</span> <span class="na">submission</span><span class="p">:</span> <span class="p">{</span> <span class="na">type</span><span class="p">:</span> <span class="nb">Object</span><span class="p">,</span> <span class="na">required</span><span class="p">:</span> <span class="kc">true</span> <span class="p">}</span> <span class="p">},</span> <span class="na">computed</span><span class="p">:</span> <span class="p">{</span> <span class="nx">versionCount</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="k">this</span> <span class="p">.</span><span class="nx">submission</span> <span class="p">.</span><span class="nx">publications</span> <span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="p">}</span> <span class="p">},</span> <span class="na">methods</span><span class="p">:</span> <span class="p">{</span> <span class="nx">getVersionCount</span><span class="p">(</span><span class="nx">submission</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nx">submission</span> <span class="p">.</span><span class="nx">publications</span> <span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <h4 id="debounce"> Debounce <a href="#debounce" class="book_heading_anchor" title="Link to Debounce section">#</a> </h4> <p>User input events, such as dragging or typing, may fire hundreds of times in a second. Debounce code that fires in response to user events to prevent browser lag.</p> <div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><template></span> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="err">@</span><span class="na">change=</span><span class="s">"inputChanged"</span><span class="nt">></span> <span class="nt"></template></span> </code></pre></div></div> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="nx">debounce</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">debounce</span><span class="dl">'</span><span class="p">;</span> <span class="k">export</span> <span class="k">default</span> <span class="p">{</span> <span class="na">methods</span><span class="p">:</span> <span class="p">{</span> <span class="na">inputChanged</span><span class="p">:</span> <span class="nx">debounce</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span> <span class="k">this</span><span class="p">.</span><span class="nx">$emit</span><span class="p">(</span><span class="dl">'</span><span class="s1">search</span><span class="dl">'</span><span class="p">,</span> <span class="nx">value</span><span class="p">);</span> <span class="p">},</span> <span class="mi">250</span><span class="p">)</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <h2 id="documentation"> Documentation <a href="#documentation" class="book_heading_anchor" title="Link to Documentation section">#</a> </h2> <p>You may be asked to update documentation when you make a code contribution. Contributions may effect documentation in the following ways.</p> <h3 id="user-guides"> User Guides <a href="#user-guides" class="book_heading_anchor" title="Link to User Guides section">#</a> </h3> <p>When your changes effect what a user sees or how a user completes a task, please tell your code reviewer. They will notify the documentation interest group.</p> <p>For example, if you change the reviewer selection list, the screenshots and text in the Learning OJS guide may need to change.</p> <h3 id="release-notebook"> Release Notebook <a href="#release-notebook" class="book_heading_anchor" title="Link to Release Notebook section">#</a> </h3> <p>When your change effects the way that a system administrator or coder interacts with the software, please file an issue in our <a href="https://github.com/pkp/pkp-docs/issues">documentation repository</a> so that we know to include details about this in the release notebook for the next major version. The issue title should follow this format:</p> <blockquote> <p>Release Notebook <version>: <subject></p> </blockquote> <p>Contributions that should be included in our release notebook include changes to:</p> <ul> <li>the config file</li> <li>hooks or events</li> <li>the system requirements</li> <li>the plugin API, the theme API, or theme templates</li> <li>application classes and methods that are likely to be used by third-party developers, such as stats service classes and repository methods</li> <li>the REST API</li> </ul> <h3 id="rest-api"> REST API <a href="#rest-api" class="book_heading_anchor" title="Link to REST API section">#</a> </h3> <p>Every change to the REST API must be documented in the <a href="https://github.com/pkp/pkp-docs#generate-rest-api-references">OpenAPI v3</a> specification file. After changing the specification, write a short summary of the change into the <a href="https://github.com/pkp/ojs/blob/faafccca8dffa0db9bba84164330810e5206571b/docs/dev/swagger-source.json#L6">description</a> of the file.</p> <p>Don’t forget to <a href="https://jsonlint.com/">validate the JSON file</a> and <a href="https://github.com/pkp/pkp-docs#generate-rest-api-references">generate the REST API documentation</a> to test your changes.</p> <hr> <p>Copyright: Simon Fraser University holds the copyright for work produced by the Public Knowledge Project and has placed its documentation under a <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.</p> <p><a href="https://creativecommons.org/licenses/by/4.0/"><img src="https://licensebuttons.net/l/by/4.0/88x31.png" alt="Creative Commons Attribution 4.0 International" title="Creative Commons Attribution 4.0 International" /></a></p> <div class="book__footer"> <div class="book__improve"> <a href="https://github.com/pkp/pkp-docs/edit/main/dev/contributors/index.md"> Edit this page </a> or <a href="https://pkp.sfu.ca/documentation-feedback/"> make a suggestion </a> </div> </div> </div> </div> <div class="book__sidebarScreen"></div> <div id="sidebar" class="book__sidebar"> <div class="book__summary"> <div class="book_page_toc"> <h2>Table of Contents</h2> <ul> <li><a href="#report-a-problem">Report a Problem</a></li> <li><a href="#teams">Teams</a></li> <li><a href="#issue-management">Issue Management</a> <ul> <li><a href="#triage">Triage</a></li> <li><a href="#investigation">Investigation</a></li> <li><a href="#todo">Todo</a></li> <li><a href="#under-research">Under Research</a></li> <li><a href="#under-development">Under Development</a></li> <li><a href="#done">Done</a></li> </ul> </li> <li><a href="#code-contributions">Code Contributions</a> <ul> <li><a href="#before-you-begin">Before you Begin</a></li> <li><a href="#source-code">Source Code</a></li> <li><a href="#branches">Branches</a></li> <li><a href="#commits">Commits</a></li> <li><a href="#pull-requests">Pull Requests</a></li> </ul> </li> <li><a href="#code-style">Code Style</a> <ul> <li><a href="#php">PHP</a></li> <li><a href="#vuejavascript">Vue/JavaScript</a></li> </ul> </li> <li><a href="#documentation">Documentation</a> <ul> <li><a href="#user-guides">User Guides</a></li> <li><a href="#release-notebook">Release Notebook</a></li> <li><a href="#rest-api">REST API</a></li> </ul> </li> </ul> </div> </div> <div class="book__backToHub"> <span class="fa fa-long-arrow-alt-left" aria-hidden="true"></span> <p>Back to <a href="/">all documentation</a>.</p> </div> <div class="book__spacer"></div> </div> </div> <div class="book__footerWrapper"> <div class="siteFooter"> <nav class="siteFooter__container"> <div class="siteFooter__top"> <div class="siteFooter__nav"> <div class="siteFooter__navHeader"> Contact Us </div> <p>Have a question or suggestion about PKP’s documentation and user guides? <a href="https://pkp.sfu.ca/documentation-feedback/">Use our documentation contact form</a>.</p> <p>If your message is not about documentation, please use the general <a href="https://pkp.sfu.ca/contact-us/">contact form</a>.</p> </div> <div class="siteFooter__nav"> <div class="siteFooter__navHeader"> Community </div> <p><a href="https://pkp.sfu.ca/documentation-interest-group/">Documentation Interest Group</a></p> <p><a href="/contributing/en/">Contributing Documentation</a></p> <p><a href="/translating-guide/">Translating Guide</a></p> <p><a href="https://forum.pkp.sfu.ca">Community Forum</a></p> </div> <div class="siteFooter__nav"> <div class="siteFooter__navHeader"> About </div> <p><a href="https://pkp.sfu.ca">Public Knowledge Project</a></p> <p><a href="https://pkpservices.sfu.ca/">PKP|Publishing Services</a></p> </div> <div class="siteFooter__logo"> <a href="https://pkp.sfu.ca"> <img src="/img/logo-on-grey.png" alt="Public Knowledge Project"> </a> <p>The Public Knowledge Project is a Core Facility of Simon Fraser University</p> <p>888 University Drive, Burnaby, B.C., Canada V5A 1S6</p> <p>We respectfully acknowledge that SFU occupies the unceded traditional territories of the Coast Salish peoples of the Musqueam, Squamish, and Tsleil-Waututh Nations.</p> </div> </div> <div class="siteFooter__bottom"> <p class="footer-copyright"><span class="terms-text"><a href="https://www.sfu.ca/contact/terms-conditions.html" target="_blank">TERMS & CONDITIONS</a> © SIMON FRASER UNIVERSITY.</span><span class="copyright-text"><img src="/img/creativecommons.svg" alt="Creative Commons logo" /><img src="/img/attribution.svg" alt="Attribution icon" /><a href="https://creativecommons.org/licenses/by/2.0/" target="_blank">CC-BY 2.0</a></span><span class="footer-copyright-separator"> | </span><span class="ab-link">Website by <a target="_blank" href="https://www.affinitybridge.com">Affinity Bridge</a></span></p> </div> </div> </div> </div> <script type="text/javascript">/** * Toggle the sidebar open/closed */ (function() { var sidebar = document.getElementById('sidebar'); var sidebarControl = document.getElementById('sidebarControl'); var isOpen = false; var sidebarOpenClass = ' -sidebarIsOpen'; if (!sidebar || !sidebarControl) { return; } // Toggle sidebar function toggle() { if (isOpen) { document.body.className = document.body.className.replace(new RegExp(sidebarOpenClass, 'g'), ''); } else { document.body.className = document.body.className + sidebarOpenClass; } isOpen = !isOpen; } sidebarControl.addEventListener('click', toggle); })(); </script> <script type="text/javascript">/** * Initialize smooth scrolling to anchor links * * See: https://github.com/cferdinandi/smooth-scroll */ (function() { function init() { if (typeof SmoothScroll === 'undefined') { setTimeout(init, 500); } else { var scroll = new SmoothScroll('a[href*="#"]', {easing: 'easeInOutCubic', offset:80}); } } init(); })(); </script> <!-- Global site tag (gtag.js) - Google Analytics --> <script async src="https://www.googletagmanager.com/gtag/js?id=UA-130558797-1"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-130558797-1'); </script> <!-- Hotjar Tracking Code for docs.pkp.sfu.ca --> <script> (function(h,o,t,j,a,r){ h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)}; h._hjSettings={hjid:2436159,hjsv:6}; a=o.getElementsByTagName('head')[0]; r=o.createElement('script');r.async=1; r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv; a.appendChild(r); })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv='); </script> <!-- Piwik/Matomo --> <script type="text/javascript"> var _paq = _paq || []; _paq.push(["setDocumentTitle", document.domain + "/" + document.title]); _paq.push(["setCookieDomain", "*.docs.pkp.sfu.ca"]); _paq.push(["setDomains", ["*.docs.pkp.sfu.ca"]]); _paq.push(["trackPageView"]); _paq.push(["enableLinkTracking"]); (function() { var u = (("https:" == document.location.protocol) ? "https" : "http") + "://" + "matomo.publicknowledgeproject.org/pkp/"; _paq.push(["setTrackerUrl", u + "piwik.php"]); _paq.push(["setSiteId", "40"]); var d = document, g = d.createElement("script"), s = d.getElementsByTagName("script")[0]; g.type = "text/javascript"; g.defer = true; g.async = true; g.src = u + "piwik.js"; s.parentNode.insertBefore(g, s); })(); </script> <!-- End Piwik Code --> </body> </html>