(See my 'solution' at bottom of this question.)
Disclaimer: I'm new to EE; I inherited a system and am looking to be able to extract entries.
I'm trying to create a template to extract entries in JSON format. This is what I've got so far:
<?php
$entries = array();
{exp:channel:entries channel="blog" limit="1" dynamic="no"}
$entries[] = array('title' => '{title}', 'author' => '{author}', 'body'=>'{exp:allow_eecode embed="y"}{blog_body}{/exp:allow_eecode}');
{/exp:channel:entries}
header('Content-type: application/json');
echo json_encode($entries);
exit;
?>
I've enabled PHP, set the PHP parsing stage to Output. This mostly works, except one field doesn't render correctly; it has embed
EE tags in the field data on output:
[
{
"title": "9 Gorgeous Wedding Color Palettes for Autumn",
"author": "WeddingExpert",
"body": "{embed=\"photos\/_embedded\" entry_id=\"50808\" context_channel=\"blog\" }\n<p>\n\tIn keeping with our ..."
}
]
If I do not use the allow_eecode
tag, then the output shows the html entity codes for braces, etc. If I turn off PHP, I can get the output for the problematic field to render 'correctly', but then I get the PHP code rendered as HTML - ie it doesn't render the JSON I need, obviously.
Is there a reason why PHP is preventing this from working? Is there another approach I should take?
Note: This is on an old version of EE: v2.1.3. I don't have the luxury of upgrading; I'm basically retiring this system once the data is extracted.
EDIT: I made two changes: I removed the PHP exit()
call and changed the Template Type to 'Javascript' from 'Web Page'. Here's the template now:
<?php
$entries = array();
{exp:channel:entries channel="blog" limit="1" dynamic="no"}
$entries[] = array('title' => '{title}', 'author' => '{author}', 'body'=>'{exp:allow_eecode embed="y"}{blog_body}{/exp:allow_eecode}');
{/exp:channel:entries}
header('Content-type: application/json');
echo json_encode($entries);
?>
and here is the output, which is slightly different (no embed
tag visible, but it also didn't render the embed
tag!):
[
{
"title": "9 Gorgeous Wedding Color Palettes for Autumn",
"author": "Azure",
"body": "\n<p>\n\tIn keeping with our ..."
}
]
Of course, now I'm even more confused.
Solution: As pointed out by Derek Hogue, there is no JSON solution due to the order of the EE rendering pipeline.
That having been said, as I need to migrate the data out and in my case it doesn't need to be in JSON format, I can simply change my template to have a consistent layout per entry and then I can parse it using any language I desire. For example with this template, I can get Entry data in a parseable format:
{exp:channel:entries channel="blog" limit="5" dynamic="no"}
ONEWEDMIGRATION-TITLE:{title}
ONEWEDMIGRATION-AUTHOR:{author}
ONEWEDMIGRATION-BODY:{exp:allow_eecode embed="y"}{blog_body}{/exp:allow_eecode}
<======================>
{/exp:channel:entries}
I can split the data on <======================>
to get a list of Entries, and then parse each Entry based on the tokens at the beginning of lines.
This is simplistic and would need to be further developed for multiline fields, etc. But the idea is sound.