{"id":27098430,"url":"https://github.com/shushtain/pyghtml","last_synced_at":"2025-04-06T11:36:52.544Z","repository":{"id":278400216,"uuid":"935441918","full_name":"shushtain/pyghtml","owner":"shushtain","description":"Build static HTML pages with Python.","archived":false,"fork":false,"pushed_at":"2025-03-27T17:17:26.000Z","size":441,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-27T18:24:48.941Z","etag":null,"topics":["foss","html","libraries","library","python","python-library","static-site-generator"],"latest_commit_sha":null,"homepage":"","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/shushtain.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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":"2025-02-19T13:01:18.000Z","updated_at":"2025-03-27T17:12:20.000Z","dependencies_parsed_at":"2025-03-21T15:06:11.964Z","dependency_job_id":null,"html_url":"https://github.com/shushtain/pyghtml","commit_stats":null,"previous_names":["shushtain/pyghtml"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shushtain%2Fpyghtml","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shushtain%2Fpyghtml/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shushtain%2Fpyghtml/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shushtain%2Fpyghtml/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shushtain","download_url":"https://codeload.github.com/shushtain/pyghtml/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247478233,"owners_count":20945262,"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":["foss","html","libraries","library","python","python-library","static-site-generator"],"created_at":"2025-04-06T11:36:52.052Z","updated_at":"2025-04-06T11:36:52.533Z","avatar_url":"https://github.com/shushtain.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pyghtml\n\nPython-Generatable HTML\n\n\u003e ⚠️ **In per-issue development**  \n\u003e 🦐 Any help or critique is encouraged.\n\n## Idea\n\nThis library was born when I needed to convert English lesson plans from JSON to a static website. I didn't want to learn how to set up a server just to compile some pages. And I don't know PHP. So this library consists of HTML tags as Python classes, with attributes as class properties.\n\n\u003e 💅 It's pie-tea-em-el, actually.\n\n## Features\n\n### Attribute types and defaults\n\nBoolean Python values behave according to the logic of boolean HTML attributes. `autofocus` is turned off by default, so `autofocus=False` doesn't lead to redundancies. The same goes for `autocorrect=\"on\"`, which is the default value.\n\n```python\nimport pyghtml as html\n\nb = html.Button() + \"Pyghtml\"\n\nb.title = \"Home\"\nb.disabled = True\nb.autofocus = False   # default\nb.autocorrect = \"on\"  # default\n\nprint(b)\n```\n\nproduces:\n\n```html\n\u003cbutton title=\"Home\" disabled\u003ePyghtml\u003c/button\u003e\n```\n\n### Simple container logic\n\n- Each container tag is a `MutableSequence` storing children in the `inner_html`\n- `.append()` is the same as `+= item`; `.extend()` is the same as `+= [items]`\n- You can use `with` to automatically append elements, so you don't forget\n\n```python\nimport pyghtml as html\n\nwith html.Div() as div:\n    html.Img(src=\"image.jpg\")\n    p = html.P(inner_html=\"Hello\")\n\np.class_ = \"greeting\"\np += \" World!\"\n\nprint(div)\n```\n\nproduces:\n\n```html\n\u003cdiv\u003e\n    \u003cimg src=\"image.jpg\" /\u003e\n    \u003cp class=\"greeting\"\u003eHello World!\u003c/p\u003e\n\u003c/div\u003e\n```\n\n\u003e `with` is safe to use while multi-threading html generation.  \n\u003e The contexts are stored in `threading.local()`.\n\n### Utilities\n\n#### Class methods\n\n- `Div().copy()` returns a shallow copy of the element\n- `Div().tag()` returns `div`\n- `Div(id=\"main\", hidden=True).attrs_to_str()` returns `id=\"main\" hidden`\n\n#### Functions\n\n- `contains()` checks if an item/element is in a container\n  - `deep=False` is equivalent to `item in container`\n  - `deep=True` checks recursively\n  \n- `find_by_tag()` returns a list of children with the specified tag\n  - `deep=True` searches recursively\n\n- `find_by_attr()` returns a list of children that support the attribute\n  - optional `value` also matches the attribute's value\n  - `deep=True` searches recursively\n\n- `sub()` substitutes children within a container\n  - `count` limits the number of replacements\n  - `deep=True` replaces recursively\n\n## Installation\n\nRun:\n\n```bash\npip install pyghtml\n```\n\nImport:\n\n```python\nimport pyghtml as html\n```\n\n## Additional notes\n\n- Self-closing tags are self-closing (`\u003cbr /\u003e`).\n\n- `\u003c!DOCTYPE html\u003e` is `Doctype()` and `\u003c!-- --\u003e` is `CommentHtml()`.\n\n- HTML attributes that match Python reserved words are suffixed with `_` (`class` is `class_`).\n\n- If the attribute's default value is `None`, that usually means there is no clear default value for it in the HTML spec (like the values controlled by the client-side agents when omitted). Attributes like `alt` default to `None` because an omitted `alt` is not the same as `alt=\"\"` from the accessibility standpoint.\n\n- `data-*`, `aria-*`, event (`onclick`, etc), and custom/missing attributes should be given as dictionaries through `data_attrs`, `aria_attrs`, `event_attrs`, `custom_attrs`. For example: `data_attrs = {\"data-custom-name\": \"custom value\"}`.\n\n- Abbreviations are broken: `Html()`, `Wbr()`. This may be debatable, but I thought that classes like `HttpEquiv()` and `AriaAttrs()` reflect `http-equiv` and `aria-*` much more clearly than `HTTPEquiv()` and `ARIAAttrs()`. Also, it's hard to keep in mind whether `bdi`, `bdo`, `src`, `ul`, `li`, `dt`, `dfn` count as abbreviations.\n\n- There are class names like `I()` for `\u003ci\u003e\u003c/i\u003e`, so please use a font that differentiates between `Il1`. I use JetBrains Mono.\n\n## Future improvements\n\n- [x] Add attribute docstrings\n- [x] Add tag docstrings\n- [ ] Add attribute validation\n- [ ] Add tag validation\n\n## Sources\n\n- [HTML Spec](https://developer.mozilla.org/en-US/docs/Web/HTML)\n- [MDN Web Docs](https://html.spec.whatwg.org/)\n- [W3Schools](https://www.w3schools.com/tags/default.asp)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshushtain%2Fpyghtml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshushtain%2Fpyghtml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshushtain%2Fpyghtml/lists"}