{"id":13698674,"url":"https://github.com/sbcgua/abap_mustache","last_synced_at":"2025-10-24T03:32:11.776Z","repository":{"id":50243011,"uuid":"79266013","full_name":"sbcgua/abap_mustache","owner":"sbcgua","description":"Mustache template engine for ABAP","archived":false,"fork":false,"pushed_at":"2024-06-24T09:43:10.000Z","size":114,"stargazers_count":32,"open_issues_count":3,"forks_count":12,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-09-26T13:21:02.549Z","etag":null,"topics":["abap","abap-mustache","hacktoberfest","mustache","sap","templating"],"latest_commit_sha":null,"homepage":"","language":"ABAP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sbcgua.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-01-17T19:56:45.000Z","updated_at":"2024-08-21T08:28:43.000Z","dependencies_parsed_at":"2024-08-02T19:01:34.998Z","dependency_job_id":null,"html_url":"https://github.com/sbcgua/abap_mustache","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sbcgua%2Fabap_mustache","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sbcgua%2Fabap_mustache/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sbcgua%2Fabap_mustache/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sbcgua%2Fabap_mustache/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sbcgua","download_url":"https://codeload.github.com/sbcgua/abap_mustache/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219866820,"owners_count":16555824,"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":["abap","abap-mustache","hacktoberfest","mustache","sap","templating"],"created_at":"2024-08-02T19:00:51.753Z","updated_at":"2025-10-24T03:32:06.491Z","avatar_url":"https://github.com/sbcgua.png","language":"ABAP","funding_links":[],"categories":["Categories"],"sub_categories":["💡 Code Templates \u0026 Generators"],"readme":"# ABAP Mustache\n\nMustache template engine for ABAP. It implements the [original mustache spec](https://mustache.github.io/mustache.5.html) plus some additions (mainly in plans now :) Mustache is a logic-less template syntax. It is good for generation of HTML or any other text stuff.  \n\n## Versions\n\nThe library has a Steampunk (740+) compatible version, thanks to @DerGuteWolf. Currently it lives in the [steampunk](https://github.com/sbcgua/abap_mustache/tree/steampunk) branch. This version, at the time of publication, is somewhat slower compared to the original (master) due to limited whitelisted features of the steampunk (see the [PR comments](https://github.com/sbcgua/abap_mustache/pull/7#issuecomment-797714683)), but it has own advantages and **may become the default in near future**. **If you are using the library in older environments, please notify in the issues to take it into account**\n\n## Example\n\nLet's assume you have some data like this:\n\n```abap\ntypes: \n  begin of ty_shop_item\n    name  type string,\n    price type s_price, \n  end of ty_shop_item,\n  \n  ty_shop_item_tt type standard table of ty_shop_item,\n\n  begin of ty_shop,\n    shop_name type string,\n    items     type ty_shop_item_tt, \n  end of ty_shop.\n```\nCreate an instance of abap mustache class, feed the desired template to it and then render with your data:\n```abap\ndata lo_mustache type ref to lcl_mustache.\ndata lv_text     type string.\n\n\" c_nl is a shortcut for newline char, e.g. from cl_abap_char_utilities\nlo_mustache = lcl_mustache=\u003ecreate(\n    'Welcome to {{shop_name}}!' \u0026\u0026 c_nl \u0026\u0026 \n    '{{#items}}'                \u0026\u0026 c_nl \u0026\u0026\n    '* {{name}} - ${{price}}'   \u0026\u0026 c_nl \u0026\u0026\n    '{{/items}}' ).\n\nlv_text = lo_mustache-\u003erender( ls_my_data ). \" ls_my_data type ty_shop \n``` \nAs the result (`lv_text`) you'll get some output like this (assuming you filled the `ls_my_data` appropriately):\n```\nWelcome to My Super Store\n* Boots - $99.00\n* T-Short - $49.00\n* Shirts - $59.00\n```\n\n## Supported input and technical details\n\n### Data structure\n\n* Input data may be a structure or a table of any type - it is detected automatically. For a table the template is repeated for each line. The depth of the data is not limited for the moment (so can be table in struc in table in struc ...).\n* In addition, there is a special table type `lcl_mustache=\u003ety_struc_tt` which processed as a universal structure. Field `name` corresponds to tag name (case **insesitive**) and the value may be put either to `val` field or as a reference to `dref`. The latter can be then a reference to a structure or a table. So the above example may would look like:\n\n```abap\ndata lt_uni_data type lcl_mustache=\u003ety_struc_tt.\nfield-symbols \u003ci\u003e like line of lt_uni_data.\n\nappend initial line to lt_uni_data assigning \u003ci\u003e.\n\u003ci\u003e-name = 'shop_name'.\n\u003ci\u003e-val  = 'My Super Store'.\n\nappend initial line to lt_uni_data assigning \u003ci\u003e.\n\u003ci\u003e-name = 'items'.\nget reference of lt_items to \u003ci\u003e-dref. \" lt_items is the ty_shop_item_tt filled elsewhere\n...\nlv_text = lo_mustache-\u003erender( lt_uni_data ).\n```  \n\n* The `lcl_mustache=\u003ety_struc_tt` is mainly intended to be the root structure. Supposedly it is convenient to prepare parts of data as regular structures and tables. However, combining them all together at the top level in yet another dedicated structure may be cumbersome. This is where `lcl_mustache=\u003ety_struc_tt` may serve well. Although you are free to choose your own way of course.\n\n### Templates    \n\n* Template may be a string or a table of strings (`type string_table`)\n\n```abap\nlo_mustache = lcl_mustache=\u003ecreate( lv_template ). \" iv_template = lv_template\n* OR\nlo_mustache = lcl_mustache=\u003ecreate( it_template = lt_template_tab ). \" TABLE of strings\n```\n\n* Output can be received as a string or a table of string (`type string_table`)\n```abap\nlv_text = lo_mustache-\u003erender( ls_my_data ).\n* OR\nlt_text_tab = lo_mustache-\u003erender_tt( ls_my_data ). \" TABLE\n```\n\n* Template as table is supposed to be separated by newlines. So in case of string rendering newline char will be inserted between template lines. In case of `render_tt` newline char is not inserted (still if any template line contain line breaks it will be split into several output table lines).\n* Input string template is split by newline chars for internal processing. Both `LF` and `CRLF` separators are supported (detected automatically). \n\n### Partials\n\nThe class supports partials (see example below). So you may prepare your templates in convenient and logical sections. And reuse them if necessary.\n\n```abap\nlo_mustache = lcl_mustache=\u003ecreate(\n    'Welcome to {{shop_name}}!' \u0026\u0026 c_nl \u0026\u0026 \n    '{{\u003eitems_template}}' ).  \" \u003c\u003c Calling partial !\n\nlo_partial  = lcl_mustache=\u003ecreate(\n    '{{#items}}'                \u0026\u0026 c_nl \u0026\u0026\n    '* {{name}} - ${{price}}'   \u0026\u0026 c_nl \u0026\u0026\n    '{{/items}}' ).\n\nlo_mustache-\u003eadd_partial(     \" Register partial\n  iv_name = 'items_template' \n  io_obj  = lo_partial ).\n\nlv_text = lo_mustache-\u003erender( ls_my_data ). \" ls_my_data type ty_shop \n``` \n\n### More\n\nFurther information can be found in [wiki](https://github.com/sbcgua/abap_mustache/wiki). There are also some notes on performance.\n\n## Installation\n\n* The best option to install is to clone the repository to your SAP system using [abapGit](https://github.com/larshp/abapGit) tool.\n* Alternatively, create `zmustache` and `zmustache_ut` includes and fill with the content of `zmustache.prog.abap` and `zmustache_ut.prog.abap` respectively. `zmustache_ut` is the unit tests include, so you might potentially skip it (just remove the references to `ltcl_mustache` from the first include). \n\n## Plans\n\nHere are some stuff I might be implementing with time:\n\n* Some stuff inspired by [Handlebars](http://handlebarsjs.com/), in particular:\n  * inline partials (within one template)\n  * `if/else`\n  * `each/else`\n  * `with` and maybe path features (not sure) \n  * section parameters\n  * maybe some sort of helpers\n* calling object methods for parts of data\n* references to object attributes (maybe, if will be needed)\n\nStill some real usage statistics would be valuable to decide on this or that feature. \n\n## Contribution\n\nContribution is always welcomed :)\n\n## License\n\nThe code is licensed under MIT License. Please see [LICENSE](/LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsbcgua%2Fabap_mustache","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsbcgua%2Fabap_mustache","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsbcgua%2Fabap_mustache/lists"}