Q:

How to store json data in a custom fieldtype so that it's data can be referenced as attribute values?

I would like to store a json object in a custom fieldtype, and be able to traverse the object's attributes using twig dot syntax in my template. I am currently storing the raw json object as a string, but I'm not sure what I need to do to be able to reference the stored string as an object.
Here is a shortened example of the raw json string that is being stored:
"Stripe_Customer JSON: {
    "id": "cus_4v68MrZu3za8XT",
    "object": "customer",
    "cards": { "object": "list", "total_count": 0, "has_more": false, "url": "/v1/customers/cus_4v68MrZu3za8XT/cards", "data": [ ] },
    "subscriptions": { "object": "list", "total_count": 0, "has_more": false, "url": "/v1/customers/cus_4v68MrZu3za8XT/subscriptions", "data": [ ] },
    "etc": "etcetcetc"
}"

In my template I would like to be able to reference the objects properties in some way (i.e. {{ fieldHandle.id }}) for display only; and on the back-end within a service, I would like to set object properties before saving back to the DB (i.e fieldhandle->id = value).
I am not sure whether defineContentAttribute should return AttributeType String or Mixed in this case.
public function defineContentAttribute()
{
    return AttributeType::String;
    //return AttributeType::Mixed;
}

And if it should be a string, how would one define the column type as "Text" vs the default VARCHAR(255)?
Update: I see that there is a similar question regarding custom fieldtype with multiple values, however, in this case, the end-user will not be manipulating the data directly in any way — they will be filling in dummy fields that will be send to a third party service via javascript/ajax, a result object returned, and then forwarded (again via ajax) to a back-end service method to be processed and saved to the DB.

A:

You already mentioned the related answer in custom fieldtype with multiple values, and it actually is perfect for your usecase.
It doesn't really matter how you transport the data over to Craft, because if the content is set to AttributeType::Mixed, then Craft will JSON encode/decode it when requested.
So, to save your data, send over an array, like so:
$stripeCustomer = [
    "id" => "cus_4v68MrZu3za8XT",
    "object" => "customer",
    "etc" => "etcetcetc"
    ];

// Transport $stripeCustomer to Craft with Ajax

In the context of Javascript, you'd send over the serialized form data.

A:

Completely untested, but a possibility would be to define your content attribute like so:
return array(AttributeType::Mixed, 'model' => 'MyPluginContentModel');

MyPluginContentModel would have every possible value that you would want to expose to your template ('id', 'obj', 'etc') defined as an attribute.
When Craft pulls the JSON from the database, it should decode it and populate your model with any matching attributes it finds.
That gets returned to your template and you can access it via {{ value.id }}.

A:

With a highly complex hierarchical object with many layers of sub-objects, etc., I found that it was much easier in the end to just store the raw JSON in the database in a text-field, and decode it manually before passing it to the template to allow full access to the object hierarchy using dot or array syntax.
In the plugin's fieldtype class definition, define the column type as String with no text limit (using the additional column declaration):
public function defineContentAttribute()
{
    return array(AttributeType::String, 'column' => ColumnType::Text);
}

In the fieldType template file the string can then be decoded as a json object manually to make it available to the template using JsonHelper::decode():
public function getInputHtml($name, $value)
{
    $jsonObj = JsonHelper::decode($value);
    return craft()->templates->render('myPlugin/fieldtypes/Myfield/input', array(
        'name'          => $name,
        'value'         => $value,
        'jsonObj'       => $jsonObj
    ));
}

And in the template, (assuming the json was properly formatted) the full json object can now be traversed using dot syntax:
{# access first level attribute #}
<p>{{ jsonObj.id }}</p>
{# access deeper object array level attribute #}
<p>{{ jsonObj.objArray.data[0].id }}</p>

Note: In php, for some unexplained reason, JsonHelper::decode($jsonStr) doesn't seem to allow access to the attributes, so instead the php equivalent php_decode($jsonStr) can be used:
$jsonObj = json_decode($entry->jsonStr);
$Id = $jsonObj->id;

