{"id":13815231,"url":"https://github.com/moremoban/moban","last_synced_at":"2026-01-14T08:29:16.205Z","repository":{"id":6056670,"uuid":"50467109","full_name":"moremoban/moban","owner":"moremoban","description":"General purpose static text generator using Jinja2 and other python template engines","archived":false,"fork":false,"pushed_at":"2025-04-09T07:41:18.000Z","size":2452,"stargazers_count":34,"open_issues_count":27,"forks_count":13,"subscribers_count":3,"default_branch":"dev","last_synced_at":"2025-09-22T09:44:45.914Z","etag":null,"topics":["cli","jinja2"],"latest_commit_sha":null,"homepage":"http://moban.readthedocs.io","language":"Python","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/moremoban.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.rst","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","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},"funding":{"github":"chfw","patreon":"chfw"}},"created_at":"2016-01-26T23:36:07.000Z","updated_at":"2025-08-07T03:01:55.000Z","dependencies_parsed_at":"2024-06-21T02:15:08.172Z","dependency_job_id":"32b720bf-7618-4125-a1d3-722b5402b27f","html_url":"https://github.com/moremoban/moban","commit_stats":{"total_commits":809,"total_committers":12,"mean_commits":67.41666666666667,"dds":0.06427688504326334,"last_synced_commit":"dcb3d9751949247b657aa5423280cf1183bb0a26"},"previous_names":[],"tags_count":61,"template":false,"template_full_name":null,"purl":"pkg:github/moremoban/moban","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moremoban%2Fmoban","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moremoban%2Fmoban/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moremoban%2Fmoban/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moremoban%2Fmoban/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/moremoban","download_url":"https://codeload.github.com/moremoban/moban/tar.gz/refs/heads/dev","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moremoban%2Fmoban/sbom","scorecard":{"id":659945,"data":{"date":"2025-08-11","repo":{"name":"github.com/moremoban/moban","commit":"11306525140a16f8b3231e41c73c48b3cfa4b333"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.8,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 2/24 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/moban-update.yml:1","Warn: no topLevel permission defined: .github/workflows/pythonpackage.yml:1","Warn: no topLevel permission defined: .github/workflows/pythonpublish.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/moban-update.yml:8: update your workflow using https://app.stepsecurity.io/secureworkflow/moremoban/moban/moban-update.yml/dev?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/moban-update.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/moremoban/moban/moban-update.yml/dev?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/moban-update.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/moremoban/moban/moban-update.yml/dev?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pythonpackage.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/moremoban/moban/pythonpackage.yml/dev?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pythonpackage.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/moremoban/moban/pythonpackage.yml/dev?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pythonpublish.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/moremoban/moban/pythonpublish.yml/dev?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pythonpublish.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/moremoban/moban/pythonpublish.yml/dev?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pythonpublish.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/moremoban/moban/pythonpublish.yml/dev?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/moban-update.yml:18","Warn: pipCommand not pinned by hash: .github/workflows/moban-update.yml:19","Warn: pipCommand not pinned by hash: .github/workflows/pythonpackage.yml:21","Warn: pipCommand not pinned by hash: .github/workflows/pythonpackage.yml:22","Warn: pipCommand not pinned by hash: .github/workflows/pythonpackage.yml:23","Warn: pipCommand not pinned by hash: .github/workflows/pythonpackage.yml:29","Warn: pipCommand not pinned by hash: .github/workflows/pythonpublish.yml:25","Warn: pipCommand not pinned by hash: .github/workflows/pythonpublish.yml:26","Info:   0 out of   6 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned","Info:   0 out of   8 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 14 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"12 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: PYSEC-2019-217 / GHSA-462w-v97r-4m45","Warn: Project is vulnerable to: PYSEC-2014-8 / GHSA-8r7q-cvjq-x353","Warn: Project is vulnerable to: GHSA-cpwx-vrp4-4pq7","Warn: Project is vulnerable to: PYSEC-2014-82 / GHSA-fqh9-2qgg-h84h","Warn: Project is vulnerable to: PYSEC-2021-66 / GHSA-g3rq-g295-4j3m","Warn: Project is vulnerable to: GHSA-h5c8-rqwp-cp95","Warn: Project is vulnerable to: GHSA-h75v-3vvj-5mfj","Warn: Project is vulnerable to: PYSEC-2019-220 / GHSA-hj2j-77xm-mc5v","Warn: Project is vulnerable to: GHSA-q2x7-8rv6-6q7h","Warn: Project is vulnerable to: PYSEC-2024-48 / GHSA-fj7x-q9j7-g6q6","Warn: Project is vulnerable to: PYSEC-2022-238 / GHSA-h3qr-fjhm-jphw","Warn: Project is vulnerable to: PYSEC-2023-117 / GHSA-mrwq-x4v8-fh7p"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-21T15:48:43.824Z","repository_id":6056670,"created_at":"2025-08-21T15:48:43.825Z","updated_at":"2025-08-21T15:48:43.825Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28414037,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T08:16:59.381Z","status":"ssl_error","status_checked_at":"2026-01-14T08:13:45.490Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["cli","jinja2"],"created_at":"2024-08-04T04:03:10.142Z","updated_at":"2026-01-14T08:29:16.190Z","avatar_url":"https://github.com/moremoban.png","language":"Python","funding_links":["https://github.com/sponsors/chfw","https://patreon.com/chfw","https://www.patreon.com/chfw","https://www.patreon.com/bePatron?u=5537627"],"categories":["General Purpose Preprocessor","Python"],"sub_categories":["Snippets Manager"],"readme":"================================================================================\nmó bǎn - 模板 General purpose static text generator\n================================================================================\n\n.. image:: https://raw.githubusercontent.com/pyexcel/pyexcel.github.io/master/images/patreon.png\n   :target: https://www.patreon.com/chfw\n\n.. image:: https://codecov.io/gh/moremoban/moban/branch/master/graph/badge.svg\n    :target: https://codecov.io/gh/moremoban/moban\n\n.. image:: https://badge.fury.io/py/moban.svg\n   :target: https://pypi.org/project/moban\n\n.. image:: https://pepy.tech/badge/moban\n   :target: https://pepy.tech/project/moban\n\n.. image:: https://readthedocs.org/projects/moban/badge/?version=latest\n    :target: http://moban.readthedocs.org/en/latest/\n\n.. image:: https://img.shields.io/gitter/room/gitterHQ/gitter.svg\n   :target: https://gitter.im/chfw_moban/Lobby\n\n:Author: C.W. and its contributors (See contributors.rst)\n:Issues: http://github.com/moremoban/moban/issues\n:License: MIT\n\n\nAnnouncement\n================================================================================\n\n\nIn version 0.8.0, `moban.plugins.jinja2.tests.files` is moved to moban-ansible\npackage. `moban.plugins.jinja2.filters.github` is moved to moban-jinja2-github\npackage Please install them for backward compatibility.\n\n\nQuick start\n================================================================================\n\n\n.. code-block:: bash\n\n    $ export HELLO=\"world\"\n    $ moban \"{{HELLO}}\"\n    world\n\nOr\n\n.. code-block:: bash\n\n    $ export HELLO=\"world\"\n    $ echo \"{{HELLO}}\" | moban\n\nOr simply\n\n.. code-block:: bash\n\n    $ HELLO=\"world\" moban \"{{HELLO}}\"\n\n\nA bit formal example:\n\n.. code-block:: bash\n\n    $ moban -c data.yml -t my.template\n    world\n\nGiven data.yml as:\n\n.. code-block:: bash\n\n    hello: world\n\nand my.template as:\n\n\n\n.. code-block:: bash\n\n    {{hello}}\n\n\n\nPlease note that data.yml will take precedence over environment variables.\n\nTemplate inheritance and custom template directories\n-------------------------------------------------------\n\nSuppose there exists `shared/base.jj2`, and two templates `child1.jj2` and\n`child2.jj2` derives from it. You can do:\n\n.. code-block:: bash\n\n    $ moban -t child1.jj2 -td shared -o child1\n    $ moban -t child2.jj2 -td shared -o child2\n\nData overload and custom data directories\n---------------------------------------------\n\nEffectively each data file you give to moban, it overrides environment variables.\nStill you can have different layers of data. For example, you can have\n`shared/company_info.yml`,  use `project1.yml` for project 1 and\n`project2.yml` for project 2. In each of the derived data file, simply mention:\n\n.. code-block:: bash\n\n   overrides: company_info.yml\n   ...\n\nHere is the command line to use your data:\n\n.. code-block:: bash\n\n   $ moban -cd shared -c project1.yaml -t README.jj2\n\nCustom jinja2 extension\n---------------------------\n\nmoban allows the injection of user preferred jinja2 extensions:\n\n.. code-block:: bash\n\n   $ moban -e jj2=jinja2_time.TimeExtension ...\n\n\nWell, can I nick some existing functions as filters, tests? Or create a global from another library?\n-----------------------------------------------------------------------------------------------------\n\nSure, you can use the same '-e' syntax:\n\n.. code-block:: bash\n\n   $ moban -e jinja2=filter:module.path.filter_function \\\n              jinja2=test:module.path.test_function \\\n              jinja2=global:identifier=module.path.variable\n\nIn this case, you would have to include the external library in your own requirements.txt\n\nHere is an example:\n\n\n.. code-block:: bash\n\n   $ moban -e jinja2=filter:moban.externals.file_system.url_join \\\n     jinja2=test:moban.externals.file_system.exists \\\n     jinja2=global:description=moban.constants.PROGRAM_DESCRIPTION \\\n     -t \"{{ 'a'|url_join('b')}} {{'b' is exists}}\"\n\nCan I write my own jinja2 test, filter and/or globals?\n-----------------------------------------------------------\n\nmoban allows the freedom of craftsmanship. Please refer to the docs for more\ndetails. Here is an example:\n\n.. code-block:: python\n\n   import sys\n   import base64\n   \n   from moban.plugins.jinja2.extensions import JinjaFilter\n   \n   \n   @JinjaFilter()\n   def base64encode(string):\n       if sys.version_info[0] \u003e 2:\n           content = base64.b64encode(string.encode(\"utf-8\"))\n           content = content.decode(\"utf-8\")\n       else:\n           content = base64.b64encode(string)\n       return content\n\nAnd you can use it within your jinja2 template, `mytest.jj2`:\n\n\n\n.. code-block:: python\n\n      {{ 'abc' | base64encode }}\n\n\nAssume that the custom example was saved in `custom-jj2-plugin`\n\n.. code-block:: bash\n\n   $ moban -pd custom-jj2-plugin -t mytest.jj2 ...\n\nMoban will then load your custom jinja2 functions\n\nSlim template syntax for jinja2\n---------------------------------\n\nwith `moban-slim \u003chttps://github.com/moremoban/moban-slim\u003e`_ installed,\n\nGiven a data.json file with the following content\n\n.. code-block::\n\n    {\n      \"person\": {\n        \"firstname\": \"Smith\",\n        \"lastname\": \"Jones\",\n      },\n    }\n\n.. code-block:: bash\n\n\n   $ moban --template-type slim -c data.json  \"{{person.firstname}} {{person.lastname}}\"\n   Smith Jones\n\nHandlebars.js template\n----------------------------\n\nWith `moban-handlebars \u003chttps://github.com/moremoban/moban-handlebars\u003e`_\ninstalled,\n\nGiven a data.json file with the following content\n\n.. code-block::\n\n    {\n      \"person\": {\n        \"firstname\": \"Yehuda\",\n        \"lastname\": \"Katz\",\n      },\n    }\n\n\n.. code-block:: bash\n\n\n   $ moban --template-type handlebars -c data.json  \"{{person.firstname}} {{person.lastname}}\"\n   Yehuda Katz\n\nFor `handlebars.js` users, yes, the example was copied from handlebarjs.com. The\naim is to show off what we can do.\n\nLet's continue with a bit more fancy feature:\n\n\n\n.. code-block:: bash\n\n   $ moban --template-type handlebars -c data.json \"{{#with person}}{{firstname}} {{lastname}} {{/with}}\"\n\n\nMoban's way of `pybar3 usage \u003chttps://github.com/wbond/pybars3#usage\u003e`_:\n\nLet's save the following file a `script.py` under `helper_and_partial` folder:\n\n.. code-block:: python\n\n   from moban_handlebars.api import Helper, register_partial\n\n   register_partial('header', '\u003ch1\u003ePeople\u003c/h1\u003e')\n\n\n   @Helper('list')\n   def _list(this, options, items):\n       result = [u'\u003cul\u003e']\n       for thing in items:\n           result.append(u'\u003cli\u003e')\n           result.extend(options['fn'](thing))\n           result.append(u'\u003c/li\u003e')\n       result.append(u'\u003c/ul\u003e')\n       return result\n\nAnd given `data.json` reads as the following:\n\n.. code-block::\n\n   {\n       \"people\":[\n           {\"name\": \"Bill\", \"age\": 100},\n           {\"name\": \"Bob\", \"age\": 90},\n           {\"name\": \"Mark\", \"age\": 25}\n       ]\n   }\n\nLet's invoke handlebar template:\n\n\n.. code-block:: bash\n\n   $ moban --template-type hbs -pd helper_and_partial -c data.json \"{{\u003eheader}}{{#list people}}{{name}} {{age}}{{/list}}\"\n   Handlebars-ing {{\u003eheader}... to moban.output\n   Handlebarsed 1 file.\n   $ cat moban.output\n   \u003ch1\u003ePeople\u003c/h1\u003e\u003cul\u003e\u003cli\u003eBill 100\u003c/li\u003e\u003cli\u003eBob 90\u003c/li\u003e\u003cli\u003eMark 25\u003c/li\u003e\u003c/ul\u003e\n\n\nVelocity template\n----------------------------\n\nWith `moban-velocity \u003chttps://github.com/moremoban/moban-velocity\u003e`_\ninstalled,\n\nGiven the following data.json:\n\n.. code-block::\n\n   {\"people\":\n       [\n           {\"name\": \"Bill\", \"age\": 100},\n           {\"name\": \"Bob\", \"age\": 90},\n           {\"name\": \"Mark\", \"age\": 25}\n       ]\n   }\n\nAnd given the following velocity.template:\n\n.. code-block::\n\n   Old people:\n   #foreach ($person in $people)\n    #if($person.age \u003e 70)\n     $person.name\n    #end\n   #end\n   \n   Third person is $people[2].name\n\n**moban** can do the template:\n\n.. code-block:: bash\n\n   $ moban --template-type velocity -c data.json -t velocity.template\n   Old people:\n\n   Bill\n \n   Bob\n \n \n   Third person is Mark\n\n\n\nCan I write my own template engine?\n--------------------------------------\n\nYes and please check for `more details \u003chttps://github.com/moremoban/moban/tree/dev/tests/regression_tests/level-7-b-template-engine-plugin\u003e`_.\n\nGiven the following template type function, and saved in custom-plugin dir:\n\n.. code-block:: python\n\n   from moban.core.content_processor import ContentProcessor\n   \n   \n   @ContentProcessor(\"de-duplicate\", \"De-duplicating\", \"De-duplicated\")\n   def de_duplicate(content: str, options: dict) -\u003e str:\n       lines = content.split(b'\\n')\n       new_lines = []\n       for line in lines:\n           if line not in new_lines:\n               new_lines.append(line)\n       return b'\\n'.join(new_lines)\n\n\nYou can start using it like this:\n\n.. code-block:: bash\n\n   $ moban --template-type de-duplicate -pd custom-plugin -t duplicated_content.txt\n\n\nTOML data format\n----------------------\n\n`moban-anyconfig \u003chttps://github.com/moremoban/moban-anyconfig\u003e`_ should be installed first.\n\nGiven the following toml file, sample.toml:\n\n.. code-block::\n\n   title = \"TOML Example\"\n   [owner]\n   name = \"Tom Preston-Werner\"\n\n\nYou can do:\n\n\n.. code-block:: bash\n\n   $ moban -c sample.toml \"{{owner.name}} made {{title}}\"\n   Tom Preston-Werner made TOML Example\n\nNot limited to toml, you can supply moban with the following data formats:\n\n.. csv-table:: Always supported formats, quoting from python-anyconfig\n   :header: \"Format\", \"Type\", \"Requirement\"\n   :widths: 15, 10, 40\n\n   JSON, json, ``json`` (standard lib) or ``simplejson``\n   Ini-like, ini, ``configparser`` (standard lib)\n   Pickle, pickle, ``pickle`` (standard lib)\n   XML, xml, ``ElementTree`` (standard lib)\n   Java properties, properties, None (native implementation with standard lib)\n   B-sh, shellvars, None (native implementation with standard lib)\n\nFor any of the following data formats, you elect to install by yourself.\n\n.. csv-table:: Supported formats by pluggable backend modules\n   :header: \"Format\", \"Type\", \"Required backend\"\n   :widths: 15, 10, 40\n\n   Amazon Ion, ion, ``anyconfig-ion-backend`` \n   BSON, bson, ``anyconfig-bson-backend`` \n   CBOR, cbor, ``anyconfig-cbor-backend``  or ``anyconfig-cbor2-backend`` \n   ConifgObj, configobj, ``anyconfig-configobj-backend`` \n   MessagePack, msgpack, ``anyconfig-msgpack-backend``\n\nOr you could choose to install all:\n\n.. code-block:: bash\n\n   $ pip install moban-anyconfig[all-backends]\n\n**Why not to use python-anyconfig itself, but yet another package?**\n\nmoban gives you a promise of any location which `python-anyconfig` does not support.\n\n**Why do it mean 'any location'?**\n\nThanks to `pyfilesystem 2 \u003chttps://github.com/PyFilesystem/pyfilesystem2\u003e`_,\nmoban is able to read data back from `git repo \u003chttps://github.com/moremoban/gitfs2\u003e`_, `pypi \u003chttps://github.com/moremoban/pypifs\u003e`_ package, `http(s) \u003chttps://github.com/moremoban/httpfs\u003e`_, zip,\ntar, ftp, `s3 \u003chttps://github.com/PyFilesystem/s3fs\u003e`_ or `you name it \u003chttps://www.pyfilesystem.org/page/index-of-filesystems/\u003e`_.\n\n\nTemplates and configuration files over HTTP(S)\n================================================================================\n\n`httpfs \u003chttps://github.com/moremoban/httpfs\u003e`_ should be installed first.\n\nWith httpfs, `moban`_ can access any files over http(s) as its\ntemplate or data file:\n\n.. code-block:: bash\n\n    $ moban -t 'https://raw.githubusercontent.com/moremoban/pypi-mobans/dev/templates/_version.py.jj2'\\\n      -c 'https://raw.githubusercontent.com/moremoban/pypi-mobans/dev/config/data.yml'\\\n      -o _version.py\n\n\n.. _moban: https://github.com/moremoban/moban\n\nIn an edge case, if github repo's public url is given,\nthis github repo shall not have sub repos. This library will fail to\ntranslate sub-repo as url. No magic.\n\nTemplates and configuration files in a git repo\n================================================================================\n\n`gitfs2 \u003chttps://github.com/moremoban/gitfs2\u003e`_ is optional since v0.7.0 but was\ninstalled by default since v0.6.1\n\nYou can do the following with moban:\n\n.. code-block:: bash\n\n    $ moban -t 'git://github.com/moremoban/pypi-mobans.git!/templates/_version.py.jj2' \\\n            -c 'git://github.com/moremoban/pypi-mobans.git!/config/data.yml' \\\n            -o _version.py\n    Info: Found repo in /Users/jaska/Library/Caches/gitfs2/repos/pypi-mobans\n    Templating git://github.com/moremoban/pypi-mobans.git!/templates/_version.py.jj2 to _version.py\n    Templated 1 file.\n    $ cat _version.py\n    __version__ = \"0.1.1rc3\"\n    __author__ = \"C.W.\"\n\n\nTemplates and configuration files in a python package\n================================================================================\n\n`pypifs \u003chttps://github.com/moremoban/pypifs\u003e`_ is optional since v0.7.0 but\nwas installed by default since v0.6.1\n\nYou can do the following with moban:\n\n.. code-block:: bash\n\n    $ moban -t 'pypi://pypi-mobans-pkg/resources/templates/_version.py.jj2' \\\n            -c 'pypi://pypi-mobans-pkg/resources/config/data.yml' \\\n            -o _version.py\n    Collecting pypi-mobans-pkg\n    ....\n    Installing collected packages: pypi-mobans-pkg\n    Successfully installed pypi-mobans-pkg-0.0.7\n    Templating pypi://pypi-mobans-pkg/resources/templates/_version.py.jj2 to _version.py\n    Templated 1 file.\n    $ cat _version.py\n    __version__ = \"0.1.1rc3\"\n    __author__ = \"C.W.\"\n\nWork with S3 and other cloud based file systems\n================================================================================\n\nPlease install `fs-s3fs \u003chttps://github.com/PyFilesystem/s3fs\u003e`_::\n\n    $ pip install fs-s3fs\n\n\nThen you can access your files in s3 bucket:\n\n\n\n.. code-block:: bash\n\n    $ moban -c s3://${client_id}:${client_secrect}@moremoban/s3data.yml \\\n            -o 'zip://my.zip!/moban.output' {{hello}}\n    $ unzip my.zip\n    $ cat moban.output\n    world\n\n\n\nWhere the configuration sits in a s3 bucket, the output is a file in a zip. The content of s3data.yaml is:\n\n\n.. code-block:\n\n    hello: world\n\nSo what can I do with it\n============================\n\nHere is a list of other usages:\n\n#. `Django Mobans \u003chttps://github.com/django-mobans\u003e`_, templates for django, docker etc.\n#. `Math Sheets \u003chttps://github.com/chfw/math-sheets\u003e`_, generate custom math sheets in pdf\n\n\nAt scale, continous templating for open source projects\n================================================================================\n\n.. image:: https://github.com/moremoban/moban/raw/dev/docs/images/moban-in-pyexcel-demo.gif\n\n**moban** enabled **continuous templating** in `pyexcel \u003chttps://github.com/pyexcel/pyexcel\u003e`_ and\n`coala \u003chttps://github.com//coala/coala\u003e`_ project to keep\ndocumentation consistent across the documentations of individual libraries in the same\norganisation. Here is the primary use case of moban, as of now:\n\n.. image:: https://github.com/moremoban/yehua/raw/dev/docs/source/_static/yehua-story.png\n   :width: 600px\n\n\nUsage beyond command line\n=============================\n\nAll use cases are `documented \u003chttp://moban.readthedocs.org/en/latest/#tutorial\u003e`_\n\nSupport\n================================================================================\n\nIf you like moban, please support me on github,\n`patreon \u003chttps://www.patreon.com/bePatron?u=5537627\u003e`_\nor `bounty source \u003chttps://salt.bountysource.com/teams/chfw-pyexcel\u003e`_ to maintain\nthe project and develop it further.\n\nWith your financial support, I will be able to invest\na little bit more time in coding, documentation and writing interesting extensions.\n\nVision\n================================================================================\n\nAny template, any data in any location\n\n**moban** started with bringing the high performance template engine (JINJA2) for web\ninto static text generation.\n\n**moban** can use other python template engine: mako, handlebars, velocity,\nhaml, slim and tornado, can read other data format: json and yaml, and can access both\ntemplate file and configuration file in\nany location: zip, git, pypi package, s3, etc.\n\n\nCredit\n================================================================================\n\n`jinja2-fsloader \u003chttps://github.com/althonos/jinja2-fsloader\u003e`_ is the key component to enable PyFilesystem2 support in moban\nv0.6x. Please show your stars there too!\n\n\nInstallation\n================================================================================\nYou can install it via pip:\n\n.. code-block:: bash\n\n    $ pip install moban\n\n\nor clone it and install it:\n\n.. code-block:: bash\n\n    $ git clone http://github.com/moremoban/moban.git\n    $ cd moban\n    $ python setup.py install\n\n\nCLI documentation\n================================================================================\n\n.. code-block:: bash\n\n    usage: moban [-h] [-c CONFIGURATION] [-t TEMPLATE] [-o OUTPUT]\n                 [-td [TEMPLATE_DIR [TEMPLATE_DIR ...]]]\n                 [-pd [PLUGIN_DIR [PLUGIN_DIR ...]]] [-cd CONFIGURATION_DIR]\n                 [-m MOBANFILE] [-g GROUP] [--template-type TEMPLATE_TYPE]\n                 [-d DEFINE [DEFINE ...]] [-e EXTENSION [EXTENSION ...]] [-f]\n                 [--exit-code] [-V] [-v]\n                 [template]\n\n    Static text generator using any template, any data and any location.\n\n    positional arguments:\n      template              string templates\n\n    optional arguments:\n      -h, --help            show this help message and exit\n      -c CONFIGURATION, --configuration CONFIGURATION\n                            the data file\n      -t TEMPLATE, --template TEMPLATE\n                            the template file\n      -o OUTPUT, --output OUTPUT\n                            the output file\n\n    Advanced options:\n      For better control\n\n      -td [TEMPLATE_DIR [TEMPLATE_DIR ...]], --template_dir [TEMPLATE_DIR [TEMPLATE_DIR ...]]\n                            add more directories for template file lookup\n      -cd CONFIGURATION_DIR, --configuration_dir CONFIGURATION_DIR\n                            the directory for configuration file lookup\n      -pd [PLUGIN_DIR [PLUGIN_DIR ...]], --plugin_dir [PLUGIN_DIR [PLUGIN_DIR ...]]\n                            add more directories for plugin lookup\n      -m MOBANFILE, --mobanfile MOBANFILE\n                            custom moban file\n      -g GROUP, --group GROUP\n                            a subset of targets\n      --template-type TEMPLATE_TYPE\n                            the template type, default is jinja2\n      -d DEFINE [DEFINE ...], --define DEFINE [DEFINE ...]\n                            to supply additional or override predefined variables,\n                            format: VAR=VALUEs\n      -e EXTENSION [EXTENSION ...], --extension EXTENSION [EXTENSION ...]\n                            to to TEMPLATE_TYPE=EXTENSION_NAME\n      -f                    force moban to template all files despite of\n                            .moban.hashes\n\n    Developer options:\n      For debugging and development\n\n      --exit-code           by default, exist code 0 means no error, 1 means error\n                            occured. It tells moban to change 1 for changes, 2 for\n                            error occured\n      -V, --version         show program's version number and exit\n      -v                    show verbose, try -v, -vv, -vvv\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoremoban%2Fmoban","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmoremoban%2Fmoban","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoremoban%2Fmoban/lists"}