# `head-context`
Easily manage your assets in meta tags (scripts, css, preload etc.) from anywhere
in the template code (and outside).
## Why
Imagine a form widget, which requires a heavy image processing library that we want to include ONLY IF the widget itself was rendered. Thanks to `head-context` you can specify what resources you need locally (in template fragments, widgets and so on) yet load them in the `head` section of your page with ease.
## What does it do?
```html+jinja
<!doctype html>
<html>
<head>
<title>My Title!</title>
<!-- this is where we want all our js/css rendered to be rendered -->
{{ head_placeholder() }}
</head>
<body>
{% include "my-cool-component.html" %}
</body>
</html>
```
And `my-cool-component.html`:
```html+jinja
<!-- we can call these from anywhere and they will be automatically rendered in the right place! -->
{% do push_js('/static/cool-component.js', mode="async") %}
{% do push_css('/static/cool-component.css') %}
{% do push_preload('/static/some-image-we-need.png', 'image') %}
<div class="my-cool-component">
<!-- ... --->
</div>
```
And that's pretty much it. You can `push_js`/`push_css`/`push_preload` from anywhere in the template (and even outside of templates) and it will be automatically attached to the page being rendered.
## Features
* Supports scripts, styles and preload directives
* Works with Jinja2
* Can be used from Python code too
* simply use `head_context.push_js/push_css/push_preload` from Python code
* it needs to run during template rendering though (otherwise it wouldn't make sense)
* useful if you have form widget rendering written in Python for example
* or basically any kind of rendering written in Python
## Installation and setup
Simply install `head-context` package:
```bash
pip install head-context
# or with poetry
poetry add head-context
```
Add extension to the Jinja2 environment:
```python
from jinja2 import Environment
env = Environment()
env.add_extension("head_context.jinja_ext.HeadContextExtension")
```
and that's it! From now on you can use `push_css()`/`push_js()`/`push_preload()` and `head_placeholder()`.
## Usage with Flask
To use this extension with `Flask` simply add it when configuring the app:
```python
def create_app():
app = Flask("app", __name__)
app.jinja_env.add_extension("head_context.jinja_ext.HeadContextExtension")
app.jinja_env.add_extension("jinja2.ext.do")
return app
```
## FAQ
### Does this work with `asyncio`?
`head-context` uses `contextvars` under the hood, which are compatible with `asyncio` but it integrates with `Jinja` in a way that won't work with templates which use `asyncio` rendering. If you have any good ideas how to make it work a PR would be welcome.
Raw data
{
"_id": null,
"home_page": "https://github.com/rafales/head-context",
"name": "head-context",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8,<4.0",
"maintainer_email": "",
"keywords": "templating,jinja2",
"author": "Rafal Stozek",
"author_email": "rafal.stozek@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/4e/c8/cf7a0bf798bbff63c6d257df756ff03d80b6f38e6590f6489efb51ab610a/head_context-0.1.1.tar.gz",
"platform": null,
"description": "# `head-context`\n\nEasily manage your assets in meta tags (scripts, css, preload etc.) from anywhere\nin the template code (and outside).\n\n## Why\n\nImagine a form widget, which requires a heavy image processing library that we want to include ONLY IF the widget itself was rendered. Thanks to `head-context` you can specify what resources you need locally (in template fragments, widgets and so on) yet load them in the `head` section of your page with ease.\n\n## What does it do?\n\n```html+jinja\n<!doctype html>\n<html>\n<head>\n <title>My Title!</title>\n <!-- this is where we want all our js/css rendered to be rendered -->\n {{ head_placeholder() }}\n</head>\n<body>\n {% include \"my-cool-component.html\" %}\n</body>\n</html>\n```\n\nAnd `my-cool-component.html`:\n\n```html+jinja\n<!-- we can call these from anywhere and they will be automatically rendered in the right place! -->\n{% do push_js('/static/cool-component.js', mode=\"async\") %}\n{% do push_css('/static/cool-component.css') %}\n{% do push_preload('/static/some-image-we-need.png', 'image') %}\n<div class=\"my-cool-component\">\n <!-- ... --->\n</div>\n```\n\nAnd that's pretty much it. You can `push_js`/`push_css`/`push_preload` from anywhere in the template (and even outside of templates) and it will be automatically attached to the page being rendered.\n\n## Features\n\n* Supports scripts, styles and preload directives\n* Works with Jinja2\n* Can be used from Python code too\n * simply use `head_context.push_js/push_css/push_preload` from Python code\n * it needs to run during template rendering though (otherwise it wouldn't make sense)\n * useful if you have form widget rendering written in Python for example\n * or basically any kind of rendering written in Python\n\n\n## Installation and setup\n\nSimply install `head-context` package:\n\n```bash\npip install head-context\n# or with poetry\npoetry add head-context\n```\n\nAdd extension to the Jinja2 environment:\n\n```python\n\nfrom jinja2 import Environment\n\nenv = Environment()\nenv.add_extension(\"head_context.jinja_ext.HeadContextExtension\")\n```\n\nand that's it! From now on you can use `push_css()`/`push_js()`/`push_preload()` and `head_placeholder()`.\n\n## Usage with Flask\n\nTo use this extension with `Flask` simply add it when configuring the app:\n\n```python\n\ndef create_app():\n app = Flask(\"app\", __name__)\n app.jinja_env.add_extension(\"head_context.jinja_ext.HeadContextExtension\")\n app.jinja_env.add_extension(\"jinja2.ext.do\")\n \n return app\n\n```\n\n## FAQ\n\n### Does this work with `asyncio`?\n\n`head-context` uses `contextvars` under the hood, which are compatible with `asyncio` but it integrates with `Jinja` in a way that won't work with templates which use `asyncio` rendering. If you have any good ideas how to make it work a PR would be welcome.\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "",
"version": "0.1.1",
"split_keywords": [
"templating",
"jinja2"
],
"urls": [
{
"comment_text": "",
"digests": {
"md5": "d78b4fdfed62a1b991ff83ac2ef9a47c",
"sha256": "a71b4b745f596e52eeb89a2f578854c99c3ffc266f5c2bf7d1ea3a0d079aca35"
},
"downloads": -1,
"filename": "head_context-0.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "d78b4fdfed62a1b991ff83ac2ef9a47c",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8,<4.0",
"size": 6021,
"upload_time": "2022-12-31T11:02:44",
"upload_time_iso_8601": "2022-12-31T11:02:44.572961Z",
"url": "https://files.pythonhosted.org/packages/54/2a/b0bc8259aa92e8cba0c82e7bfae20605f78328b470910ec35c8f91ee03aa/head_context-0.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"md5": "f3b006363308c086b4485c20ca10ab34",
"sha256": "e0b608313761e917c0b05a0a0a600a9aed59bdef0086d1f97b3fdbac1991f7fc"
},
"downloads": -1,
"filename": "head_context-0.1.1.tar.gz",
"has_sig": false,
"md5_digest": "f3b006363308c086b4485c20ca10ab34",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8,<4.0",
"size": 5644,
"upload_time": "2022-12-31T11:02:45",
"upload_time_iso_8601": "2022-12-31T11:02:45.931307Z",
"url": "https://files.pythonhosted.org/packages/4e/c8/cf7a0bf798bbff63c6d257df756ff03d80b6f38e6590f6489efb51ab610a/head_context-0.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2022-12-31 11:02:45",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "rafales",
"github_project": "head-context",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "head-context"
}