{"id":19877461,"url":"https://github.com/mla/text-forge","last_synced_at":"2025-06-22T13:04:23.436Z","repository":{"id":15061868,"uuid":"17788077","full_name":"mla/text-forge","owner":"mla","description":"Embedded Perl Templating","archived":false,"fork":false,"pushed_at":"2020-06-13T05:59:53.000Z","size":53,"stargazers_count":2,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-01T01:45:19.672Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mla.png","metadata":{"files":{"readme":"README.md","changelog":"Changes","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-03-15T23:39:04.000Z","updated_at":"2020-06-13T05:59:56.000Z","dependencies_parsed_at":"2022-07-16T11:30:29.805Z","dependency_job_id":null,"html_url":"https://github.com/mla/text-forge","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/mla/text-forge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mla%2Ftext-forge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mla%2Ftext-forge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mla%2Ftext-forge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mla%2Ftext-forge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mla","download_url":"https://codeload.github.com/mla/text-forge/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mla%2Ftext-forge/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261296915,"owners_count":23137217,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-12T16:37:30.085Z","updated_at":"2025-06-22T13:04:18.425Z","avatar_url":"https://github.com/mla.png","language":"Perl","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SYNOPSIS\n\n    use Text::Forge;\n\n    my $forge = Text::Forge-\u003enew;\n\n    # template in external file\n    print $forge-\u003erun('path/to/template');\n\n    # template passed as reference\n    print $forge-\u003erun(\\'\n      \u003c% my $d = scalar localtime %\u003eThe date is \u003c%= $d %\u003e\n    ');\n    # Outputs: The date is Fri Nov 26 11:32:22 2010\n\n# DESCRIPTION\n\nThis module uses templates to generate documents dynamically. Templates\nare normal text files with a bit of special syntax that allows Perl code\nto be embedded.\n\nThe following tags are supported:\n\n    \u003c%  %\u003e code block (no output)\n    \u003c%= %\u003e interpolate, result is HTML escaped\n    \u003c%? %\u003e interpolate, result is URI escaped\n    \u003c%$ %\u003e interpolate, no escaping (let's be careful)\n    \u003c%# %\u003e comment\n\nAll blocks are evaluated within the same lexical scope (so my\nvariables declared in one block are visible in subsequent blocks).\n\nCode blocks contain straight Perl code; it is executed, but nothing\nis output.\n\nInterpolation blocks are evaluated and the result inserted into\nthe template.\n\nTemplates are compiled into normal Perl methods. They can\nbe passed arguments, as you might expect:\n\n    print $forge-\u003erun(\n      \\'\u003c% my %args = @_ %\u003eName is \u003c%= $args{name} %\u003e',\n      name =\u003e 'foo'\n    );\n\nThe $self variable is available within all templates, and is a reference\nto the Text::Forge instance that is generating the document. This allows\nsubclasses to provide customization and context to templates.\n\nAnything printed to standard output (STDOUT) becomes part of the template.\n\nAny errors in compiling or executing a template raises an exception.\nErrors should correctly reference the template line causing the problem.\n\nIf a block is followed solely by whitespace up to the next newline,\nthat whitespace (including the newline) will be suppressed from the output.\nIf you really want a newline, add another newline after the block.\nThe idea is that the blocks themselves shouldn't affect the formatting.\n\n# METHODS \n\n## new\n\nConstructor. Returns a Text::Forge instance.\n\n    my $forge = Text::Forge-\u003enew(%options);\n\n## run\n\nGenerate a template. The first argument is the template, which may be\neither a file path or a reference to a scalar. Any additional arguments\nare passed to the template.\n\n    my $content = $forge-\u003erun('path/to/my/template', name =\u003e 'foo');\n\nIf a path is supplied and is not absolute, it will be searched for within\nthe list of [\"search\\_paths\"](#search_paths).\n\nThe generated output is returned.\n\n## cache\n\n    my $forge = Text::Forge-\u003enew;\n    $forge-\u003ecache(1);\n\nSpecifies whether templates should be cached. Defaults to true.\n\nIf caching is enabled, templates are compiled into subroutines once and\nthen reused.\n\nIf you want to ensure templates always reflect the latest changes\non disk (such as during development), set cache() to false.\n\nIf you want to maximize performance, set cache() to true.\n\n## charset\n\n    my $forge = Text::Forge-\u003enew;\n    $forge-\u003echarset('iso-8859-1');\n\nSpecifies the character encoding to use for templates.\nDefaults to Unicode (utf8).\n\n## search\\_paths\n\nThe list of directories to search for relative template paths.\n\n    my $forge = Text::Forge-\u003enew;\n    $forge-\u003esearch_paths('/app/templates', '.');\n\n    # will look for /app/templates/header and ./header\n    $forge-\u003erun('header');\n\n## content\n\nReturns the result of the last call to run().\n\n# TEMPLATE METHODS\n\nThe following methods are intended for use _within_ templates. It's all the\nsame object though, so knock yourself out.\n\n## include\n\nInclude one template within another.\n\nFor example, if you want to insert a \"header\" template within another\ntemplate. Note that arguments can be passed to included templates and\nvalues can be returned (like normal function calls).\n\n    my $forge = Text::Forge-\u003enew;\n    $forge-\u003erun(\\'\u003c% $self-\u003einclude(\"header\", title =\u003e 'Hi') %\u003eHello');\n\n## capture\n\nCapture the output of a template.\n\nUsed to capture (but not necessarily include) one template within another.\nFor example:\n\n    my $forge = Text::Forge-\u003enew;\n    $forge-\u003erun(\\'\n      \u003c% my $pagination = $self-\u003ecapture(sub { %\u003e\n           Page \n           \u003cul\u003e\n             \u003c% foreach (1..10) { %\u003e\n                  \u003cli\u003e\u003c%= $_ %\u003e\u003c/li\u003e\n             \u003c% } %\u003e\n           \u003c/ul\u003e\n      \u003c% }) %\u003e\n\n      \u003ch1\u003eTitle\u003c/h1\u003e\n      \u003c%$ $pagination %\u003e\n      Results...\n      \u003c%$ $pagination %\u003e\n    ');\n\nIn this case the \"pagination\" content has been captured into the variable\n$pagination, which is then inserted in multiple locations elsewhere in\nthe document.\n\n## content\\_for \n\nCapture the output into a named placeholder. Same as [\"capture\"](#capture) except the\nresult in stored internally as $forge-\u003e{captures}{ $name }.\n\nNote that multiple calls to content\\_for() with the same name are concatenated\ntogether (not overwritten); this allows, for example, multiple calls\nto something like content\\_for('head', ...), which are then aggregated and\ninserted elsewhere in the document.\n\nWhen called with two arguments, this method stores the specified content in\nthe named location:\n\n    my $forge = Text::Forge-\u003enew;\n    $forge-\u003erun(\\'\n      \u003ch1\u003eTitle\u003c/h1\u003e\n\n      \u003c% $self-\u003ecapture_for('nav', sub { %\u003e\n           \u003cul\u003e\n             \u003cli\u003e...\u003c/li\u003e\n           \u003c/ul\u003e\n      \u003c% }) %\u003e\n    ');\n\nWhen called with one argument, it returns the previously stored content, if any:\n\n    my $nav = $self-\u003econtent_for('nav');\n\n## layout\n\nSpecifies a layout template to apply. Defaults to none.\n\nIf defined, the layout template is applied after the primary template\nhas been generated. The layout template may then \"wrap\" the primary template\nwith additional content.\n\nFor example, rather than have each template [\"include\"](#include) a separate header\nand footer template explicitly, a layout() template can be used more\nsimply:\n\n    my $forge = Text::Forge-\u003enew;\n    $forge-\u003elayout(\\'\u003chtml\u003e\u003cbody\u003e\u003c%$ $_ %\u003e\u003c/body\u003e\u003c/html\u003e');\n    print $forge-\u003erun(\\'\u003ch1\u003eHello, World!\u003c/h1\u003e');\n\n    # results in:\n    # \u003chtml\u003e\u003cbody\u003e\u003ch1\u003eHello, World!\u003c/h1\u003e\u003c/body\u003e\u003c/html\u003e\n\nWithin the layout, the primary template content is available as $\\_ (as well\nas through $self-\u003econtent\\_for('main')).\n\n## escape\\_html, h\n\nReturns HTML encoded versions of its arguments. This method is used internally\nto encode the result of \u003c%= %\u003e blocks, but can be used directly:\n\n    my $forge = Text::Forge-\u003enew;\n    print $forge-\u003erun(\\'\u003c% print $self-\u003eescape_html(\"\u003cstrong\u003e\") %\u003e');\n    # outputs: \u0026lt;strong\u0026gt;\n\nThe h() method is just an alias for convenience.\n\nIf a blessed reference is passed that provides an as\\_html() method, the\nresult of that method will be returned instead. This allows objects to\nbe constructed that keep track of their own encoding state.\n\n## escape\\_uri, u\n\nReturns URI escaped versions of its arguments. This method is used internally\nto encode the result of \u003c%? %\u003e blocks, but can be used directly:\n\n    my $forge = Text::Forge-\u003enew;\n    print $forge-\u003erun(\\'\u003c% print $self-\u003eescape_uri(\"name=foo\") %\u003e');\n    # outputs: name%3Dfoo\n\nThe u() method is just an alias for convenience.\n\nIf a blessed reference is passed that provides an as\\_uri() method, the\nresult of that method will be returned instead. This allows objects to\nbe constructed that keep track of their own encoding state.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmla%2Ftext-forge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmla%2Ftext-forge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmla%2Ftext-forge/lists"}