Documentation!

This commit is contained in:
leogermani 2019-05-13 16:31:56 -03:00
parent 2e71d421a5
commit f85119e3e5
4 changed files with 271 additions and 64 deletions

View File

@ -40,11 +40,13 @@ Check out the digital exhibits from [Museu do Índio](http://tainacan.museudoind
In addition to [our documentation](https://wiki.tainacan.org/) and [instructional videos](https://youtu.be/oEl9bWe_rWI), we provide technical support on our [mailing list](https://lists.riseup.net/www/info/tainacan) in English, Portuguese and Spanish. You are welcome to send all of your questions!
### Developers
Please refer to our [Developers Documentation](docs/index.md) if you want to develop tainacan plugins, themes or if you want to contribute to the core.
### Contributing
Tainacan is a free, open source software licensed under **GPLv3**. Contributions to the codebase will abide to the same license; other contributions may be under additional or other terms.
See how to setup your local development environment directly on your system following [this instructions](docs/setup-local.md) or using our [Docker tools](https://github.com/tainacan/tainacan-docker).
To contribute with our project, you can report bugs and other issues, or suggest new features. You are also free to submit pull requests or translate Tainacan to multiple languages. If you are interested in contributing, you can get started by reading our [contribution guidelines](docs/CONTRIBUTING.md).
### Acknowledgements

View File

@ -15,6 +15,10 @@ Nevertheless, you are still able to create more specific templates, using the st
Examples:
A template to list Collections:
`archive-tainacan-collection.php`
A template for single items in the collection with id 4:
`single-tnc_col_4_item.php`

View File

@ -1,104 +1,260 @@
# Exposers
# How to create an Exposer
Exposers are declarations and methods that expose the items of your repository in a certain way.
Exposers are classes that implement a new Exposer that can be used by Tainacan to expose the content of a repository via API.
## Structure
In order to create a new exposer you basically have to create an Exposer class and register it.
### Name
## Creating an Exposer class
String $name
Create a class that extends `\Tainacan\Exposers\Exposer`.
The name of the Exposer.
```PHP
<?php
### Slug
class MyExposer extends \Tainacan\Exposers\Exposer {
}
String $slug
```
In this class you will have to set up some attributes and methods:
### Attributes
#### Slug
**String $slug**
A URL friendly version of the Exposer name, to be used as a parameter to the API request informing you want to get the data using this exposer.
```PHP
<?php
### Supported Mapping Standard
class MyExposer extends \Tainacan\Exposers\Exposer {
public $slug = 'my-exposer';
}
Array or true $mappers
```
A list of mapping standards that is exposer supports. This means that whenever someone makes a request to receive that via this exposer, he/she will also be able to choose in which mapping standar they want the content to be served, or true for serve all mappers.
#### Supported Mapping Standard
**Array or true $mappers**
A list of mapping standards that is exposer supports. This means that whenever someone makes a request to receive data via this exposer, he/she will also be able to choose in which mapping standard they want the content to be served. If set to `true` the exposer will accept all mapping standards.
```PHP
<?php
class MyExposer extends \Tainacan\Exposers\Exposer {
public $slug = 'my-exposer';
public $mappers = true;
}
```
or
```PHP
<?php
class MyExposer extends \Tainacan\Exposers\Exposer {
public $slug = 'my-exposer';
public $mappers = ['dublin-core']; // indicates that this exposer will only serve data mapped to dublin core mapper
}
```
#### Accept no Mapping Standards
**Bool $accept_no_mapper**
Indicates whether this exposer accept to serve data in its native form, without any mapping standards.
```PHP
<?php
class MyExposer extends \Tainacan\Exposers\Exposer {
public $slug = 'my-exposer';
public $mappers = ['dublin-core']; // indicates that this exposer will only serve data mapped to dublin core mapper
public $accept_no_mapper = true;
}
```
### Methods
Every exposer have to implement PHP methods that will build the API response and have to be parent of Tainacan\Exposers\Types\Type
Now that you have declared the basic attributes of your Exposer, there are two methods you must implement.
####callback rest response
\WP_REST_Response rest_request_after_callbacks will receve a array of elements to be exposed, and api request, server and reponse.
#### __construct()
/**
* Change response after api callbacks
* @param \WP_REST_Response $response
* @param \WP_REST_Server $handler
* @param \WP_REST_Request $request
* @return \WP_REST_Response
*/
public function rest_request_after_callbacks( $response, $handler, $request );
In this method you must call `set_name()` and `set_description()` to identify your exposer.
```PHP
<?php
class MyExposer extends \Tainacan\Exposers\Exposer {
public $slug = 'my-exposer';
public $mappers = ['dublin-core']; // indicates that this exposer will only serve data mapped to dublin core mapper
public $accept_no_mapper = true;
public function __construct() {
$this->set_name( __('My Exposer', 'my-test-plugin-namespace') );
$this->set_description( __('This exposer server the data in a very different way', 'my-test-plugin-namespace') );
}
}
```
**Note**: The reason Name and Description are declared this way, and not as attributes, is to give you the opportunity to localize your strings to different languages. Please refer to the WordPress documentation to learn how to internationalize your plugin.
#### rest_request_after_callbacks()
Now this is where all the magic happens!
This method will be called right before the API returns the data to the client.
It will give you all the items it received, in the way they were about to be served in the default JSON format, and give you the opportunity to transform it.
It receives 3 parameters:
* $response: an instance of the `\WP_REST_Response` object
* $response: an instance of the `\WP_REST_Server` object
* $response: an instance of the `\WP_REST_Request` object
This method have to return the modified version of the `\WP_REST_Response` object.
```PHP
<?php
class MyExposer extends \Tainacan\Exposers\Exposer {
public $slug = 'my-exposer';
public $mappers = ['dublin-core']; // indicates that this exposer will only serve data mapped to dublin core mapper
public $accept_no_mapper = true;
public function __construct() {
$this->set_name( __('My Exposer', 'my-test-plugin-namespace') );
$this->set_description( __('This exposer server the data in a very different way', 'my-test-plugin-namespace') );
}
public function rest_request_after_callbacks( $response, $handler, $request ) {
// Set the headers to another content type, if applicable
$response->set_headers( ['Content-Type: text/plain; charset=' . get_option( 'blog_charset' )] );
$items = $response->get_data();
// Transform the items somehow ...
// ...
$response->set_data($items);
return $response;
}
}
```
Using this method an exposer can also print data in the `HEAD` section of the HTML when visiting an item page. For example, JSON-LD exposer can add a JSON-LD object to the head of the page of every item in your collection, modifing the rest server ($handler).
### Registering a new exposer
For register a new exposer, the action need to be added to `tainacan-register-exposer-types` hook, like:
```
function myNewExposer($exposers) {
$exposers->register_exposer_type('Tainacan\Exposers\Types\NewExposer');
To register a new exposer, the action need to be added to the `init` hook, like:
```PHP
<?php
function registerMyExposer() {
$exposers = \Tainacan\Exposers_Handler::get_instance();
$exposers->register_exposer_type('MyExposer');
}
add_action('tainacan-register-exposer-types', 'myNewExposer');
add_action('init', 'registerMyExposer');
```
### Example
### Full Example
<?php
namespace Tainacan\Exposers\Types;
/**
* Generate a text formated response
*
*/
class Txt extends Type {
This is a full example of a plugin that implements a simple text exposer
```PHP
<?php
/*
Plugin Name: Tainacan TXT Exposer
Description: This is a sample exposer class
*/
function myNewExposer($exposers) {
class TxtExposer extends \Tainacan\Exposers\Exposer {
public $mappers = ['Value'];
public $slug = 'txt'; // type slug for url safe
public $name = 'TXT';
protected $mappers = true;
public $accept_no_mapper = true;
private $identation = '';
function __construct() {
$this->set_name( 'TXT' );
$this->set_description( __('A simple TXT table', 'my-test-plugin-namespace') );
}
/**
*
* {@inheritDoc}
* @see \Tainacan\Exposers\Types\Type::rest_request_after_callbacks()
*/
*
* {@inheritDoc}
* @see \Tainacan\Exposers\Types\Type::rest_request_after_callbacks()
*/
public function rest_request_after_callbacks( $response, $handler, $request ) {
$response->set_headers( ['Content-Type: text/plain; charset=' . get_option( 'blog_charset' )] );
$txt = '';
$txt = $this->array_to_txt($response->get_data(), apply_filters('tainacan-exposer-txt', $txt));
$txt = $this->array_to_txt($response->get_data(), false);
$response->set_data($txt);
return $response;
}
/**
* Convert Array to Txt
* @param array $data
* @param string $txt
* @return string
*/
protected function array_to_txt( $data, $txt ) {
foreach( $data as $key => $value ) {
if( is_numeric($key) ){
$key = apply_filters('tainacan-exposer-numeric-item-prefix', __('item', 'tainacan').'-', get_class($this)).$key; //dealing with giving a key prefix
}
if( is_array($value) ) {
$txt .= $key.": ".$this->array_to_txt($value, '['.$txt.']\n');
} else {
$txt .= $key.": ".$value .'\n';
}
* Convert Array to Txt
* @param array $data
* @param string $txt
* @return string
*/
protected function array_to_txt( $data, $addlevel = true ) {
$return = '';
if ($addlevel) {
$this->identation .= ' ';
}
return $txt;
foreach( $data as $key => $value ) {
$return .= $this->identation . $key . ': ';
if (is_array($value)) {
$return .= "\n" . $this->array_to_txt($value);
} else {
$return .= $value . "\n";
}
}
if ($addlevel) {
$this->identation = substr($this->identation, 0, strlen($this->identation) - 4 );
}
return $return;
}
}
$exposers = \Tainacan\Exposers_Handler::get_instance();
$exposers->register_exposer('TxtExposer');
}
add_action('init', 'myNewExposer');
```

45
docs/index.md Normal file
View File

@ -0,0 +1,45 @@
# Tainacan for developers
As you know, Tainacan is a WordPress plugin and is built on the top of this very well known platform. If you know WordPress it will be very easy for you to understand how Tainacan is organized, how it interacts with the database and how to build your own features on the top of it.
## Well, but I'm new to WordPress
If you don't have expirience with WordPress and would like to develop a plugin for Tainacan, or to contribute to the Tainacan plugin, it's a good idea to get to know some WordPress fundamentals. Those will be useful to everything you will deal with while working with Tainacan.
This is a non-exhaustive list of the most important topics you should look into:
* [WP_Query](https://codex.wordpress.org/Class_Reference/WP_Query) class - This is the heart of WordPress, the class that gives you the interface fo query for posts in the database. All interaction with the database in Tainacan uses this class.
* [Custom Post types](https://codex.wordpress.org/Post_Types) and [taxonomies](https://codex.wordpress.org/Taxonomies) - All Tainacan entities, such as collections, metadata, filters and items, are WordPress Custom post types. To understand how WordPress handles custom post types and custom taxonomies is very helpful.
* [The Loop](https://codex.wordpress.org/The_Loop) - One of the main WordPress elements used to interact through posts. Useful specially if you are tweaking with themes.
* [Template Tags](https://codex.wordpress.org/Template_Tags) - Simple functions used by theme developers to display dynamic content. Usually these function are used inside "The Loop" and Tainacan implements [it's own Template tags](../src/theme-helper/template-tags.php).
* [Template Hierarchy](https://developer.wordpress.org/themes/basics/template-hierarchy/) - Crucial if working with themes.
* Custom queries and loops - Based on the topics above, it is good to understand how to build custom queries and loops to list posts.
## Resources
### Development Resources
* [Key Concepts](key-concepts.md) - First things first. Let's understand what is what in Tainacan.
* [Tainacan internals](internal-api.md) - Reference on Tainacan main classes and how to use them.
* [Setting up local environment](setup-local.md) - If you want to contribute to Tainacan core, you must set up your local environment. Alternatively, you can use our [Docker repository](https://github.com/tainacan/tainacan-docker). **If you want to develop themes or plugins, you don't need this**.
* [Tainacan Custom templates](custom-templates.md) - Custom templates that Tainacan add to WordPress Template Hierarchy
* [Tainacan Template Tags](../src/theme-helper/template-tags.php) - Template tags useful to use in templates
* Tainacan Hooks - soon
* [Tainacan API](https://tainacan.org/api-docs/) - (Under construction)
* [Exporting and Exposing](exporting-and-exposing.md)
* [Creating a new Metadata Type](creating-metadata-type.md)
* [How to create Exporters](exporter-flow.md)
* [How to create Importers](importer-flow.md)
* [How to create Exposers](exposers.md)
* [Creating new View Modes](https://wiki.tainacan.org/index.php?title=Extra_View_Modes)
### Configuration and performance
* [Faceted Search](faceted-search.md)
* [Search Engine](search-engine.md)
* [Garbage Collector](garbage-collector.md)
### Other
* [Tainacan release process](release.md)