Dynamic functions and filters¶
A need’s field can hold a value computed from other needs, and a view selects its needs with an expression. This page shows both, and the Cypher query ubCode takes beside a view’s expression. The views themselves, with their options, are on Need views.
The specimens below select only needs tagged ex-dynamic,
which only the specimen needs of this page carry,
so they show those needs and no others.
Dynamic functions in fields¶
A field value written as [[function(arguments)]] is a dynamic function:
it is computed while the project is indexed, and the card, the views and needs.json show the result.
Here the specification copies the owner of the requirement it refines,
and the implementation links to every specification tagged ex-dynamic.
Dynamic functions in fields
.. req:: Store the settings
:id: EX_REQ_DYNAMIC_1
:status: open
:tags: ex-dynamic
:owner: settings team
The settings survive a restart.
.. spec:: Write the settings file
:id: EX_SPEC_DYNAMIC_1
:owner: [[copy("owner", "EX_REQ_DYNAMIC_1")]]
:tags: ex-dynamic
:links: EX_REQ_DYNAMIC_1
The owner is that of [[copy("id")]], which is not computed here.
.. impl:: Settings writer
:id: EX_IMPL_DYNAMIC_1
:status: done
:tags: ex-dynamic
:links: [[links_from_filter("'ex-dynamic' in tags and type == 'spec'")]]
Writes the settings file.
The settings survive a restart. |
The owner is that of [[copy(“id”)]], which is not computed here. |
Writes the settings file. |
```{req} Store the settings
:id: EX_REQ_MYST_DYNAMIC_1
:status: open
:tags: ex-dynamic-myst
:owner: settings team
The settings survive a restart.
```
```{spec} Write the settings file
:id: EX_SPEC_MYST_DYNAMIC_1
:owner: [[copy("owner", "EX_REQ_MYST_DYNAMIC_1")]]
:tags: ex-dynamic-myst
:links: EX_REQ_MYST_DYNAMIC_1
The owner is that of [[copy("id")]], which is not computed here.
```
```{impl} Settings writer
:id: EX_IMPL_MYST_DYNAMIC_1
:status: done
:tags: ex-dynamic-myst
:links: [[links_from_filter("'ex-dynamic-myst' in tags and type == 'spec'")]]
Writes the settings file.
```
The MyST form renders live in the MyST dynamic functions.
A dynamic function is computed in a field (an option) only.
In a need’s content [[…]] is plain text, as the specification shows:
Sphinx-Needs stopped running it there in 9.0.0, and ubCode does not run it either.
To show a computed value in running text, write the :ndf: role
(see Dynamic functions).
copy, check_linked_values, calc_sum,
links_from_content and links_from_filter are among the built-in functions;
a value that reads another computed value is computed after it.
What ubCode does not compute is listed under the dynamic-function differences.
Filter strings¶
A view’s :filter: is an expression in a subset of Python, tested on each need:
a field name stands for the need’s value,
and ==, !=, in, and, or, not and len() work as they do in Python.
The same expressions select the needs of a needextend, a needimport and the :need_count: role.
A filter on fields
.. needlist::
:filter: owner == "settings team" and "ex-dynamic" in tags
:sort_by: id
```{needlist}
:filter: owner == "settings team" and "ex-dynamic" in tags
:sort_by: id
```
The MyST form renders live in the MyST filters.
The specification is listed because a filter reads the computed values: its owner is the one it copies.
In MyST an option value that starts with a double quote is refused (Invalid options format) by both tools,
so these filters start with a field name rather than with a quoted value.
A filter on links
.. needtable::
:filter: len(links) > 0 and "ex-dynamic" in tags
:columns: id, title, links
:style: table
ID |
Title |
Links |
|---|---|---|
Settings writer |
||
Write the settings file |
```{needtable}
:filter: len(links) > 0 and "ex-dynamic" in tags
:columns: id, title, links
:style: table
```
The MyST form renders live in the MyST filters.
Every name a filter can read, the string methods and search(), are under Python syntax.
Cypher queries¶
ubCode gives needlist, needtable, needflow, needpie and needbar a :cypher: option:
a read-only Cypher query over the needs and their links,
which can select a need by the needs it links to.
Sphinx-Needs accepts the option and ignores it,
so a view that must show the same needs in both builds the same selection as a :filter: beside it,
as this one does: ubCode reads the query, and a Sphinx-Needs build the filter.
A Cypher query
.. needlist::
:cypher: MATCH (n:spec)-[:links]->(r:req) WHERE 'ex-dynamic' IN r.tags RETURN n
:filter: type == "spec" and "EX_REQ_DYNAMIC_1" in links
```{needlist}
:cypher: MATCH (n:spec)-[:links]->(r:req) WHERE 'ex-dynamic' IN r.tags RETURN n
:filter: type == "spec" and "EX_REQ_DYNAMIC_1" in links
```
The MyST form renders live in the MyST Cypher query.
The query follows a link to a requirement tagged ex-dynamic;
the filter can only name that requirement,
so the two agree on these needs and not in general.
The query language is described under Cypher syntax,
and Selecting with Cypher pairs queries and filters on a larger model.