Contribute to plone.api
#
This section describes how to contribute to the plone.api
project.
It extends Contributing to Plone.
Prerequisites#
Prepare your system by installing prerequisites.
System libraries#
You need to install system libraries, as described in Prerequisites, with the exception of GNU make.
tox#
tox automates and standardizes testing in Python. Install tox into your Python user space with the following command.
python -m pip install --user tox
pre-commit#
plone.api
uses pre-commit to automate code quality checks before every commit.
Install pre-commit either with your system package manager. Alternatively you can install pre-commit into your Python user.
python -m pip install --user pre-commit
Once installed, set up the git hook scripts to run on every commit.
pre-commit install
Create development environment#
After satisfying the prerequisites, you are ready to create your development environment.
plone.api
uses tox
as a wrapper around coredev.buildout
to simplify development, whereas Plone core uses coredev.buildout
directly.
Start by changing your working directory to your project folder, and download the latest plone.api
source code.
cd <your_project_folder>
git clone https://github.com/plone/plone.api.git
Next go into the newly created directory, and build your environment.
cd plone.api
tox
Go make some tea while tox
runs all tasks listed by issuing the command tox -l
.
Open tox.ini
in your code editor to see all configured commands and what they do.
Some helpful tox
commands are shown below.
tox -e py39-plone-60 # run all tests for Python 3.9 and Plone 6
tox -e plone6docs # build documentation
tox -e livehtml # build, serve, and reload changes to documentation
tox -l # list all tox environments
git#
Use the following git branches when contributing to plone.api
.
- feature branches
All development for a new feature or bug fix must be done on a new branch.
main
Pull requests should be made from a feature branch against the
main
branch. When features and bug fixes are complete and approved, they are merged into themain
branch.
See also
Continuous integration#
plone.api
uses GitHub workflows for continuous integration.
On every push to the main
branch, GitHub runs its workflows for all tests and code quality checks.
GitHub workflows are configured in the directory .github/workflows
at the root of this package.
Documentation#
For every feature change or addition to plone.api
, you must add documentation of it.
plone.api
uses MyST for documentation syntax.
See also
After adding or modifying documentation, you can build the documentation with the following command.
tox -e plone6docs
Alternatively, you can automatically reload changes to the documentation as you edit it in a web browser.
tox -e livehtml
The plone.api
documentation is automatically generated from the documentation source files when its submodule is updated in the main Plone documentation
repository.
Add a function to an existing module#
This section describes how to add a new function foo
to plone.api
.
The function would go in the module plone.api.content
, located in the file src/plone/api/content.py
.
@mutually_exclusive_parameters('path', 'UID')
@at_least_one_of('path', 'UID')
def foo(path=None, UID=None):
"""Do foo.
:param path: Path to the object we want to get,
relative to the portal root.
:type path: string
:param UID: UID of the object we want to get.
:type UID: string
:returns: String
:raises:
:class:`~plone.api.exc.MissingParameterError`,
:class:`~plone.api.exc.InvalidParameterError`
:Example: :ref:`content-foo-example`
"""
return "foo"
Add documentation in docs/api/content.md
.
Narrative documentation should describe what your function does.
You should also write some tests in code blocks.
TestCase
methods, such as self.assertEqual()
, are available in doctests
.
See unittest.TestCase assert methods for all available methods.
The file is linked in /src/plone/api/tests/doctests/
, which includes the doctests in plone.api
's test setup.
The package manuel
allows you to write doctests as common Python code in code blocks.
The following example shows narrative documentation and doctests.
(content-foo-example)=
## Get the foo of an object
You can use the {meth}`api.content.foo` function to get the `foo` of an object.
```python
from plone import api
blog_foo = api.content.foo(path="/plone/blog")
```
% invisible-code-block: python
%
% self.assertEqual(blog_foo,"foo")
Code blocks are rendered in documentation.
```python
from plone import api
blog_foo = api.content.foo(path="/plone/blog")
```
Invisible code blocks are not rendered in documentation and can be used for tests.
% invisible-code-block: python
%
% self.assertEqual(blog_foo,"foo")
Invisible code blocks are also handy for enriching the namespace without cluttering the narrative documentation.
% invisible-code-block: python
%
% portal = api.portal.get()
% image = api.content.create(type='Image', id='image', container=portal)
% blog = api.content.create(type='Link', id='blog', container=portal)
Functions and examples in documentation are mutually referenced.
The function references the narrative documentation via the label content-foo-example
.
The narrative documentation references the API function documentation via {meth}`api.content.foo`
.
The documentation is rendered with a link from the API reference to the narrative documentation, which in turn links back to the API reference.