Module: Uniword::TemplateManager

Defined in:
lib/uniword/template_manager.rb

Overview

High-level template library management.

Manages a directory of .docx template files with sidecar metadata (.uniword.json). Provides create, list, and apply operations used by the CLI and directly by Ruby code.

Examples:

Create a template from an existing DOCX

Uniword::TemplateManager.create("report", "report.docx", "templates")

List templates

templates = Uniword::TemplateManager.list("templates")
templates.each { |t| puts t[:name] }

Apply a template

Uniword::TemplateManager.apply("report", { title: "Q1" }, "output.docx", template_dir: "templates")

Constant Summary collapse

METADATA_EXT =
".uniword.json"

Class Method Summary collapse

Class Method Details

.apply(template_name, data, output_path, template_dir:) ⇒ void

This method returns an undefined value.

Apply a template with data to generate a new document.

Loads the named template from the library, renders it with the provided data using Uniword::Template, and saves the result to output_path.

Parameters:

  • template_name (String)

    Name of the template in the library

  • data (Hash)

    Data to fill template markers

  • output_path (String)

    Where to save the rendered document

  • template_dir (String)

    Template library directory

Raises:

  • (ArgumentError)

    If the template is not found in the library



100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/uniword/template_manager.rb', line 100

def self.apply(template_name, data, output_path, template_dir:)
  template_path = File.join(template_dir, "#{template_name}.docx")

  unless File.exist?(template_path)
    raise ArgumentError,
          "Template '#{template_name}' not found in #{template_dir}"
  end

  template = Uniword::Template::Template.load(template_path)
  document = template.render(data)
  document.save(output_path)
end

.create(name, source_docx, output_dir, description: nil) ⇒ Hash

Create a template from an existing DOCX file.

Copies the source DOCX into the template library directory and writes sidecar metadata with name, description, source path, and timestamps.

Parameters:

  • name (String)

    Template name (used as filename stem)

  • source_docx (String)

    Path to the source .docx file

  • output_dir (String)

    Template library directory

  • description (String, nil) (defaults to: nil)

    Optional description of the template

Returns:

  • (Hash)

    Metadata hash for the created template

Raises:

  • (ArgumentError)

    If source file does not exist



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/uniword/template_manager.rb', line 38

def self.create(name, source_docx, output_dir, description: nil)
  unless File.exist?(source_docx)
    raise ArgumentError,
          "Source file not found: #{source_docx}"
  end

  FileUtils.mkdir_p(output_dir)

  dest_path = File.join(output_dir, "#{name}.docx")
  FileUtils.cp(source_docx, dest_path)

   = (
    name: name,
    description: description,
    source: File.basename(source_docx),
  )

  (output_dir, name, )
  
end

.list(template_dir) ⇒ Array<Hash>

List available templates in a directory.

Scans the directory for .docx files, reads their sidecar metadata (if present), and returns an array of template info hashes sorted alphabetically by name.

Parameters:

  • template_dir (String)

    Template library directory

Returns:

  • (Array<Hash>)

    Array of template info hashes, each containing :name, :path, :description, :source, :created_at, :updated_at, :markers



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/uniword/template_manager.rb', line 68

def self.list(template_dir)
  return [] unless Dir.exist?(template_dir)

  docx_files = Dir.glob(File.join(template_dir, "*.docx"))

  docx_files.map do |path|
    name = File.basename(path, ".docx")
     = (template_dir, name)

    {
      name: name,
      path: path,
      description: [:description],
      source: [:source],
      created_at: [:created_at],
      updated_at: [:updated_at],
      markers: [:markers],
    }
  end
end