# PQL Language Features
PQL adds several language features over GQL. This is a summary of them.
Standard operations, such as
sprintf and many others, are supported as fields:
1. ?query=not(true) 2. ?query=or([1,0]) 3. ?query=and([1,0]) 4. ?query=if(true, Show this text, Hide this text) 5. ?query=equals(first text, second text) 6. ?query=isNull(),isNull(something) 7. ?query=sprintf(%s API is %s, [PoP, cool])
# Composable fields
Arguments passed to a field can receive other fields or operators as input.
?query= posts. if ( hasComments(), sprintf( "Post with ID %s has %s comment(s) and title '%s'", [ id(), commentCount(), title() ] ), sprintf( "Post with ID %s, created on %s, has no comments", [ id(), date(d/m/Y) ] ) )@postDesc
# Composable fields in directive arguments
Through composable fields, the directive can be evaluated against the object, granting it a dynamic behavior.
The example below implements the standard GraphQL
skip directive, however it is able to decide if to skip the field or not based on a condition from the object itself:
/?query= posts. title| featuredimage< skip(if:isNull(featuredimage())) >. src
# Composable directives
A directive can modify the behaviour of another directive. Values can be passed from one to another through "expressions": special variables set by each directive, wrapped with
For instance, in the example below, directive
<forEach> iterates through all the items in an array, passing each of them to its composed directive
<applyFunction> through expression
?query= echo([ [banana, apple], [strawberry, grape, melon] ])@fruitJoin< forEach< applyFunction( function: arrayJoin, addArguments: [ array: %value%, separator: "---" ] ) > >
# Directive expressions
An expression, defined through symbols
%...%, is a variable used by directives to pass values to each other. An expression can be pre-defined by the directive or created on-the-fly in the query itself.
In the example below, an array contains strings to translate and the language to translate the string to. The array element is passed from directive
<forEach> to directive
<advancePointerInArray> through pre-defined expression
%value%, and the language code is passed from directive
<advancePointerInArray> to directive
<translate> through variable
%toLang%, which is defined only in the query:
/?query= echo([ [ text: Hello my friends, translateTo: fr ], [ text: How do you like this software so far?, translateTo: es ], ])@translated< forEach< advancePointerInArray( path: text, appendExpressions: [ toLang:extract(%value%,translateTo) ] )< translate( from: en, to: %toLang%, oneLanguagePerField: true, override: true ) > > >
# Skip output if null
Exactly the same result above (
<skip(if(isNull(...)))>) can be accomplished using the
? operator: Adding it after a field, it skips the output of its value if it is null.
/?query= posts. title| featuredimage?. src
# Skip argument names
Field and directive argument names can be deduced from the schema.
/? postId=1& query= post($postId). date(d/m/Y)| title< skip(false) >
...is equivalent to this query:
/? postId=1& query= post(id: $postId). date(format: d/m/Y)| title< skip(if: false) >