Data and Templates

Dyngle maintains a block of "Live Data" throughout an operation - a set of named values that can be injected into commands using template syntax.

Template Syntax

Use double-curly-bracket syntax ({{ and }}) to inject values into commands:

dyngle:
  operations:
    hello:
      - echo "Hello {{name}}!"

Input Data

Pass data to operations via stdin as YAML:

echo "name: Francis" | dyngle run hello

Output:

Hello Francis!

Data Sources

Data can come from several sources:

  1. Stdin - YAML data piped to the operation
  2. Values - Declared in the configuration
  3. Expressions - Computed Python values
  4. Data flow operators - Values captured during execution using =>

Global Values

Define values under dyngle: that are available to all operations:

dyngle:
  values:
    environment: production
    region: us-west-2
  operations:
    deploy:
      - echo "Deploying to {{environment}} in {{region}}"

Local Values

Define values within a specific operation:

dyngle:
  operations:
    greet:
      values:
        greeting: Hello
        name: World
      steps:
        - echo "{{greeting}}, {{name}}!"

Nested Object Properties

Access nested properties in dictionaries using dot notation:

dyngle:
  operations:
    weather-report:
      steps:
        - curl -s "https://api.example.com/weather" => weather
        - echo "Temperature: {{weather.temperature}}"
        - echo "Location: {{weather.location.city}}, {{weather.location.country}}"

Important: Dot notation works only for named dictionary properties, not for array indices. You cannot use .0 or other integers in dot notation.

Working with Arrays

For arrays, use Python expressions to extract values:

dyngle:
  values:
    users:
      - name: Alice
        email: [email protected]
      - name: Bob
        email: [email protected]
  operations:
    show-users:
      expressions:
        first-user: get('users')[0]
        first-name: get('users')[0]['name']
        all-names: "[u['name'] for u in get('users')]"
      steps:
        - echo "First user: {{first-name}}"

Data Precedence

When names overlap, Dyngle uses this precedence (highest to lowest):

  1. Live data (populated via => operator)
  2. Local expressions (defined in the operation)
  3. Global expressions (defined under dyngle:)
  4. Local values (defined in the operation)
  5. Global values (defined under dyngle:)
  6. Input data (from stdin)

Example:

dyngle:
  values:
    name: Global
  expressions:
    name: "'Expression'"
  operations:
    test:
      values:
        name: Local
      steps:
        - echo "Start: {{name}}"        # "Local" (local value wins)
        - echo "Override" => name
        - echo "After: {{name}}"         # "Override" (live data wins)

Next Steps