{"id":16012458,"url":"https://github.com/knowsuchagency/ninjadog","last_synced_at":"2025-03-15T10:30:50.907Z","repository":{"id":22049393,"uuid":"95086450","full_name":"knowsuchagency/ninjadog","owner":"knowsuchagency","description":"Pug/Jinja template support for Python. ","archived":false,"fork":false,"pushed_at":"2024-05-06T04:32:08.000Z","size":2090,"stargazers_count":24,"open_issues_count":18,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-14T23:36:50.467Z","etag":null,"topics":["html","jinja2","pug","python"],"latest_commit_sha":null,"homepage":"http://journalpanic.com/ninjadog","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/knowsuchagency.png","metadata":{"files":{"readme":"README.rst","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-06-22T07:19:51.000Z","updated_at":"2024-07-09T23:46:54.000Z","dependencies_parsed_at":"2023-12-04T05:24:12.249Z","dependency_job_id":"a9e635a7-2e0f-4137-9e5f-e854b9c3c1e2","html_url":"https://github.com/knowsuchagency/ninjadog","commit_stats":{"total_commits":231,"total_committers":2,"mean_commits":115.5,"dds":"0.0043290043290042934","last_synced_commit":"54f0c98da1006d97b6e39d39d0e4e056288f52d0"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knowsuchagency%2Fninjadog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knowsuchagency%2Fninjadog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knowsuchagency%2Fninjadog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knowsuchagency%2Fninjadog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/knowsuchagency","download_url":"https://codeload.github.com/knowsuchagency/ninjadog/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243663571,"owners_count":20327303,"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":["html","jinja2","pug","python"],"created_at":"2024-10-08T14:03:32.081Z","updated_at":"2025-03-15T10:30:50.307Z","avatar_url":"https://github.com/knowsuchagency.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"========\nninjadog\n========\n\n\n.. image:: https://img.shields.io/pypi/v/ninjadog.svg\n        :target: https://pypi.org/project/ninjadog/\n\n.. image:: https://img.shields.io/travis/knowsuchagency/ninjadog.svg\n        :target: https://travis-ci.org/knowsuchagency/ninjadog\n\n.. image:: https://pyup.io/repos/github/knowsuchagency/ninjadog/shield.svg\n     :target: https://pyup.io/repos/github/knowsuchagency/ninjadog/\n     :alt: Updates\n\n.. image:: https://img.shields.io/github/license/mashape/apistatus.svg\n\n`Pug`_ template (formerly `jade`_) support in Python\n\n\n* Documentation: http://journalpanic.com/ninjadog\n* GitHub: https://github.com/knowsuchagency/ninjadog\n\n\n\nInstallation\n------------\n\nninjadog requires Python 3, node-js, npm, and the `pug-cli`_ library\n\n::\n\n    brew install npm\n    npm install -g pug-cli\n    pip install ninjadog\n\n\nFor use with `Pyramid`_, just add it to the configuration\n\n.. code-block:: python\n\n    config.include('ninjadog')\n\n\nUsage\n-----\n\nninjadog leverages the `pug-cli`_ library, written in nodejs, to render\n`pug`_ templates in Python.\n\nIt allows you to take something like this\n\n.. code-block:: pug\n\n    html\n        head\n            title my pug template\n        body\n            #content\n                h1 Hello #{name}\n                .block\n                    input#bar.foo1.foo2\n                    input(type=\"text\", placeholder=\"your name\")\n                    if name == \"Bob\"\n                        h2 Hello Bob\n                    ul\n                        for book in books\n                            li= book\n                        else\n                            li sorry, no books\n\n\nand sprinkle some Python over it\n\n.. code-block:: python\n\n    from ninjadog import render\n\n    context = {\n        'name': 'Bob',\n        'books': ['coloring book', 'audio book', \"O'Reilly book\"],\n        'type': 'text',\n    }\n\n    print(render(file=filepath, context=context, pretty=True))\n\nto render this\n\n.. code-block:: html\n\n    \u003c!DOCTYPE html\u003e\n    \u003chtml\u003e\n      \u003chead\u003e\n        \u003ctitle\u003emy pug template\u003c/title\u003e\n      \u003c/head\u003e\n      \u003cbody\u003e\n        \u003cdiv id=\"content\"\u003e\n          \u003ch1\u003eHello Bob\u003c/h1\u003e\n          \u003cdiv class=\"block\"\u003e\n            \u003cinput class=\"foo1 foo2\" id=\"bar\"\u003e\n            \u003cinput type=\"text\" placeholder=\"your name\"\u003e\n            \u003ch2\u003eHello Bob\u003c/h2\u003e\n            \u003cul\u003e\n              \u003cli\u003ecoloring book\u003c/li\u003e\n              \u003cli\u003eaudio book\u003c/li\u003e\n              \u003cli\u003eO'Reilly book\u003c/li\u003e\n            \u003c/ul\u003e\n          \u003c/div\u003e\n        \u003c/div\u003e\n      \u003c/body\u003e\n    \u003c/html\u003e\n\n\nYou can even combine `jinja2`_ syntax for unparalleled\ntemplate-rendering power.\n\n.. code-block:: python\n\n\n    from ninjadog import render\n\n\n    def stop_believing():\n        return False\n\n\n    context = {\n        'stop_believing': stop_believing,\n        'happy': {\n            'birthday': 'today',\n        }\n    }\n\n    template_string = \"\"\"\n    h1 hello, world\n    if happy.birthday == 'today'\n        p it's time to celebrate!\n        p {{ \"Don't\" if not stop_believing() }} stop believing\n    \"\"\"\n\n    print(render(template_string,\n                 context=context,\n                 pretty=True,\n                 with_jinja=True))\n\n\n\n.. code-block:: html\n\n    \u003ch1\u003ehello, world\u003c/h1\u003e\n    \u003cp\u003eit's time to celebrate!\u003c/p\u003e\n    \u003cp\u003eDon't stop believing\u003c/p\u003e\n\n\nWhy?\n----\n\n`Pug`_ templates are a super elegant and expressive way to write\nhtml, IMO.\n\nThere exists a project, `pyjade`_ and a less-popular fork, `pypugjs`_,\nthat are pure-python implementations of the pug template engine,\nbut they have some minor bugs and the maintenance is a bit lacking.\n\nI figured it would be good to have an alternative method to render\n`pug`_ templates that used the native javascript rendering engine.\n\nninjadog does this by spawning the `pug cli`_ as a subprocess.\nThis means that it can't be as fast as a native template engine\nlike `pyjade`_, but it will likely be more reliable over time as\nit's leveraging the popular and well-maintained nodejs implementation.\n\n\nGotchas\n-------\n\nCurrently, rendering a template with `jinja2`_ syntax goes through the following process:\n\n1. Render elements on the initial template through `jinja2`_\n2. Pass the output to the `pug-cli`_, gathering extensions and inclusions in the process\n3. Render the output through `jinja2`_ again, since the original template may have extended or included other templates that countained `jinja2`_ syntax themselves.\n\nWhat this means is that if you want to escape `jinja2`_ syntax, you need to do it twice.\n\nFor example, to have a literal ``{{ escaping inception }}`` rendered,\nyou'll need to have ``{{ \"{{ '{{ escaping inception }}' }}\" }}`` in your template.\n\n对不起\n\n\n.. _pug: https://pugjs.org/api/getting-started.html\n.. _jade: https://naltatis.github.io/jade-syntax-docs/\n.. _pyjade: https://github.com/syrusakbary/pyjade\n.. _pypugjs: https://github.com/matannoam/pypugjs\n.. _pug-cli: https://www.npmjs.com/package/pug-cli\n.. _pug cli: https://www.npmjs.com/package/pug-cli\n.. _jinja2: http://jinja.pocoo.org/\n.. _jinja 2: http://jinja.pocoo.org/\n.. _pyramid: https://trypyramid.com/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fknowsuchagency%2Fninjadog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fknowsuchagency%2Fninjadog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fknowsuchagency%2Fninjadog/lists"}