Restructure the dev manual

This moves lots of pages around. The high-level changes are

* Better main sections, so it's more *general*, *into*, *basics* and *details*
* Move more general topics to a *Basic* section, which are not
  app-specific
* Remove app docs to the stuff that is likely used, anything else goes
  into "Digging deeper"
* Move general guides into a prologue
* Try to *compress*/combine some pages with similar content
* Try to have better consistencs on level ob abstraction across pages
* Split app development and maintenance pages into two sections
* Integrate bugtracker info into prologue
* Integrate Android pages into client APIs section

Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
This commit is contained in:
Christoph Wurst
2020-06-22 18:35:59 +02:00
parent 547810edd8
commit 2647cd93c7
71 changed files with 228 additions and 105 deletions

View File

@@ -0,0 +1,58 @@
=============
Bootstrapping
=============
Every php process has a relatively short lifespan that lasts as long as the HTTP request or the invokation of the command
line program. At the beginning of this lifespan, Nextcloud initializes its services. At the same time, any additional apps
might want to register their services to Nextcloud as well. This event is called the *bootstrapping* and this chapter
shall shed some light on how to hook into this with an app.
.. _app-php:
app.php
-------
Nextcloud will ``require_once`` every installed and enabled app's ``appinfo/app.php`` file if it exists. The app can use
this file to run registrations of services, event listeners and similar.
To leverage the advantages of object-oriented programming, it's recommended to put the logic into an :ref:`application-php`
class and query an instance like
.. code-block:: php
<?php
declare(strict_types=1);
$app = \OC::$server->query(\OCA\MyApp\AppInfo\Application::class);
$app->registerHooks();
.. _application-php:
Application
-----------
An `Application` class shall serve as central initialization point of an app.
.. code-block:: php
<?php
declare(strict_types=1);
namespace OCA\MyApp\AppInfo;
use OCP\AppFramework\App;
class Application extends App {
public function registerHooks(): void {
\OCP\Util::connectHook('OC_User', 'pre_deleteUser', 'OCA\MyApp\Hooks\User', 'deleteUser');
}
}
.. note:: Nextcloud does not load this class for every request. You should query an instance inside your :ref:`app-php` to
load for every request, if desired.

View File

@@ -0,0 +1,13 @@
===============
App development
===============
.. toctree::
:maxdepth: 2
intro
tutorial
bootstrap
info
init
logging

View File

@@ -0,0 +1,371 @@
============
App metadata
============
.. sectionauthor:: Bernhard Posselt <dev@bernhard-posselt.com>
The :file:`appinfo/info.xml` contains metadata about the app. A detailed documentation can be found at the `app store documentation <https://nextcloudappstore.readthedocs.io/en/latest/developer.html#info-xml>`_.
The info.xml is validated using an XML Schema which can be accessed `online <https://apps.nextcloud.com/schema/apps/info.xsd>`_.
A minimum valid **info.xml** would look like this:
.. code-block:: xml
<?xml version="1.0"?>
<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>news</id>
<name>News</name>
<summary>An RSS/Atom feed reader</summary>
<description>An RSS/Atom feed reader</description>
<version>8.8.2</version>
<licence>agpl</licence>
<author>Bernhard Posselt</author>
<category>multimedia</category>
<bugs>https://github.com/nextcloud/news/issues</bugs>
<dependencies>
<nextcloud min-version="10"/>
</dependencies>
</info>
A full blown example would look like this (needs to be utf-8 encoded):
.. code-block:: xml
<?xml version="1.0"?>
<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>news</id>
<name lang="de">Nachrichten</name>
<name>News</name>
<summary lang="en">An RSS/Atom feed reader</summary>
<description lang="en"># Description\nAn RSS/Atom feed reader</description>
<description lang="de"><![CDATA[# Beschreibung\nEine Nachrichten App, welche mit [RSS/Atom](https://en.wikipedia.org/wiki/RSS) umgehen kann]]></description>
<version>8.8.2</version>
<licence>agpl</licence>
<author mail="mail@provider.com" homepage="http://example.com">Bernhard Posselt</author>
<author>Alessandro Cosentino</author>
<author>Jan-Christoph Borchardt</author>
<documentation>
<user>https://github.com/nextcloud/news/wiki#user-documentation</user>
<admin>https://github.com/nextcloud/news#readme</admin>
<developer>https://github.com/nextcloud/news/wiki#developer-documentation</developer>
</documentation>
<category>multimedia</category>
<category>tools</category>
<website>https://github.com/nextcloud/news</website>
<discussion>https://your.forum.com</discussion>
<bugs>https://github.com/nextcloud/news/issues</bugs>
<repository>https://github.com/nextcloud/news</repository>
<screenshot small-thumbnail="https://example.com/1-small.png">https://example.com/1.png</screenshot>
<screenshot>https://example.com/2.jpg</screenshot>
<dependencies>
<php min-version="5.6" min-int-size="64"/>
<database min-version="9.4">pgsql</database>
<database>sqlite</database>
<database min-version="5.5">mysql</database>
<command>grep</command>
<command>ls</command>
<lib min-version="2.7.8">libxml</lib>
<lib>curl</lib>
<lib>SimpleXML</lib>
<lib>iconv</lib>
<nextcloud min-version="9" max-version="10"/>
</dependencies>
<background-jobs>
<job>OCA\DAV\CardDAV\Sync\SyncJob</job>
</background-jobs>
<repair-steps>
<pre-migration>
<step>OCA\DAV\Migration\Classification</step>
</pre-migration>
<post-migration>
<step>OCA\DAV\Migration\Classification</step>
</post-migration>
<live-migration>
<step>OCA\DAV\Migration\GenerateBirthdays</step>
</live-migration>
<install>
<step>OCA\DAV\Migration\GenerateBirthdays</step>
</install>
<uninstall>
<step>OCA\DAV\Migration\GenerateBirthdays</step>
</uninstall>
</repair-steps>
<two-factor-providers>
<provider>OCA\AuthF\TwoFactor\Provider</provider>
</two-factor-providers>
<commands>
<command>A\Php\Class</command>
</commands>
<settings>
<admin>OCA\Theming\Settings\Admin</admin>
<admin-section>OCA\Theming\Settings\Section</admin-section>
</settings>
<activity>
<settings>
<setting>OCA\Files\Activity\Settings\FavoriteAction</setting>
<setting>OCA\Files\Activity\Settings\FileChanged</setting>
<setting>OCA\Files\Activity\Settings\FileCreated</setting>
<setting>OCA\Files\Activity\Settings\FileDeleted</setting>
<setting>OCA\Files\Activity\Settings\FileFavorite</setting>
<setting>OCA\Files\Activity\Settings\FileRestored</setting>
</settings>
<filters>
<filter>OCA\Files\Activity\Filter\FileChanges</filter>
<filter>OCA\Files\Activity\Filter\Favorites</filter>
</filters>
<providers>
<provider>OCA\Files\Activity\FavoriteProvider</provider>
<provider>OCA\Files\Activity\Provider</provider>
</providers>
</activity>
<navigations>
<navigation role="admin">
<id>files</id>
<name>Files</name>
<route>files.view.index</route>
<order>0</order>
<icon>app.svg</icon>
<type>link</type>
</navigation>
</navigations>
<collaboration>
<plugins>
<plugin type="collaborator-search" share-type="SHARE_TYPE_CIRCLE">OCA\Circles\Collaboration\v1\CollaboratorSearchPlugin</plugin>
</plugins>
</collaboration>
</info>
The following tags are validated and used in the following way:
id
* required
* must contain only lowercase ASCII characters and underscore
* must match the first folder in the archive
* will be used to identify the app
name
* required
* must occur at least once with **lang="en"** or no lang attribute
* can be translated by using multiple elements with different **lang** attribute values, language code needs to be set **lang** attribute
* will be rendered on the app detail page
summary
* optional
* if not provided the description element's text will be used
* must occur at least once with **lang="en"** or no lang attribute
* can be translated by using multiple elements with different **lang** attribute values, language code needs to be set **lang** attribute
* will be rendered on the app list page as short description
description
* required
* must occur at least once with **lang="en"** or no lang attribute
* can contain Markdown
* can be translated by using multiple elements with different **lang** attribute values, language code needs to be set **lang** attribute
* will be rendered on the app detail page
version
* required
* must be a `semantic version <http://semver.org/>`_ without build metadata, e.g. 9.0.1 or 9.1.0-alpha.1
licence
* required
* must contain **agpl**, **mpl*** and/or **apache** as the only valid values. These refer to the AGPLv3, MPL 2.0 and Apache License 2.0
author
* required
* can occur multiple times with different authors
* can contain a **mail** attribute which must be an email
* can contain a **homepage** which must be an URL
* will not (yet) be rendered on the App Store
* will be provided through the REST API
documentation/user
* optional
* must contain an URL to the user documentation
* will be rendered on the app detail page
documentation/admin
* optional
* must contain an URL to the admin documentation
* will be rendered on the app detail page
documentation/developer
* optional
* must contain an URL to the developer documentation
* will be rendered on the app detail page
category
* optional
* if not provided the category **tools** will be used
* must contain one of the following values:
* **customization**
* **files**
* **games**
* **integration**
* **monitoring**
* **multimedia**
* **office**
* **organization**
* **security**
* **social**
* **tools**
* old categories are migrated:
* **auth** will be converted to **security**
* can occur more than once with different categories
website
* optional
* must contain an URL to the project's homepage
* will be rendered on the app detail page
discussion
* optional
* must contain an URL to the project's discussion page/forum
* will be rendered on the app detail page as the "ask question or discuss" button
* if absent, it will default to our forum at https://help.nextcloud.com/ and create a new category in the apps category
bugs
* required
* must contain an URL to the project's bug tracker
* will be rendered on the app detail page
repository
* optional
* must contain an URL to the project's repository
* can contain a **type** attribute, **git**, **mercurial**, **subversion** and **bzr** are allowed values, defaults to **git**
* currently not used
screenshot
* optional
* must contain an HTTPS URL to an image
* can contain a **small-thumbnail** attribute which must contain an https url to an image. This image will be used as small preview (e.g. on the app list overview). Keep it small so it renders fast
* will be rendered on the app list and detail page in the given order
dependencies/php
* optional
* can contain a **min-version** attribute (maximum 3 digits separated by dots)
* can contain a **max-version** attribute (maximum 3 digits separated by dots)
* can contain a **min-int-size** attribute, 32 or 64 are allowed as valid values
* will be rendered on the app releases page
dependencies/database
* optional
* must contain the database name as text, **sqlite**, **pgsql** and **mysql** are allowed as valid values
* can occur multiple times with different databases
* can contain a **min-version** attribute (maximum 3 digits separated by dots)
* can contain a **max-version** attribute (maximum 3 digits separated by dots)
* will be rendered on the app releases page
dependencies/command
* optional
* must contain a linux command as text value
* can occur multiple times with different commands
* will be rendered on the app releases page
dependencies/lib
* optional
* will be rendered on the app releases page
* must contain a required php extension
* can occur multiple times with different php extensions
* can contain a **min-version** attribute (maximum 3 digits separated by dots)
* can contain a **max-version** attribute (maximum 3 digits separated by dots)
dependencies/nextcloud
* required on Nextcloud 11 or higher
* if absent white-listed owncloud versions will be taken from the owncloud element (see below)
* must contain a **min-version** attribute (maximum 3 digits separated by dots)
* can contain a **max-version** attribute (maximum 3 digits separated by dots)
background-jobs/job
* optional
* must contain a php class which is run as background jobs
* will not be used, only validated
repair-steps/pre-migration/step
* optional
* must contain a php class which is run before executing database migrations
* will not be used, only validated
repair-steps/post-migration/step
* optional
* must contain a php class which is run after executing database migrations
* will not be used, only validated
repair-steps/live-migration/step
* optional
* must contain a php class which is run after executing post-migration jobs
* will not be used, only validated
repair-steps/install/step
* optional
* must contain a php class which is run after installing the app
* will not be used, only validated
repair-steps/uninstall/step
* optional
* must contain a php class which is run after uninstalling the app
* will not be used, only validated
two-factor-providers/provider
* optional
* must contain a php class which is registered as two factor auth provider
* will not be used, only validated
commands/command
* optional
* must contain a php class which is registered as occ command
* will not be used, only validated
activity/settings/setting
* optional
* must contain a php class which implements OCP\Activity\ISetting and is used to add additional settings ui elements to the activity app
activity/filters/filter
* optional
* must contain a php class which implements OCP\Activity\IFilter and is used to add additional filters to the activity app
activity/providers/provider
* optional
* must contain a php class which implements OCP\Activity\IProvider and is used to react to events from the activity app
settings/admin
* optional
* must contain a php class which implements OCP\Settings\ISettings and returns the form to render for the global settings area
settings/admin-section
* optional
* must contain a php class which implements OCP\Settings\ISection and returns data to render navigation entries in the global settings area
navigations
* optional
* must contain at least one navigation element
navigations/navigation
* required
* must contain a name and route element
* denotes a navigation entry
* role denotes the visibility, all means everyone can see it, admin means only an admin can see the navigation entry, defaults to all
navigations/navigation/id
* optional
* the app id
* you can also create entries for other apps by setting an id other than your app one's
navigations/navigation/name
* required
* will be displayed below the navigation entry icon
* will be translated by the default translation tools
navigations/navigation/route
* required
* name of the route that will be used to generate the link
navigations/navigation/icon
* optional
* name of the icon which is looked up in the app's **img/** folder
* defaults to app.svg
navigations/navigation/order
* optional
* used to sort the navigation entries
* a higher order number means that the entry will be ordered further to the bottom
navigations/navigation/type
* optional
* can be either link or settings
* link means that the entry is added to the default app menu
* settings means that the entry is added to the right-side menu which also contains the personal, admin, users, help and logout entry
collaboration
* optional
* can contain plugins for collaboration search (e.g. supplying share dialog)
collaboration/plugins
* optional
* must contain at least one plugin
collaboration/plugins/plugin
* required
* the PHP class name of the plugin
* must contain **type** attribute (currently only *collaboration-search*). The class must implement OCP\Collaboration\Collaborators\ISearchPlugin.
* must contain **share-type** attribute, according to the specific \OCP\Share constants
The following character maximum lengths are enforced:
* All description Strings are database text fields and therefore not limited in size
* All other Strings have a maximum of 256 characters
The following elements are either deprecated or for internal use only and will fail the validation if present:
* **standalone**
* **default_enable**
* **shipped**
* **public**
* **remote**
* **requiremin**
* **requiremax**

View File

@@ -0,0 +1,62 @@
====================================
Navigation and pre-app configuration
====================================
.. sectionauthor:: Bernhard Posselt <dev@bernhard-posselt.com>
Adding a navigation entry
-------------------------
Navigation entries for apps can be created by adding a navigation section to the :file:`appinfo/info.xml` file, containing the name, order and route the navigation entry should link to. For details on the XML schema check the `app store documentation <https://nextcloudappstore.readthedocs.io/en/latest/developer.html#info-xml>`_.
.. code-block:: xml
<navigation>
<name>MyApp</name>
<route>myapp.page.index</route>
<order>0</order>
</navigation>
Further pre-app configuration
-----------------------------
The :file:`appinfo/app.php` is the first file that is loaded and executed in Nextcloud. Depending on the purpose of the app it is usually used to setup things that need to be available on every request to the server, like :doc:`backgroundjobs` and :doc:`hooks` registrations. This is how an example :file:`appinfo/app.php` could look like:
.. code-block:: php
<?php
// execute OCA\MyApp\BackgroundJob\Task::run when cron is called
\OC::$server->getJobList()->add('OCA\MyApp\BackgroundJob\Task');
// execute OCA\MyApp\Hooks\User::deleteUser before a user is being deleted
\OCP\Util::connectHook('OC_User', 'pre_deleteUser', 'OCA\MyApp\Hooks\User', 'deleteUser');
Initialization events
---------------------
Often apps do not need to load their JavaScript and CSS on every page. For this
purpose there are several events emitted that an app can act upon.
* `OCA\Files::loadAdditionalScripts` (string): loaded on the files list page
* `OCA\Files_Sharing::loadAdditionalScripts` (string): loaded on the public sharing page
* `OCA\Files_Sharing::loadAdditionalScripts::publicShareAuth` (string): loaded on the public share authentication page
* `OCP\AppFramework\Http\TemplateResponse::EVENT_LOAD_ADDITIONAL_SCRIPTS` (constant): loaded when a template response is finished
* `OCP\AppFramework\Http\TemplateResponse::EVENT_LOAD_ADDITIONAL_SCRIPTS_LOGGEDIN` (constant): loaded when a template response is finished for a logged in user
.. code-block:: php
<?php
$dispatcher = \OC::$server->getEventDispatcher();
$dispatcher->addListener(
OCP\AppFramework\Http\TemplateResponse::EVENT_LOAD_ADDITIONAL_SCRIPTS,
function() {
\OCP\Util::addScript('myapp', 'script');
\OCP\Util::addStyle('myapp', 'style');
}
);

View File

@@ -0,0 +1,31 @@
============
Introduction
============
Create an app
-------------
.. sectionauthor:: Bernhard Posselt <dev@bernhard-posselt.com>
After :doc:`you've set up the development environment <../general/devenv>` change into the Nextcloud apps directory::
cd /var/www/nextcloud/apps
Then create a skeleton app in the `app store <https://apps.nextcloud.com/developer/apps/generate>`_. This doesn't publish anything on the appstore yet, it just gives you a download.
Enable the app
--------------
The app can now be enabled on the Nextcloud apps page.
App architecture
----------------
The following directories have now been created:
* **appinfo/**: Contains app metadata and configuration
* **css/**: Contains the CSS
* **img/**: Contains icons and images
* **js/**: Contains the JavaScript files
* **lib/**: Contains the PHP class files of your app
* **src/**: Contains the source code of your vue.js app
* **templates/**: Contains the templates
* **tests/**: Contains the tests

File diff suppressed because it is too large Load Diff