Go to file
Hans Fast 6f2001618b working demo and discussion 2026-02-28 16:12:01 +01:00
.gitignore working demo and discussion 2026-02-28 16:12:01 +01:00
README.md working demo and discussion 2026-02-28 16:12:01 +01:00
a_pubfile.md working demo and discussion 2026-02-28 16:12:01 +01:00
allfiles.sh working demo and discussion 2026-02-28 16:12:01 +01:00
anotherfile.md working demo and discussion 2026-02-28 16:12:01 +01:00
config.ori working demo and discussion 2026-02-28 16:12:01 +01:00
package-lock.json working demo and discussion 2026-02-28 16:12:01 +01:00
package.json working demo and discussion 2026-02-28 16:12:01 +01:00
pubfiles.sh working demo and discussion 2026-02-28 16:12:01 +01:00
select.sh working demo and discussion 2026-02-28 16:12:01 +01:00
sh_handler.js working demo and discussion 2026-02-28 16:12:01 +01:00
site.ori working demo and discussion 2026-02-28 16:12:01 +01:00

README.md

Demonstration of shell handler accepting arguments

The current shell handler in Web Origami allows passing an argument to a .sh file which will be passed to the child process' stdin. Here, we demonstrate how the shell handler could also take arguments and pass those to the child process.

Rationale

Sample and walkthrough

In this example, we're going to filter filenames based on a pattern, using both the stdin mechanism and the argument-passing mechanism.

Modified sh_handler.js

To make this possible, I use a local modified version of the distribution sh_handler.js in this directory. It accepts optional further arguments after the first inputText argument. If these are present, they will be passed as additional arguments in the shell invocation. Hence, you can use both stdin and arguments, and if you do not want to use stdin, you need to pass null as the first argument.

Data

two markdown files, a_pubfile.md and anotherfile.md.

Handlers: stdin approach

  • allfiles.sh is a one-liner: fd -e md. So it returns all Markdown filenames in this tree. As such, it has no need to use stdin. (If you don't have fd, you can replace the contents of the script with find -type f -name "*.md".)
  • pubfiles.sh is another one-liner: rg '_pub' || true. It selects only filenames matching the pattern _pub from its stdin. (If you don't have ripgrep, you can replace rg with grep.)

The purpose of this pair is to demonstrate shell script files as pipe filters: you pass the output of allfiles.sh to the input of pubfiles.sh and get a filtered list. In the shell, that works like this: sh allfiles.sh | sh pubfiles.sh. In Ori: ori "pubfiles.sh allfiles.sh()". In site.ori:

{
  allfiles: allfiles.sh()
  pubfiles: pubfiles.sh(allfiles)
}

Handlers: Argument approach

The remaining shell file select.sh takes an argument and passes it through to fd as a match pattern. In the shell: sh select.sh '_pub'. Ori cli: ori "select.sh(null, '_pub')". In site.ori:

{
  selectedfiles: pubfiles.sh(null, '_pub')
}

Discussion

Whether or not passing arguments to a shell script makes sense in Origami land is actually a subtle question. An Origami project is an interesting type of program in that a lot of config is usually hard-coded. Origami projects are usually things like websites, where there is a single, specific intended output. You don't reuse the project source to generate lots of different outputs; you add data over time (e.g. blog posts) and then regenerate the same site with the latest data set. Hence, it makes sense if database connection strings, or remote http requests, or other 'config' values are hard-coded in the source.

I want to generate a public and a private version of a static website. I could keep two completely separate site.ori files, but that would lead to maintenance problems. So the ability to pass a parameter to the part that selects input files allows me to use one site.ori.

Still, this isn't technically necessary, because you could do this parameterization in Ori-land and call two different shell scripts: since they are one-liners, it's not a problem to have one script for the public source and one script for the private source. Where this would be more useful is if a shell script was wrapping some more complex, opaque data source or calculation engine. In such a case, it could be conceivable that a shell script handler would be worth distributing and reusing, in which case it might be worth making it configurable.

Making data sources parameterizable might open Web Origami up to other types of projects, like data pipelines. I don't really have a compelling case, but having this option would allow more experimentation.