3

If I want to create fields that get set to a custom content table rather than craft_content how would I do that?

3

Okie doke. After bashing my head against the wall THIS is how you create your very own super deluxe content table. Allow me to explain...

In your element class you will need to specify the following:

  public function hasContent()
  {
    return true; // You definitely will need this
  }

  public function hasTitles()
  {
    return true; // This is optional
  }

  public function isLocalized()
  {

    return false; // This is optional

  }

  public function getContentTableForElementsQuery(ElementCriteriaModel $criteria){

    return "custom_content_table_name"; // You definitely will need this

  }

  public function getFieldsForElementsQuery(ElementCriteriaModel $criteria)
  {

      // NOTE: I do not have any custom fields set to this table. If you have custom fields you should return them here so that they are included in the criteria query. If you also do not have custom fields just do what I'm doing here and return an empty array. 

       $fields = array();

       return $fields;

  }

In your element's model class you'll need to do the following:

  public function getContentTable(){

    return "custom_content_table_name"; // you will need this

  }

  public function getFieldContext()
  {

    return 'custom_content_table_name'; // I have NO idea what this is and the Craft documentation is not clear about it.

  }

Finally, your record for the content table will have to make the following columns:

  1. elementId
  2. title
  3. locale

That's basically it. If you run into any errors make sure you're not including extra non-existent fields in the criteria queries when querying content. Check the Craft logs to see exactly what's happening if you encounter any problems.

1

I've created a custom Element Type, and used the getContentTableForElementsQuery() to set where the element's content is stored.

For instance, the default BaseElement class defines:

public function getContentTableForElementsQuery(ElementCriteriaModel $criteria)
{
    return 'content'; // table craft_content
}

Here, you would simply provide the table you want to store your data in, rather than content.

Then, when going to save the field(s), you need to set the contentTable like so:

$originalContentTable = craft()->content->contentTable;

craft()->content->contentTable = 'mycontenttable';

// Save your fields

craft()->content->contentTable = $originalContentTable;

FYI - I learnt this from looking at how SproutForms works, which uses its own content table for fields.

  • Ehh. I've done this so, considering your answer, I'm either missing something or not explaining myself well enough. What I'm after is the ability to define where Craft fields go. Right now If I create a new plain text field a column gets created in craft_content. I would prefer to be able to choose where that column gets created. Is that possible? – Matt V May 7 '15 at 13:44
  • Sure, I've added some extra code to the above answer – crawf May 7 '15 at 13:50
  • As per your updated answer, I assume I'll need to make custom fields to get them to save where I want? – Matt V May 7 '15 at 13:58
  • You don't have to - you just put whatever your saving (your element) between those contentTable assignments. Haven't tried, but craft()->elements->saveElement($element) should do – crawf May 7 '15 at 14:18
  • Ok. So let's take some steps back because I'm clearly doing something wrong. I have getContentTableForElementsQuery returning the name of my custom table and I have hasContent set to true. In my model I have getContentTable returning the same table name as getContentTableForElementsQuery. Now in my CP when I go to my page for inputting data for my element I immediately see "An unknown error has occurred" – Matt V May 7 '15 at 17:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.