Template guide
Sections
Sections let you repeat entire chunks of a document — including tables, images, and nested sections — for each item in a collection.
When to use sections
Use sections when you need to repeat a structure more complex than a simple table row. A section can contain paragraphs, tables, images, fields, and even other sections.
Creating a section in LibreOffice
- Select the content you want to repeat (or place your cursor where you want the section)
- Go to Insert > Section...
- Give the section a name (e.g.,
SC_INVOICE) - Click Insert
The section will appear with a subtle border in LibreOffice.
Basic usage
@invoices = Invoice.all
report = ODFReport::Report.new("template.odt") do |r|
r.add_section("SC_INVOICE", @invoices) do |s|
s.add_field(:number) { |invoice| invoice.number.to_s.rjust(5, '0') }
s.add_field(:customer_name)
s.add_field(:customer_address)
s.add_field(:total) { |invoice| format("$%.2f", invoice.total) }
end
end
For each invoice in @invoices, the section is cloned and its placeholders are replaced with that invoice's data.
Adding tables inside sections
Sections can contain tables. When adding a table to a section, pass a symbol for the collection instead of the array itself — this symbol refers to a method on each section item:
r.add_section("SC_INVOICE", @invoices) do |s|
s.add_field(:number)
s.add_field(:customer_name)
s.add_table("TB_ITEMS", :items, header: true) do |t|
t.add_column(:product) { |item| item.product.name }
t.add_column(:quantity)
t.add_column(:price, :product_value)
end
end
Here, :items refers to invoice.items — the collection for that particular invoice's table. Each cloned section gets its own table populated with that invoice's line items.
Nesting sections
Sections can contain other sections:
r.add_section("SC_INVOICE", @invoices) do |s|
s.add_field(:number)
s.add_section("SUB_NOTES", :notes) do |s1|
s1.add_field(:note_title) { |note| note.title }
s1.add_field(:note_body) { |note| note.body }
end
end
The inner section SUB_NOTES is repeated for each note belonging to each invoice.
Images inside sections
r.add_section("SC_PRODUCTS", @products) do |s|
s.add_field(:product_name)
s.add_image(:product_photo) { |product| product.photo_path }
end
Empty collections
When the collection is nil or empty, the section is removed from the document entirely. This is the default behavior — no extra option needed.
How data sources work in sections
Inside a section block, the data source for nested elements works differently than at the report level:
- At the report level,
add_field(:name, "value")uses the literal string - Inside a section,
add_field(:name)callsrecord.nameon each collection item - For nested tables, pass a symbol (
:items) instead of an array — it callsrecord.items
See Data sources for the full explanation.