{"id":2969,"library":"html5tagger","title":"HTML5Tagger","description":"HTML5Tagger is a Python library designed for Pythonic HTML generation and templating without the need for external template files. It provides a simplified HTML5 syntax, allowing developers to create entire HTML documents using only Python code. Maintained under the Sanic organization, it aims for speed and simplicity, offering a pure Python implementation with no external dependencies. The library sees infrequent but consistent updates, with the latest major release in March 2023.","status":"active","version":"1.3.0","language":"python","source_language":"en","source_url":"https://github.com/sanic-org/html5tagger","tags":["html","templating","web-development","markup-generation"],"install":[{"cmd":"pip install html5tagger","lang":"bash","label":"Install with pip"}],"dependencies":[{"reason":"Required for execution.","package":"Python","optional":false}],"imports":[{"note":"Primary class for generating full HTML5 documents with a DOCTYPE declaration.","symbol":"Document","correct":"from html5tagger import Document"},{"note":"An empty builder for creating HTML snippets.","symbol":"E","correct":"from html5tagger import E"},{"note":"Used to wrap preformatted HTML strings to prevent automatic escaping, especially for known safe content.","symbol":"HTML","correct":"from html5tagger import HTML"}],"quickstart":{"code":"from html5tagger import Document, E\n\n# Create a full HTML document\ndoc = Document(\n    E.TitleText_,\n    lang=\"en\", # HTML tag attributes as keyword arguments\n    _urls=[\"style.css\", \"script.js\"], # Special argument for linking resources\n)\n\n# Add elements directly or with context managers\nwith doc.body:\n    doc.h1(\"Welcome to html5tagger!\")\n    with doc.p(\"This is an example of creating HTML content in Python. It's \") as p:\n        p.strong(\"easy\")\n        p(\" and \")\n        p.em(\"intuitive\")\n        p(\".\")\n    \n    # Nesting elements\n    with doc.ul:\n        doc.li(\"No manual closing tags for most elements.\")\n        doc.li(\"Attributes are passed as keyword arguments.\")\n        doc.li.a(href=\"https://github.com/sanic-org/html5tagger\")(\"Check out the GitHub repo!\")\n    \n    # Add a paragraph with a dynamic title using template variables\n    doc.p(doc.IntroText_, id=\"intro-paragraph\")\n\n# Fill in template variables (optional)\ndoc.TitleText = \"My Dynamic Page\"\ndoc.IntroText = \"Here's some dynamic content.\"\n\n# Render the document to an HTML string\nhtml_output = doc.render()\nprint(html_output)\n","lang":"python","description":"This quickstart demonstrates how to create a basic HTML5 document using `html5tagger`. It shows how to initialize a `Document` object, add standard HTML elements using attribute access (e.g., `doc.h1`), pass attributes as keyword arguments, nest elements using `with` statements, and utilize template variables for dynamic content. Finally, it shows how to render the complete HTML string."},"warnings":[{"fix":"To close an empty element (e.g., `<script>`) or prevent further nesting into an empty tag after setting attributes, pass `None` as the first argument: `doc.script(None, src='path/to/script.js')`.","message":"Automatic Tag Closing and Empty Elements: Tags are automatically closed when new content or another tag is added. Setting attributes alone does not close an element. For self-closing or empty elements (e.g., `<script src='...'></script>`) where subsequent content should not be nested, explicitly close with `(None)`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"NEVER use `html5tagger.HTML()` to wrap user-generated or untrusted content. Only use it for HTML strings that you have explicitly verified as safe. All other content should be passed directly to HTML5Tagger elements for automatic escaping.","message":"Security: Unsafe use of `html5tagger.HTML()` with untrusted input can lead to Cross-Site Scripting (XSS). While content is generally auto-escaped, `html5tagger.HTML(string)` explicitly marks `string` as safe HTML, bypassing escaping.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Be mindful of the current nesting context when inserting template variables. If the variable should be at a different level, ensure the preceding elements are correctly closed by adding content or explicit `(None)` calls before inserting the template.","message":"Templating behavior: When using template variables, `doc.TemplateName_` does NOT close the preceding tag but inserts the variable's content *inside* any currently open element. This differs from how new tag calls (`doc.p(...)`) close prior tags.","severity":"gotcha","affected_versions":"All versions supporting templating (v1.2.0+)"},{"fix":"While not yet deprecated, consider using `_script` and `_style` for clarity and future compatibility if explicitly handling script/style blocks. Consult the latest documentation for definitive guidance on these methods.","message":"Potential deprecation of non-underscored `_script` and `_style` methods: The introduction of `_script` and `_style` special methods in 2023 suggests a potential future shift to primarily use underscored versions for special element handling, with the non-underscored versions potentially being deprecated or changed.","severity":"deprecated","affected_versions":"v1.2.0+"}],"env_vars":null,"search_vec":"'2023':72 'aim':44 'allow':27 'code':37 'consist':63 'creat':30 'depend':57 'design':7 'develop':28,77 'document':33 'entir':31 'extern':18,56 'file':20 'generat':11,80 'html':10,32,73 'html5':25 'html5tagger':1,2 'implement':53 'infrequ':61 'latest':67 'librari':6,59 'maintain':38 'major':68 'march':71 'markup':79 'markup-gener':78 'need':16 'offer':49 'organ':42 'provid':22 'pure':51 'python':5,9,36,52 'releas':69 'sanic':41 'see':60 'simplic':48 'simplifi':24 'speed':46 'syntax':26 'templat':13,19,74 'updat':64 'use':34 'web':76 'web-develop':75 'without':14","created_at":"2026-04-11T09:15:21.816195+00:00","updated_at":"2026-04-16T15:36:33.949764+00:00","problems":[{"fix":"Append an underscore to the reserved keyword to use it as an attribute, e.g., `E.div(class_='my-class')` instead of `E.div(class='my-class')`.","cause":"Python reserved keywords like 'class' cannot be directly used as HTML attribute names; they need to be escaped.","error":"AttributeError: 'Builder' object has no attribute 'class'"},{"fix":"Add `from html5tagger import E` at the beginning of your Python file to import the builder object.","cause":"The 'E' object, which is the main entry point for creating HTML snippets, was not imported from the html5tagger library.","error":"NameError: name 'E' is not defined"},{"fix":"Install the library using pip: `pip install html5tagger`","cause":"The 'html5tagger' library is not installed in your Python environment.","error":"ModuleNotFoundError: No module named 'html5tagger'"},{"fix":"Ensure you are correctly chaining calls for content or attributes. For example, `E.p('Some text')` for content, or `E.img(src='image.jpg')` for attributes. If no content is needed and you want to close an empty element for subsequent content to *not* go inside it, use `E.tag(None)`.","cause":"This error occurs if you try to call a method on a Builder object without providing content, or if you attempt to use an attribute as a method when it's meant to be an attribute setter.","error":"TypeError: 'Builder' object is not callable"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"2.0.0","cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/sanic-org/html5tagger","docs":null,"changelog":null,"pypi":"https://pypi.org/project/html5tagger/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["web-framework","serialization"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-28","next_check":"2026-07-28","install_tag":null}}