{"id":15377516,"url":"https://github.com/mislav/asbestos","last_synced_at":"2025-04-15T17:11:54.392Z","repository":{"id":598936,"uuid":"234543","full_name":"mislav/asbestos","owner":"mislav","description":"Render JSON from your XML Builder templates","archived":false,"fork":false,"pushed_at":"2009-12-20T11:27:25.000Z","size":87,"stargazers_count":7,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-15T17:11:48.919Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","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/mislav.png","metadata":{"files":{"readme":"README.markdown","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}},"created_at":"2009-06-23T18:37:40.000Z","updated_at":"2020-07-29T11:23:23.000Z","dependencies_parsed_at":"2022-07-15T01:47:00.178Z","dependency_job_id":null,"html_url":"https://github.com/mislav/asbestos","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mislav%2Fasbestos","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mislav%2Fasbestos/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mislav%2Fasbestos/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mislav%2Fasbestos/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mislav","download_url":"https://codeload.github.com/mislav/asbestos/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249116245,"owners_count":21215143,"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-10-01T14:12:05.838Z","updated_at":"2025-04-15T17:11:54.375Z","avatar_url":"https://github.com/mislav.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"Asbestos\n========\n\nTemplate handler for Rails that allows you to use\na subset of XML Builder markup to produce JSON.\n\nTake, for instance, a common \"show.xml.builder\" template:\n\n    xml.instruct!\n    xml.category(:private =\u003e false) do\n      xml.name @category.name\n      xml.parent do\n        xml.id @category.parent_id\n        xml.name @category.parent.name\n      end\n    end\n\nIf you copied that to \"show.json.asbestos\", you would get:\n    \n    {\"category\": {\n      \"private\": \"false\",\n      \"name\": \"Science \u0026 Technology\",\n      \"parent\": {\n        \"id\": 1,\n        \"name\": \"Religion\"\n      }\n    }}\n\nBut of course, you don't want to duplicate your builder template\nin another file, so we'll handle this in the controller:\n\n    def show\n      respond_to do |wants|\n        wants.xml\n        wants.json {\n          # takes the \"show.xml.builder\" template and renders it to JSON\n          render_json_from_xml\n        }\n      end\n    end\n\nWith this method there's no need for a special template file for JSON.\nAsbestos is designed to use existing XML Builder templates.\n\nHow does it work?\n-----------------\n\nThe `xml` variable in your normal builder templates is the XML Builder object.\nWhen you call methods on this object, it turns that into XML nodes and appends\neverything to a string, which is later returned as the result of rendering.\n\nThis plugin provides Asbestos::Builder, which tries to mimic the behavior\nof the XML Builder while saving all the data to a big nested ruby hash.\nIn the end, `to_json` is called on it.\n\nAggregates and ignores (important!)\n-----------------------------------\n\nProblems start when you have Builder templates that render *collections*,\nlike in index actions:\n\n    xml.instruct!\n    for category in @categories\n      xml.category do\n        # ...\n      end\n    end\n\nThere is a ruby loop in there, so if there are multiple categories the resulting\nJSON would have just one. This is because the same \"category\" field in the JSON\nhash would keep getting re-written by the next iteration. Asbestos::Builder is,\nunfortunately, not aware about any loops in your template code.\n\nThe solution is to indicate explicitly which keys you want aggregated:\n\n    render_json_from_xml :aggregate =\u003e ['category']\n\nNow, what would previously create a \"category\" key will get aggregated\nunder a \"categories\" array, instead:\n\n    { \"categories\": [ ... ] }\n\nSometimes, most often with root elements, you want a key ignored.\nYou can specify which occurrences to ignore:\n\n    render_json_from_xml :ignore =\u003e ['category']\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmislav%2Fasbestos","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmislav%2Fasbestos","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmislav%2Fasbestos/lists"}