====== Strata Plugin ======
---- plugin ----
description: Add and query semi-structured data in your wiki
author : François Kaag
email : francois.kaag@cardynal.fr
type : syntax, action, helper
lastupdate : 2024-09-27
compatible : Jack Jackrum
depends :
conflicts : caption
similar : data, fields, struct
tags : database, sqlite, data, tables, listing, mysql, postgresql
downloadurl: https://github.com/fkaag71/dokuwiki-strata/zipball/master
bugtracker : https://github.com/fkaag71/dokuwiki-strata/issues
sourcerepo : https://github.com/fkaag71/dokuwiki-strata/
donationurl:
screenshot_img :
----
This plugin was originally created by [[brend+strata@13w.nl|Brend Wanders]]. Although he could not maintain it any longer after 2021, it is still useful, since no other data plugin seems to propose graph based queries that fit extremely well with the Wiki structure.
The Strata plugin allows you to add data to your pages, just like the [[data]] plugin. You can think of this data either as named values attached to the page, or as describing things on the page in a more structured way.
Though a little more complex than the [[data]] plugin, Strata allows you to create tables that combine data from different pages. Strata also supports previewing your edits showing you the correctly changed data, and has a flexible and user-controlled data type display. Finally, you can put multiple data entries on a single page, and have them combined or remain separate depending on how you want to model your data.
**Requirements:**
* Strata requires PHP 5.6.x
* [[http://www.php.net/manual/en/ref.pdo-sqlite.php|pdo-sqlite]] extension for accessing and creating the default data storage
===== Installation =====
Search and install the plugin using the [[extension|Extension Manager]]. Refer to [[:Plugins]] on how to install plugins manually.
After installation, it might be useful to copy the contents [[https://github.com/fkaag71/dokuwiki-strata/blob/main/manual.txt|manual.txt]] on Github to a wiki page on your installation. This will put the [[~:reference guide]] on your own wiki installation, complete with listing of available types and aggregates.
Strata followes DokuWiki's [[config:useheading]] configuration when displaying links. Changing that setting will also adjust how Strata displays links, which might help with making a lot of the automatically generated listings and links look better.
===== Examples/Usage =====
//For a separate page focusing only on examples and troubleshooting, see [[~:examples|Strata Plugin Examples]].//
Below is a very simple example of how to use Strata.
Add data to a page (let's say ''people:john_doe'') with:
Full Name: John Doe
Age: 24
Contact [link]: john.doe@example.org
Friends [ref]*: Alice, Bob
This will create a data block that looks like:
^ Page Title //(person)// ||
^ Full Name | John Doe |
^ Age | 24 |
^ Contact | |
^ Friends | [[Alice]], [[Bob]] |
Later on, you can make a list (to get a table, use '''' instead) of people with:
?person is a: person
?person Contact [link]: ?contact
You could also ask for a list of contact links of all people and the contact links of their friends:
?person is a: person
?friend is a: person
?person Friends [ref]: ?friend
?friend Contact [link]: ?fc
Note that by default, the results will be cached. So if you edit other pages, you'll need to refresh the page with the list yourself, or add ''%%~~NOCACHE~~%%'' to force dokuwiki to rerender.
The next section will go over the syntax in more detail.
===== Syntax =====
The strata plugin allows you to add data to your pages and to query that data from your pages. The quick guide will get you up and running with some examples of how to enter and query. More advanced uses are discussed in the [[~:reference guide]].
A good way to get more experienced is to add some simple data to your wiki, and start querying it. Most error messages are descriptive enough to get some idea of what went wrong.
==== Data Block ====
Data entry is done with '''' tags. The following example is a data block for Jane Doe. The block is meant to add some extra data to the page it is on (we assume it is on the page ''persons:jane_doe''). The example shows you how to add simple values, how to declare a class, and how to use types.
Full Name: Jane Maria Doe
Birthday [date]: 1982-7-23
**Simple Values**: You add simple values to the data block by adding a line like ''field: value''. The field and value are sometimes called the predicate and object respectively.
**Classes**: You can add one or more classes to a data block by placing them in the opening tag. Classes are separated by spaces, so class names declared in this way can not contain spaces. (Note that declaring a class name is effectively the same as adding a ''is a: person'' field-value pair to the data block.)
**Types**: You can add a [[#types|type]] to use by putting the type between ''['' and '']'' after the field name. Types determine how the data is displayed, and how it is stored.
The same example, but extended with more features:
-- Simple field-value pairs
Full Name: Jane Maria Doe
Address:
-- Types and Type Hint
Birthday [date]: 1982-7-23
Birthplace [page::places]: Springfield
-- Multiple values
Contact [link]*: j.doe@example.com, http://www.facebook.com/Jane-Doe
Contact [link]: jane.doe@workmail.com
**Empty values**: Any field that doesn't have a value is ignored. This way you can quickly write down some fields you want to use, but fill in their values later.
**Type hints**: You can change how a [[#types|type]] behaves by adding a type hint. Type hints are added by appending them to the type with ''::''. For example ''[page::places]'' uses the page type, and will try to resolve values without an explicit namespace as if they were in the ''places:'' namespace. For a list of types and their hints, see [[#Types]].
**Multiple Values**: You can have multiple values with a field. Do this by either putting a ''*'' after the field (or after the type, if it has any), or by simply adding the field multiple times.
**Comments** All lines that start with double dashes (i.e., ''%%--%%'') are ignored. Note that your comments can still be read by anyone viewing the source of the wiki page.
==== Tables and Lists ====
Queries are written inside '''' or '''' tags. You query the data by describing what pattern the data should fit. A simple example that produces a table of all persons and their birthday would be described as follows:
?p is a: person
?p Birthday [date]: ?b
?b < 1990-1-1
**Patterns**: You can use variables and literals to describe what data you want to match. The patterns should be written down in lines, with each line formatted like ''subject field: value''.
For example, ''?p is a: person'' will match any subject that has field ''is a'' and value ''person'' to variable ''?p''.
Variables are indicated with the ''?''. You can use a variable in any spot (except types or type hints). For example ''?p ?k [date]: 1982-7-23'' to find out who has what relation to the date 1982-7-23.
Literals can be written down verbatim, except for subject literals. These should be enclosed in ''%%[[%%'' and ''%%]]%%''. For example ''%%[[persons:jane_doe]] Address: ?a%%'' to get the address associated with Jane Doe.
**Types**: In a query, you can use [[#types]]. You can use types for fields and values, and you can use them in the opening tag. Types are 'sticky': if you put ''?p Birthday [date]: ?b'' the date type will automatically stick to the ''?b'' variable (you could have achieved the same with ''?p Birthday: ?b [date]'').
**Comparisons**: You can use normal operators (e.g, ''<'', ''>'', ''>='', ''%%<=%%'', ''='', ''!='') to compare values. A variable's type will be taken into account for the comparison.
You can only compare variables that are used in a pattern.
**Captions**: You can put captions in the opening tag to change the caption of the column. Captions are not displayed by lists, but are still used to add names to the filtering and sorting interface.
?p is a: person
optional {
?p Address: ?address
}
minus {
?p Contact: ?c
}
group {
?p
}
sort {
?address (desc)
}
ui {
Person {
filter: select
}
Address {
filter: text
}
}
**Aggregates**: Variables can have multiple values (usually through grouping). You can apply an aggregate function to the variable's values by adding it to any variable in the opening tag with ''@''. For example ''?address@count'' will apply the count aggregate to the values in ''?address''. For more on aggregates, see [[#Aggregates]].
**Optional matches**: Normally, all patterns must be matched for the results to be shown. You can use an ''optional'' block to indicate that some of the patterns are optional, and need not be matched for the results to be shown. All patterns in an optional block must match for the optional block to be used. If any pattern in the block doesn't match, none of the patterns in the block will be used.
You can have multiple optional blocks. You can even have optional blocks inside optional blocks.
**Exclusions**: With the ''minus'' block, you can declare that the data is not allowed to match certain patterns. In this case, the results are not allowed to have contact information.
**Grouping**: By adding a ''group'' block zero or more variables can be grouped. This means that all results that have the same value for the grouped variable will be merged, and the ungrouped variables will contain multiple values. You can name one variable per line. If the ''group'' is empty //all// results will be merged into a single result.
**Sorting**: By adding ''sort'' you can define one or more variables to sort on. You can name one variable per line, and include a direction with ''(ascending)'' or ''(descending)'' (or their short-hands ''(asc)'' and ''(desc)'').
**User Interface**: By adding ''ui'' you can define how and if the user interface allows filtering (and sorting) on the client.
**Comments**: As with a data block, you can use ''%%--%%'' at the start of a line to add comments.
==== Types ====
Types are normally indicated by putting them between ''['' and '']''. Type hints are noted after the type itself in the following format: ''[type::hint]''
On your own wiki, you can get a list of all available types with ''%%~~INFO:stratatypes~~%%''. Below are some of the commonly used types:
* **date** (type hint: different date format)\\ Stores and displays dates in the YYYY-MM-DD format. The optional hint can give a different format to use (as described by [[phpfn>datetime.createfromformat|date_create_from_format]]). (numeric)
* **image** (type hint: size to scale the image to)\\ Displays an image. The optional hint is treated as the size to scale the image to. Give the hint in WIDTHxHEIGHT format.
* **link** (type hint: The link title)\\ Creates a link. This type is multi-purpose: it handles external links, interwiki links, email addresses, windows shares and normal wiki links (basically any link DokuWiki knows of). The optional hint will be used as link title.
* **ref** (type hint: namespace)\\ References another piece of data or wiki page, and creates a link. An optional hint can be given to change how links are interepreted when saving them: if present, the hint is used as namespace for the link. If the hint ends with a #, all values will be treated as fragments.
* **title** is identical to **ref**, except that the page heading will be used instead of the page name to display the link.
* **wiki**\\ Allows the use of dokuwiki syntax; only non-block syntax is allowed (only links, formatting, etc.; no tables, headers, and other large stuff). The hint is ignored.
* ** enum** (type hint: value set name)\\ Searches the entry in the value set, a '''' block where rows are in the form ''label: entry'', and displays the label corresponding to the entry, or #NA if no correspondence was found.
==== Aggregates ====
Aggregates are used on displays of variables. They are attached to the variable with ''@'', for example: ''%%?x@unique%%'' applies the unique aggregate to the values of variables ''?x''. Aggregates can be passed a hint by adding the hint between parenthesis: ''%%?variable@aggregate(hint)%%''.
On your own wiki, you can get a list of all available aggregates with ''%%~~INFO:strataaggregates~~%%''. Below are some commonly used aggregates:
* **count**\\ Counts the number of items.
* **max** (aggregate hint: 'strict' to ignore non-numeric values)\\ Returns the maximum value. Any item that does not have a clear numeric value (i.e. starts with a number) is counted as 0. If the 'strict' hint is used, values that are not strictly numeric (i.e. contains only a number) are ignored. (numeric)
* **sum** (aggregate hint: 'strict' to leave non-numeric values)\\ Sums up all items. Any item that does not have a clear numeric value (i.e. starts with a number) is counted as 0. If the 'strict' hint is used, values that are not strictly numeric (i.e. contains only a number) are left intact. (numeric)
* **unique**\\ Removes all duplicates.
===== Configuration and Settings =====
The following settings are available:
* **Default value type** (//Default:// ''[text]''): The default type to use for any value that does not have a determinable type. It is possible to give a type hint in the same field, e.g. ''[type::hint]''.
* **Default predicate type** (//Default:// ''[text]''): The type to use to normalize (and display) predicates. It is possible to give a hint (e.g. ''[ref::predicates#]''). Note that changing this option might make your current data unqueryable.
* **Default database source name** (//Default:// ''sqlite:@METADIR@/strata.sqlite''): The [[phpfn>PDO]] data source name used to connect to the database. The ''@METADIR@'' token will be replaced with the path of DokuWiki's meta data directory.
* **The name of the 'is a' relation** (//Default:// ''is a''): The predicate that should be used to indicate the 'is a' relation. This is used when you enter a data block with one or more classes.
* ** Data scope reduced to the current namespace ** (//Default:// ''inactive''): When set, only the triples within the current namespace are considered in expressions.
* **The name of the 'entry title' relation** (//Default:// ''entry title''): The predicate that should be used to indicate the 'entry title' relation. The 'entry title' relation links a human readable label to the data entry. Normally, this is done automatically by the data block syntax, this setting only changes the relation used to attach the title to the data.
* **Enable debug information?** (//Default:// no): Tick this box if you want to have more extensive information on what's going wrong. For example, use it when the connection to the database fails.
* **Is the data entry syntax enabled?** (//Default:// yes): Uncheck this box if you want to disable the data blocks for entry.
Furthermore, the following DokuWiki settings are relevant:
* **[[config:useheading]]**: adjusts how links are displayed
==== Database Drivers ====
The Strata plugin will construct the necessary tables and indices itself. You only have to set up the database itself.
=== SQLite ===
//DSN:// ''sqlite:/path/to/database/file'' (See [[phpfn>ref.pdo-sqlite|PDO SQLite]])
SQLite is a simple on-disk database that does not require setting up a server or managing users. The SQLite driver is the default driver.
**Set-up**: The SQLite driver requires no set-up if you use the default path. If you use another path than the default path, make sure that your web server has write access to the directory the database resides in, this is required by SQLite.
=== MySQL ===
//DSN:// ''mysql:host=localhost;dbname=testdb'' (See [[phpfn>ref.pdo-mysql|PDO MySQL]])
Uses the MySQL DMBS to store and retrieve triples. Credentials can only be used through the [[#credentials file]].
**Set-up**: the MySQL driver requires you to set up a database in the MySQL server. An example is given here, but refer to the MySQL manual for details on creating databases and adding users.
The following snippet will create a database called ''strata'', make sure to replace ''username'' and ''password'' with other values.
CREATE DATABASE strata;
GRANT ALL ON strata.* TO 'username'@localhost IDENTIFIED BY 'password';
After the creation of the database you'll have to set up the [[#credentials file]] as described below.
Finally, set the DSN to: ''mysql:host=localhost;dbname=strata''
=== PostgreSQL ===
//DSN:// ''pgsql:host=localhost;port=5432;dbname=testdb;user=myuser;password=mypass'' (See [[phpfn>ref.pdo-pgsql|PDO PostgreSQL]])
Uses the PostgreSQL DMBS to store and retrieve triples. Credentials can be given in the DSN, or through the [[#credentials file]]. However, if you specify a user and password in the DSN, the credentials file will be ignored.
**Set-up**: The PostgreSQL driver requires you to set up a database before using it. An example is given here, but you should refer to the PostgreSQL manual for details on database and user creation.
The following snippet will create a user called ''strata'' without a password. It will also create a database with the name ''strata'', the database has the correct locale settings for use of UTF-8.
createuser -SDR strata
createdb -l "en_US.UTF-8" -E UTF8 -T template0 strata
Next, set the DSN to: ''pgsql:host=localhost;port=5432;dbname=strata;user=strata''
=== Credentials File ===
Unfortunately, the MySQL PDO driver does not allow the use of a user and password field in the DSN. To enable the use of password protected databases, you can give the username and password in a small file. The file is called ''credentials.local.php'' and should be placed in the strata plugin directory (normally ''/lib/plugins/strata'').
The credentials file should have the following content
It is advisable to use ''.htaccess'' and file system rights to make sure this file is not readable by outsiders. (You can also edit ''driver/driver.php'' to change where Strata looks for the file.)
=== Change Log ===
After adoption:
{{rss>https://github.com/fkaag71/dokuwiki-strata/commits.atom date}}
Before adoption:
{{rss>https://github.com/bwanders/dokuwiki-strata/commits/master.atom date}}
===== FAQ =====
* The [[plugin:sqlite]] plugin gives warnings that the ''strata.sqlite'' files needs to be renamed?
* The [[https://github.com/bwanders/dokuwiki-strata/issues/9|SQLite problems (#9)]] issue describes the symptoms and offers two solutions.
===== Bugs, Feature Requests and Patches =====
Please submit bugs and feature requests in the [[https://github.com/fkaag71/dokuwiki-strata/issues|issue tracker on github]]. The easiest way to submit patches is through forking on github and opening a pull request. Alternatively, patches can be sent in unified diff format or as git patches against the master branch.