I was modifying my locations json file this morning, so I thought I would weigh in. I'm using the JSON Encode add-on inside of a low_search results. Of course, the Low Search results could be switched with Channel Entries or any other tag which gets your data.
This is my full json_locations.html template:
{exp:http_header content_type="application/json"}
{"locations": [
{exp:low_search:results
channel="locations"
limit="1000"
dynamic="no"
distance:to="locations_latitude|locations_longititude"
distance:unit="mi"
require_all="category"
}
{
"id": "{entry_id}",
"url_title": "{url_title}",
"type": "{categories show_group="6" backspace="1"}{category_id}|{/categories}",
"region": "{categories show_group="7" backspace="1"}{category_id}|{/categories}",
"name": {exp:json_encode}{locations_displayed_name}{/exp:json_encode},
"address": {exp:json_encode}{locations_address_1}{/exp:json_encode},
"city": {exp:json_encode}{locations_city}{/exp:json_encode},
"state": {exp:json_encode}{locations_state}{/exp:json_encode},
"zip": {exp:json_encode}{locations_zip}{/exp:json_encode},
"phone": {exp:json_encode}{locations_primary_phone_number}{/exp:json_encode},
"geo_lat": {exp:json_encode}{locations_latitude}{/exp:json_encode},
"geo_lng": {exp:json_encode}{locations_longititude}{/exp:json_encode},
"additional_data": {exp:json_encode}{categories show_group="6"}<i class='fa fa-map-marker {category_url_title}'></i> {exp:ce_str:ing ucwords}{category_name}{/exp:ce_str:ing}<br> {/categories}{/exp:json_encode}
}{if count<absolute_results}, {/if}
{/exp:low_search:results}
]}
I'm calling this from Javascript to render map locations on a Google Map. This is the line from JS:
var location_json = "/locations/json_locations";
This is what it would look like if you used exp:channel:data:
{exp:http_header content_type="application/json"}
{"locations": [
{exp:channel:entries
channel="locations"
limit="2"
dynamic="no"
}
{
"id": "{entry_id}",
"url_title": "{url_title}",
"type": "{categories show_group="6" backspace="1"}{category_id}|{/categories}",
"region": "{categories show_group="7" backspace="1"}{category_id}|{/categories}",
"name": {exp:json_encode}{locations_displayed_name}{/exp:json_encode},
"address": {exp:json_encode}{locations_address_1}{/exp:json_encode},
"city": {exp:json_encode}{locations_city}{/exp:json_encode},
"state": {exp:json_encode}{locations_state}{/exp:json_encode},
"zip": {exp:json_encode}{locations_zip}{/exp:json_encode},
"phone": {exp:json_encode}{locations_primary_phone_number}{/exp:json_encode},
"geo_lat": {exp:json_encode}{locations_latitude}{/exp:json_encode},
"geo_lng": {exp:json_encode}{locations_longititude}{/exp:json_encode},
"additional_data": {exp:json_encode}{categories show_group="6"}<i class='fa fa-map-marker {category_url_title}'></i> {exp:ce_str:ing ucwords}{category_name}{/exp:ce_str:ing}<br> {/categories}{/exp:json_encode}
}{if count<absolute_results}, {/if}
{/exp:channel:entries}
]}
Then point your browser to http://yourwebsite.com/locations/locations_json to see the results. You should see this:
{"locations": [
{
"id": "10477",
"url_title": "my-url-1",
"type": "343",
"region": "51",
"name": "Caf\u00e9 Degas",
"address": "2020 Smith Ave",
"city": "New Orleans",
"state": "LA",
"zip": "70119",
"phone": "504-777-5635",
"geo_lat": "29.98032300",
"geo_lng": "-90.08639902",
"additional_data": "<i class='fa fa-map-marker'><\/i> My Location 1<br> "
},{
"id": "10233",
"url_title": "my-location-2",
"type": "48",
"region": "51|173|57",
"name": "My Location 2 \u2013 Bloomfield",
"address": "4500 Archer Pkwy., 1st Floor",
"city": "Metairie ",
"state": "LA",
"zip": "70004",
"phone": "504-555-8563",
"geo_lat": "30.017772",
"geo_lng": "-90.1880092",
"additional_data": "<i class='fa fa-map-marker'><\/i> My Location 2<br> "
}
]}