The Shortcode External Caller plugin provides the [external-caller="..."]
shortcode for
Grav to call external programs.
Basically the external program gets an environment and arguments. The text between the opening and ending shortcode is passed to the program as stdin. The complete shortcode is replaced by the HTML output of the external program (stdout).
The output from the external program is not post-processed by the markdown processor of Grav!
Typically a plugin should be installed via GPM (Grav Package Manager):
$ bin/gpm install shortcode-external-caller
Alternatively it can be installed via the Admin Plugin
Using the shortcode like:
[external-caller="PROGRAM ARGUMENTS"]
```
OPTIONAL-STDIN-OF-PROGRAM
```
[/external-caller]
The shortcode is replaced by the HTML output (stdout) of the program. See the examples below. Don't forget the double quotes around the program and its arguments. Enclose the stdin, between the opening and closing shortcode with block code fences. Unless you want Grav to process the stdin with its markdown processor before giving it to the program. (Not really a good idea, if you want to handle indented text to a program. E.g. YAML files.) – But, this is optional. You may want to read the HTML produced by the markdown processor of Grav.
A set of environment variables is defined. You may use them in your program.
Your external program normally returns HTML code which is inserted in your page.
For some applications this is not enough, because you want to inject CSS or Javascript to your page via Grav. No problem. Return a JSON object which contains the HTML and the URLs to the CSS and JS files.
Schematic JSON object:
{
"html": "HTML-CODE",
"css": [ "CSS-URL-1", "CSS-URL-2" ],
"js": [ "JS-URL-1" ]
}
"html"
contains the HTML code inserted to your page.
"css"
is an array of URLs to CSS files. "js"
is an array of URLs to JS files. Both values must be an array, even if containing only one value.
"css"
and "js"
may contain common external URLs pointing to the Web.
Example: "js": [ "https://code.jquery.com/jquery-3.5.1.min.js" ]
To access local CSS or JS files in the context of Grav, say routes, use special protocol specifiers. Discussed in the next chapter.
This chapter is only important, if you return JSON. If the URL starts with self://
,plugin://
, page://
or grav://
this is substituted.
PHP Regular Expression Pattern | Replacement | Example |
---|---|---|
"~^self://~" |
Route to the directory of this plugin. (See: THIS_PLUGIN_PATH) | /user/plugins/shortcode-external-caller |
"~^plugin://~" |
Route to the directory of all plugins. (See: PLUGIN_PATH) | /user/plugins |
"~^page://~" |
Route to the directory of the current page. (See: PAGE_PATH) | /user/page/08.about |
"~^grav://~" |
/ (Slash) – Route to the top level of Grav. This is normally ROOT_PATH, but Grav may have internally other routes, which may alter this behaviour. |
/ |
To access CSS or JS files in the file space of all plugins use URLs starting with plugin://
.
If the root path of all plugins is /var/www/grav_instance/user/plugins/
the location:
plugin://shortcode-external-caller/css/sample.css
will refer to this route:
/user/plugins/shortcode-external-caller/css/sample.css
To access CSS or JS files in the file space of the current page starting with page://
.
If the path to the current page is /var/www/grav_instance/user/page/08.about
the location:
page://css/sample.css
will refer to this route:
/user/page/08.about/css/sample.css
To access CSS or JS files in the file space of Grav use URLs starting with grav://
.
If the path of the Grav instance is /var/www/grav_instance
the location:
grav://css/sample.css
will refer to this route:
/css/sample.css
Warning! Do not misunderstand these helper routes for CSS and JS files with the normal Grav routes. If you enter such a helper route to a markdown page in the browser, you'll go outside the regular Grav routes and neither get any page.
Your decision.
The working directory is the root directory of your Grav instance. This in mind, you may use all kinds of path (absolute, relative).
The program path and all arguments are processed with following replacements. If the program path or argument starts with self://
, plugin://
, page://
or grav://
this is substituted.
PHP Regular Expression Pattern | Replacement |
---|---|
"~^self://~" |
Directory of this plugin. (See: THIS_PLUGIN_PATH) |
"~^plugin://~" |
Root directory of all plugins. (See: PLUGIN_PATH) |
"~^page://~" |
Directory of the current page. (See: PAGE_PATH) |
"~^grav://~" |
Root directory of Grav instance. (See: ROOT_PATH) |
So, you may create a external-bin
directory in the root directory of your Grav instance and place programs (shell scripts, etc.) there.
Example: [external-caller="/bin/sh grav://external-bin/script.sh"]
Alternatively you may use the existing bin
directory from this plugin. Which can be found here. ($ROOT_PATH
is the instance directory of your Grav installation.)
$ROOT_PATH/user/plugins/shortcode-external-caller/bin
Refer a sample script by:
[external-caller="/bin/sh self://bin/inspect.sh"]
Please note! In contrast to the CSS an JS routes (discussed above). These replacements here are concrete file and directory paths. They don't conflict with Grav routes and should always work.
[external-caller="/bin/sh self://bin/inspect.sh"]
If you call programs without the closing shortcode the programs gets an empty stdin.
The inspect.sh
script is delivered with this plugin.
[external-caller="/bin/sh self://bin/inspect.sh One Two Argument\ with\ spaces Four"]
Escape spaces in arguments with a \
(backslash).
[external-caller="/bin/sh self://bin/inspect.sh"]
```
---
planet: Earth
avenger:
-
name: 'Captain America'
superpower: 'Infinity-Formula-Serum'
-
name: 'Iron Man'
superpower: 'Arc-Reaktor'
...
```
[/external-caller]
Here you see a YAML input. Essential to YAML files is the indentation. The block code fences prevent Grav from processing the stdin as markup.
Language: Bourne Shell.
Outputs all environment variables provided by this plugin, the PATH, the arguments and the stdin.
Call: [external-caller="/bin/sh self://bin/inspect.sh"]
Arguments: Optional.
Stdin: Optional.
Output: HTML.
Language: Ruby.
Prerequisite: Ruby, gems: redcarpet, fast_gettext
Creates a map with optional markers.
Call: [external-caller="ruby self://bin/create-embedded-map.rb"]
Arguments: None.
Stdin: YAML file with map definitions.
Output: JSON. The JSON output is processed by this plugin. And HTML is placed to the page. This indirection and its use is described above.
For a complete documentation of this program see: create-embedded-map.md