Skip to content

proposal: text/template: add table action #45752

@heaths

Description

@heaths

I'd like to propose adding a new node to text/template similar to {{range pipeline}} named {{table pipeline}}. Inspired by Docker CLI's pseudo-function to format an array using text/tabwriter, this could be a generally useful way to format an array as columnar data using elastic tabstops.

As noted in cli/cli#3488 (comment), Docker CLI checks if the template starts with "table" and does some simple string pre-parsing. The inherent problem is that the template must start with "table", so you can't first scope a pipeline with {{with pipeline}}, for example. You can't really do this wthin a string either because you need to know where the table columns should end, and only parse tree nodes have {{end}}.

I propose (and interested in contributing) something like range that works on an array, but lets you delimit columns like so:

nodes := []struct{
  Nodes []struct{
    Id string
    Name string
  }
  Description string
}{
  // ...
}

template.Must(template.New("main").Parse(`{{table .Nodes}}{{.Id}}{{"\t"}}{{.Name}}{{end}}`)).Execute(os.Stdout, nodes)

This would product output like:

123  Foo
4567 Bar
8    Baz

The {{end}} node would call Writer.Flush which should effectively set the final tabstops.

Ideally, it would be great to provide some control over tabwriter.NewWriter's arguments. Perhaps {{table}} could support variadic ...[]string arguments to set a few options, but columns can help support that on their own, like a user-defined pad function that prefixes or suffixes padding characters like "..", changing colors, etc. Another option might be to emit a header using the same tabstops so the headers align with the columns, much like Docker CLI does with their pseudo-function.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions