{"id":13594266,"url":"https://github.com/crufter/haquery","last_synced_at":"2025-04-05T06:09:19.425Z","repository":{"id":7616850,"uuid":"8975623","full_name":"crufter/haquery","owner":"crufter","description":"jQuery for Haskell","archived":false,"fork":false,"pushed_at":"2025-01-27T14:17:19.000Z","size":210,"stargazers_count":65,"open_issues_count":3,"forks_count":7,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-29T05:09:29.473Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/crufter.png","metadata":{"files":{"readme":"README.md","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":"2013-03-23T19:13:26.000Z","updated_at":"2025-01-27T14:17:24.000Z","dependencies_parsed_at":"2022-09-05T02:31:48.478Z","dependency_job_id":"80ad3999-eac9-490d-bba4-5237bbb06ae5","html_url":"https://github.com/crufter/haquery","commit_stats":{"total_commits":18,"total_committers":3,"mean_commits":6.0,"dds":0.4444444444444444,"last_synced_commit":"e09d80194b3aa17426f922908949403da7555da0"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crufter%2Fhaquery","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crufter%2Fhaquery/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crufter%2Fhaquery/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crufter%2Fhaquery/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/crufter","download_url":"https://codeload.github.com/crufter/haquery/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247294541,"owners_count":20915340,"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":[],"created_at":"2024-08-01T16:01:31.053Z","updated_at":"2025-04-05T06:09:19.407Z","avatar_url":"https://github.com/crufter.png","language":"Haskell","funding_links":[],"categories":["Haskell","Web"],"sub_categories":["Frontend and UI Components"],"readme":"Haquery\n=====\n[![build](https://github.com/lambdamechanic/haquery/actions/workflows/haskell.yml/badge.svg)](https://github.com/lambdamechanic/haquery/actions/workflows/haskell.yml)\n\n**jQuery selector API for Haskell**, a CSS selector based HTML manipulation and template engine.\n\n### Why?\n\nThe advantage is that most web developers already know CSS selectors, and if you are one of them,  \nyou don't have to learn a new template language just to render data as HTML pages.\n\nAlso, you can use any data structure, any functions with Haquery.  \n\nNo more \"if there is an if construct why there is no else\" moment like with many other template\nlanguages.\n\n### Installation\n\nUsing `cabal install haquery` or `stack install haquery`.\n\n### Selectors\n\n    Example                     Name                                    URL\n    *                           - All selector                          http://api.jquery.com/all-selector/\n    #id                         - Id selector                           http://api.jquery.com/id-selector/\n    .class                      - Class selector                        http://api.jquery.com/class-selector/\n    selector1 selector2         - Descendant selector                   http://api.jquery.com/descendant-selector/\n    type                        - Element selector                      http://api.jquery.com/element-selector/\n    selector1 \u003e selector2       - Child selector                        http://api.jquery.com/child-selector/\n    [attrName]                  - Has attribute selector                http://api.jquery.com/has-attribute-selector/\n    [attrName=\"val\"]            - Attribute equals selector             http://api.jquery.com/attribute-equals-selector/\n    [attrName*=\"val\"]           - Attribute contains selector           http://api.jquery.com/attribute-contains-selector/\n    [attrName^=\"val\"]           - Attribute starts with selector        http://api.jquery.com/attribute-starts-with-selector/\n    [attrName$=\"val\"]           - Attribute ends with selector          http://api.jquery.com/attribute-ends-with-selector/\n    [attrName~=\"val\"]           - Attribute contains word selector      http://api.jquery.com/attribute-contains-word-selector/\n    [attrName!=\"val\"]           - Attribute not equals selector         http://api.jquery.com/attribute-not-equal-selector/\n    selector1, selector2        - Multiple selectors selector           http://api.jquery.com/multiple-selector/\n    prev + next                 - Next adjacent selector                http://api.jquery.com/next-adjacent-selector/\n    prev ~ siblings             - Next siblings selector                http://api.jquery.com/next-siblings-selector/\n    :not(selector)              - :not() selector                       http://api.jquery.com/not-selector/\n    :has(selector)              - :has() selector                       http://api.jquery.com/has-selector/\n    :eq(3)                      - :eq() selector                        http://api.jquery.com/eq-selector/\n    :lt(3)                      - :lt() selector                        http://api.jquery.com/lt-selector/\n    :gt(3)                      - :gt() selector                        http://api.jquery.com/gt-selector/\n    :even                       - :even selector                        http://api.jquery.com/even-selector/\n    :odd                        - :odd selector                         http://api.jquery.com/odd-selector/\n    :first                      - :first selector                       http://api.jquery.com/first-selector/\n    :last                       - :last selector                        http://api.jquery.com/last-selector/\n    :first-child                - :first-child selector                 http://api.jquery.com/first-child-selector/\n    :last-child                 - :last-child selector                  http://api.jquery.com/last-child-selector/\n    :nth-child(3)               - :nth-child() selector                 http://api.jquery.com/nth-child-selector/\n    :nth-last-child(3)          - :nth-last-child() selector            http://api.jquery.com/nth-last-child-selector/\n    :empty                      - :empty selector                       http://api.jquery.com/empty-selector/\n    :parent                     - :parent selector                      http://api.jquery.com/parent-selector/\n\n### Examples\n\nWe can write the HTML data structures in Haskell, or we can parse them from HTML.    \nWe will focus on the former.\n\nAn HTML tag is nothing else but a tagname, some key value pairs and children:\n\n```haskell\n--  Tagname     Attribute 1         Attribute 2         Children\n    body        [at \"id\" \"x\",      at \"class\" \"y\"]    [\n        div' [] [], -- Child 1 with no attributes, no children\n        div' [] []  -- Child 2 also with no attributes and no children\n    ]\n```\n\n'at' means create attribute. Note that the names are not final. Any suggestion is welcome.  \ndiv became div', and head is called head' to avoid clash with Prelude.\n\nIf you want, you can use the general tag form too:\n\n```haskell\n    tag \"body\" [at \"id\" \"x\", at \"class\" \"y\"] [\n        tag \"div\" [] [],\n        tag \"div\" [] []\n    ]\n```\n\nNow let's look at some complete examples.  \n\n```haskell\n{-# LANGUAGE OverloadedStrings #-}\nimport Haquery\n\nexample :: Tag\nexample = html [\n        head' [] [],\n        body [] [\n            div' [at \"id\" \"main\", at \"class\" \"c1\"] [\n                div' [at \"id\" \"sub1\"] [],\n                div' [at \"id\" \"sub2\"] []\n            ]\n        ]\n    ]\n```\n\nThe above example is identical to the following HTML snippet:\n\n```html\n\u003chtml\u003e\n    \u003chead\u003e\u003c/head\u003e\n    \u003cbody\u003e\n        \u003cdiv id=\"main\" class=\"c1\"\u003e\n            \u003cdiv id=\"sub1\"\u003e\u003c/div\u003e\n            \u003cdiv id=\"sub2\"\u003e\u003c/div\u003e\n        \u003c/div\u003e\n    \u003c/body\u003e\n\u003c/html\u003e\n```\n\nNow we can start querying and manipulating our 'example'.\n\nLet's do a selection.\n\n```haskell\n\u003e select \"#main\" example\n[\u003cdiv id=\"main\" class=\"c1\"\u003e\n    \u003cdiv id=\"sub1\"\u003e\u003c/div\u003e\n    \u003cdiv id=\"sub2\"\u003e\u003c/div\u003e\n\u003c/div\u003e]\n```\n\nA selection returns all tags matching the given selector.  \nObviously, we can't modify these values due to Haskell's purity.\nIf we want to modify tags matching a selector, we can use the alter function.\n\n```haskell\n\u003e :t alter\nalter :: T.Text -\u003e Tag -\u003e (Tag -\u003e Tag) -\u003e Tag\n```\n\nAs we can see, the alter functions needs a selector, a tag to search in, and a function which transforms\nthe matching tags. Let's add a class to every div! We can do this with the addClass method.\n\n```haskell\n\u003e :t addClass\naddClass :: T.Text -\u003e Tag -\u003e Tag\n```\n\n```haskell\n\u003e alter \"div\" example (addClass \"hello-class\")\n\u003chtml\u003e\n    \u003chead\u003e\u003c/head\u003e\n    \u003cbody\u003e\n        \u003cdiv id=\"main\" class=\"c1 hello-class\"\u003e\n            \u003cdiv id=\"sub1\" class=\"hello-class\"\u003e\u003c/div\u003e\n            \u003cdiv id=\"sub2\" class=\"hello-class\"\u003e\u003c/div\u003e\n        \u003c/div\u003e\n    \u003c/body\u003e\n\u003c/html\u003e\n```\n\nFor parsing HTML into `Tag`s, use `parseHtml`:\n\n```haskell\nparseHtml :: T.Text -\u003e [Tag]\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrufter%2Fhaquery","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcrufter%2Fhaquery","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrufter%2Fhaquery/lists"}