mirror of
https://github.com/nextcloud/documentation.git
synced 2026-01-03 02:09:45 +07:00
first tutorial commit
This commit is contained in:
@@ -1,16 +0,0 @@
|
||||
App Tutorial (App Framework)
|
||||
============================
|
||||
This tutorial contains the MVC approach to write an app. The benefits of this approach are:
|
||||
|
||||
* Highest authentication level and security checks are enforced by default and have to explicitely be turned off
|
||||
* Possiblity to use Twig templates which escape XSS by default
|
||||
* Easy to test: The App Framework allows to unittest the whole app by using :doc:`../general/dependencyinjection`
|
||||
* Comes with AngularJS JavaScript code
|
||||
* MVC style
|
||||
|
||||
The disadvantages of this approach are:
|
||||
|
||||
* App Framework app has to be installed
|
||||
* Requires to read more documentation
|
||||
* Possible
|
||||
|
||||
@@ -5,10 +5,11 @@ This tutorial contains the traditional approach to write an app. The benefits of
|
||||
|
||||
* Not dependant on the App Framework app
|
||||
* Easy and fast to create an app
|
||||
* Typical PHP style like
|
||||
|
||||
The disadvantages of this approach are:
|
||||
|
||||
* No automatic security checks: privilege checks have to be included at the top of each file
|
||||
* No automatic XSS escaping: :php:class:`OC_Template` does require manual escaping of output
|
||||
* Hard to unittest: Using files instead of Controllers makes it hard to write unittests for the whole application
|
||||
|
||||
* Hard to maintain: Using files instead of functions makes the design inflexible
|
||||
|
||||
@@ -33,4 +33,4 @@ The classloader works like this:
|
||||
|
||||
require '/apps/apptemplateadvanced/db/itemmapper.php';
|
||||
|
||||
Remember : for it to be autoloaded, the :file:`itemmapper.php` needs to either be stored in the **/apps/apptemplateadvanced/db/** folder, or adjust its namespace according to the folder it's stored in.
|
||||
Remember: for it to be autoloaded, the :file:`itemmapper.php` needs to either be stored in the **/apps/apptemplateadvanced/db/** folder, or adjust its namespace according to the folder it's stored in.
|
||||
0
developer_manual/app/css.rst
Normal file
0
developer_manual/app/css.rst
Normal file
58
developer_manual/app/info.rst
Normal file
58
developer_manual/app/info.rst
Normal file
@@ -0,0 +1,58 @@
|
||||
App Metadata
|
||||
============
|
||||
The :file:`appinfo/info.xml` contains metadata about the app:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<?xml version="1.0"?>
|
||||
<info>
|
||||
<id>yourappname</id>
|
||||
<name>Your App</name>
|
||||
<description>Your App description</description>
|
||||
<version>1.0</version>
|
||||
<licence>AGPL</licence>
|
||||
<author>Your Name</author>
|
||||
<require>5</require>
|
||||
<types>
|
||||
<filesystem/>
|
||||
</types>
|
||||
</info>
|
||||
|
||||
id
|
||||
--
|
||||
This field contains the internal app name, and has to be the same as the foldername of the app. This id needs to be unique in ownCloud, meaning no other app should have this id.
|
||||
|
||||
name
|
||||
----
|
||||
This is the human-readable name/title of the app that will be displayed in the app overview page.
|
||||
|
||||
description
|
||||
-----------
|
||||
This contains the description of the app which will be shown in the apps overview page.
|
||||
|
||||
version
|
||||
-------
|
||||
Contains the version of your app
|
||||
|
||||
licence
|
||||
-------
|
||||
The licence of the app. This licence must be compatible with the AGPL and **must not be proprietary**, for instance:
|
||||
|
||||
* AGPL 3 (recommended)
|
||||
* MIT
|
||||
|
||||
If a proprietary/non AGPL compatible licence should be used, the `ownCloud Enterprise Edition <https://owncloud.com/overview/enterprise-edition>`_ must be used.
|
||||
|
||||
types
|
||||
-----
|
||||
ownCloud allows to specify four kind of "types" in the file:`appinfo/info.xml` of a app. The type doesn't have to be specified if the app doesn't match any of them.
|
||||
|
||||
Currently supported "types":
|
||||
|
||||
* **prelogin**: apps which needs to load on the login page
|
||||
|
||||
* **filesystem**: apps which provides filesystem functionality (e.g. files sharing app)
|
||||
|
||||
* **authentication**: apps which provided authentication backends
|
||||
|
||||
* **logging**: apps which implement a logging system
|
||||
@@ -1,98 +0,0 @@
|
||||
App settings
|
||||
============
|
||||
|
||||
.. sectionauthor:: Bernhard Posselt <nukeawhale@gmail.com>
|
||||
|
||||
You'll need to give some information on your app for instance the name. To do that open the :file:`appinfo/app.php` and adjust it like this
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
// if you dont want to register settings for the admin, delete the following
|
||||
// line
|
||||
\OCP\App::registerAdmin('yourappname', 'admin/settings');
|
||||
|
||||
\OCP\App::addNavigationEntry( array(
|
||||
|
||||
// the string under which your app will be referenced
|
||||
// in owncloud, for instance: \OC_App::getAppPath('APP_ID')
|
||||
'id' => 'yourappname',
|
||||
|
||||
// sorting weight for the navigation. The higher the number, the higher
|
||||
// it will be listed in the navigation
|
||||
'order' => 74,
|
||||
|
||||
// the route that will be shown on startup
|
||||
// the routes have to be defined inside the appinfo/routes.php file
|
||||
'href' => \OC_Helper::linkToRoute('yourappname_index'),
|
||||
|
||||
// the icon that will be shown in the navigation
|
||||
// the icon must be stored inside the app's img/ folder
|
||||
'icon' => \OCP\Util::imagePath('yourappname', 'example.png' ),
|
||||
|
||||
// the title of your application. This will be used in the
|
||||
// navigation or on the settings page of your app
|
||||
'name' => \OC_L10N::get('yourappname')->t('Your App')
|
||||
|
||||
));
|
||||
|
||||
?>
|
||||
|
||||
.. _xml:
|
||||
|
||||
The second place where app specifc information is stored is in :file:`appinfo/info.xml`
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<?xml version="1.0"?>
|
||||
<info>
|
||||
<id>yourappname</id>
|
||||
<name>Your App</name>
|
||||
<description>Your App description</description>
|
||||
<version>1.0</version>
|
||||
<licence>AGPL</licence>
|
||||
<author>Your Name</author>
|
||||
<require>5</require>
|
||||
<types>
|
||||
<filesystem/>
|
||||
</types>
|
||||
</info>
|
||||
|
||||
ownCloud allows to specify four kind of "types" in the file:`appinfo/info.xml` of a app. The type doesn't have to be specified if the app doesn't match any of them.
|
||||
|
||||
Currently supported "types":
|
||||
|
||||
* **prelogin**: apps which needs to load on the login page
|
||||
|
||||
* **filesystem**: apps which provides filesystem functionality (e.g. files sharing app)
|
||||
|
||||
* **authentication**: apps which provided authentication backends
|
||||
|
||||
* **logging**: apps which implement a logging system
|
||||
|
||||
|
||||
|
||||
Dependency Injection
|
||||
--------------------
|
||||
Dependency Injection helps you to create testable code. A good overview over how it works and what the benefits are can be seen on `Google's Clean Code Talks <http://www.youtube.com/watch?v=RlfLCWKxHJ0>`_
|
||||
|
||||
The container is configured in :file:`dependencyinjection/dicontainer.php`. By default Pimple is used as dependency injection container. The documentation on how to use it can be read on the `Pimple Homepage <http://pimple.sensiolabs.org/>`_
|
||||
|
||||
To add your own classes simply open the :file:`dependencyinjection/dicontainer.php` and add a line like this to the constructor:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
// in the constructor
|
||||
|
||||
$this['MyClass'] = function($c){
|
||||
return new MyClass($c['SomeOtherClass']);
|
||||
};
|
||||
|
||||
?>
|
||||
|
||||
You can also overwrite already existing items from the App Framework simply by redefining them.
|
||||
|
||||
**See also** :doc:`../general/dependencyinjection`
|
||||
@@ -3,7 +3,9 @@ API abstraction layer
|
||||
|
||||
.. sectionauthor:: Bernhard Posselt <nukeawhale@gmail.com>
|
||||
|
||||
ownCloud currently has a ton of static methods which is a very bad thing concerning testability. Therefore the App Framework comes with an :php:class:`OCA\\AppFramework\\Core\\API` abstraction layer (basically a `facade <http://en.wikipedia.org/wiki/Facade_pattern>`_) which is located in the App Framework app at :file:`core/api.php`.
|
||||
ownCloud currently has a ton of static methods which is a very bad thing concerning testability. Therefore the App Framework comes with an :php:class:`OCA\\AppFramework\\Core\\API` abstraction layer (basically a `facade <http://en.wikipedia.org/wiki/Facade_pattern>`_) which is located in the App Framework app at :file:`core/api.php`.
|
||||
|
||||
This is a temporary solution until ownCloud offers a proper API with normal classes that can be used in the DIContainer.
|
||||
|
||||
This will allow you to easily mock the API in your unittests.
|
||||
|
||||
170
developer_manual/appframework/appframeworktutorial.rst
Normal file
170
developer_manual/appframework/appframeworktutorial.rst
Normal file
@@ -0,0 +1,170 @@
|
||||
App Tutorial (App Framework)
|
||||
============================
|
||||
This tutorial contains the MVC approach to write an app. The benefits of this approach are:
|
||||
|
||||
* Highest authentication level and security checks are enforced by default and have to explicitely be turned off
|
||||
* Possiblity to use Twig templates which escape XSS by default
|
||||
* Easy to test: The App Framework allows to unittest the whole app by using :doc:`../general/dependencyinjection`
|
||||
* Comes with AngularJS JavaScript code
|
||||
* MVC style
|
||||
|
||||
The disadvantages of this approach are:
|
||||
|
||||
* App Framework app has to be installed
|
||||
* Requires to read more documentation
|
||||
|
||||
Goal
|
||||
----
|
||||
The goal of this tutorial is a simple notes app.
|
||||
|
||||
Create basic files
|
||||
------------------
|
||||
First create a new folder inside your apps directry and name it **mynotes**. The name of the folder is important because it will be used for the :doc:`classloader` to include your classes.
|
||||
|
||||
Next create the :file:`appinfo/app.php`. This file will always loaded for every app and can for instance be used to load additional JavaScript for the files app:
|
||||
|
||||
:file:`appinfo/app.php`
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
namespace OCA\MyNotes;
|
||||
|
||||
$api = new \OCA\AppFramework\Core\API('mynotes');
|
||||
|
||||
$api->addNavigationEntry(array(
|
||||
|
||||
// the string under which your app will be referenced in owncloud
|
||||
'id' => $api->getAppName(),
|
||||
|
||||
// sorting weight for the navigation. The higher the number, the higher
|
||||
// will it be listed in the navigation
|
||||
'order' => 10,
|
||||
|
||||
// the route that will be shown on startup
|
||||
'href' => $api->linkToRoute('mynotes_index'),
|
||||
|
||||
// the icon that will be shown in the navigation
|
||||
'icon' => $api->imagePath('example.png' ),
|
||||
|
||||
// the title of your application. This will be used in the
|
||||
// navigation or on the settings page of your app
|
||||
'name' => $api->getTrans()->t('My notes app')
|
||||
|
||||
));
|
||||
|
||||
|
||||
Next up is the :file:`appinfo/info.xml` where metadata for the app is stored. This will be used to check if the app is compatible with ownCloud (require tag) and to display text on the app info page:
|
||||
|
||||
:file:`appinfo/info.xml`
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<?xml version="1.0"?>
|
||||
<info>
|
||||
<id>mynotes</id>
|
||||
<name>My notes app</name>
|
||||
<description>Simple notes app</description>
|
||||
<version>1.0</version>
|
||||
<licence>AGPL</licence>
|
||||
<author>Your Name</author>
|
||||
<require>6</require>
|
||||
</info>
|
||||
|
||||
|
||||
First Page
|
||||
----------
|
||||
|
||||
Now that the basic files are created, the following things are needed to create a page:
|
||||
|
||||
* **A route**: The URL which links to the controller
|
||||
* **A controller**: Gets the request and returns a response
|
||||
* **An entry in the DIContainer**: This makes the controller available for the application
|
||||
* **A template**: HTML which should be displayed on the page
|
||||
|
||||
First the route which is linked in the :file:`appinfo/app.php` needs to be created. To do that create the :doc:`routes` file:
|
||||
|
||||
:file:`appinfo/routes.php`
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
namespace OCA\MyNotes;
|
||||
|
||||
use \OCA\AppFramework\App;
|
||||
use \OCA\MyNotes\DependencyInjection\DIContainer;
|
||||
|
||||
$this->create('mynotes_index', '/')->action(
|
||||
function($params){
|
||||
// call the index method on the class PageController
|
||||
App::main('PageController', 'index', $params, new DIContainer());
|
||||
}
|
||||
);
|
||||
|
||||
The :doc:`controllers` to which the route links does not exist yet and it has to be created:
|
||||
|
||||
:file:`controllers/pagecontroller.php`
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
namespace OCA\MyNotes\Controller;
|
||||
|
||||
use OCA\AppFramework\Controller\Controller;
|
||||
|
||||
|
||||
class PageController extends Controller {
|
||||
|
||||
|
||||
public function __construct($api, $request){
|
||||
parent::__construct($api, $request);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @CSRFExemption
|
||||
* @IsAdminExemption
|
||||
* @IsSubAdminExemption
|
||||
*/
|
||||
public function index(){
|
||||
return $this->render('main');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
Now create the template:
|
||||
|
||||
:file:`templates/main.php`
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<div>Hello World</div>
|
||||
|
||||
|
||||
The last thing that is left is to tell the application how the controller needs to be created. The App Framework makes heavy use of :doc:`../general/dependencyinjection` and provides an IOC Container. Inside this container, the controller needs to be created:
|
||||
|
||||
:file:`dependencyinjection/dicontainer.php`
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
class DIContainer extends BaseContainer {
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct('mynotes');
|
||||
|
||||
// use this to specify the template directory
|
||||
$this['TwigTemplateDirectory'] = __DIR__ . '/../templates';
|
||||
|
||||
$this['PageController'] = function($c){
|
||||
return new PageController($c['API'], $c['Request']);
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
24
developer_manual/appframework/container.rst
Normal file
24
developer_manual/appframework/container.rst
Normal file
@@ -0,0 +1,24 @@
|
||||
Dependency Injection
|
||||
====================
|
||||
Dependency Injection helps you to create testable code. A good overview over how it works and what the benefits are can be seen on `Google's Clean Code Talks <http://www.youtube.com/watch?v=RlfLCWKxHJ0>`_
|
||||
|
||||
The container is configured in :file:`dependencyinjection/dicontainer.php`. By default `Pimple <http://pimple.sensiolabs.org/>`_ is used as dependency injection container. A `tutorial can be found here <http://jtreminio.com/2012/10/an-introduction-to-pimple-and-service-containers/>`_
|
||||
|
||||
|
||||
To add your own classes simply open the :file:`dependencyinjection/dicontainer.php` and add a line like this to the constructor:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
// in the constructor
|
||||
|
||||
$this['MyClass'] = function($c){
|
||||
return new MyClass($c['SomeOtherClass']);
|
||||
};
|
||||
|
||||
?>
|
||||
|
||||
You can also overwrite already existing items from the App Framework simply by redefining them.
|
||||
|
||||
**See also** :doc:`../general/dependencyinjection`
|
||||
25
developer_manual/appframework/index.rst
Normal file
25
developer_manual/appframework/index.rst
Normal file
@@ -0,0 +1,25 @@
|
||||
========================================
|
||||
App Developement Using the App Framework
|
||||
========================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
gettingstarted
|
||||
appframeworktutorial
|
||||
../app/info
|
||||
../app/classloader
|
||||
container
|
||||
api
|
||||
routes
|
||||
controllers
|
||||
database
|
||||
templates
|
||||
javascript
|
||||
../app/css
|
||||
unittesting
|
||||
middleware
|
||||
externalapi
|
||||
filesystem
|
||||
hooks
|
||||
data-migration
|
||||
0
developer_manual/appframework/javascript.rst
Normal file
0
developer_manual/appframework/javascript.rst
Normal file
Reference in New Issue
Block a user