Been looking at porting a site from EE to Craft.

We have a custom module that accepts a POST and then stores that data in fields in a particular channel. The mappings are stored in extension settings so there are no hardcoded field IDs in the module code.

In Craft, how would we go about that? I can see that we'd need to have a controller method that would be publicly accessibly but am unsure if we can easily use Entries or if we need a custom table with fields, field layout etc.

The use case is a job board. Jobs are just entries in that they have a job title, body, summary, salary range, blah blah blah, and CMS users should be able to create jobs in Craft, so just a channel looks fine. The only addition is that a third party needs to post data to the channel to create jobs too, hence the need for the plugin.

Can you please advise the best approach here? The bit I'm stuck on is either creating mappings in the plugin settings that link the posted data with fields created in the channel, or on showing a template where the CMS user can create and edit jobs using the standard Craft field layout UI.

Hope that all makes sense!



I'm not sure if this is the 'best' approach, but you can definitely accomplish this without creating your own tables, unless you have some other specific need. In your plugin defineSettings method you could either define individual fields (if the entry fields are predetermined) or a table field (if both the post data and entry fields should be configurable) to store field mappings. In your public controller method you can then map the post data to your entry's fields via the settings that you defined, perform other security/data checks, etc. and save the entry.

In the plugin's controller:

public function actionSaveJob()
    // get 'post to field' mappings from plugin settings
    $pluginSettings = craft()->plugins->getPlugin('JobPostPlugin')->getSettings();
    $titlePostVar   = $pluginSettings->titlePostVar;
    $bodyPostVar    = $pluginSettings->bodyPostVar;
    $summaryPostVar = $pluginSettings->summaryPostVar;

    // retrieve post data
    $title   = craft()->request->getPost($titlePostVar);
    $body     = craft()->request->getPost($bodyPostVar);
    $summary = craft()->request->getPost($summaryPostVar);

    // create a new entry
    $entry = new EntryModel(); 
    $entry->sectionId  = 2; 
    $entry->typeId     = 2; 
    $entry->authorId   = 1; 
    $entry->enabled    = true;

    // set entry content
        'title'     => $title,     
        'body'      => $body,
        'summary'   => $summary, 

    // save the entry
    $success = craft()->entries->saveEntry($entry);

Completely untested, but should be more or less correct. If anyone sees an error please comment or feel free to edit.

You would also want to add conditions to ensure that the post data exists and that it is formatted correctly, and that whatever security conditions you've established are met, and perhaps record/return success and or errors.

For simplicity I have shown this all happening in a controller action, however, I think the recommended approach would be to separate this between a controller and a corresponding service, so that the controller is never actually modifying the DB.

  • Thanks. How can I grab a list of fields in a select menu so the user can map each field in the settings? – Russ Back Oct 31 '14 at 20:53
  • I was thinking that you would have them enter them manually, but you're right — a drop-down would be nicer. You can access the fields through the fieldLayoutModel. Although I'm not sure how to get that from a section id directly. I do know how to do this from an entry {{ entry.getFieldLayout().getFields() }}. Maybe that will get you started. I'll play around later, when I have time to check out the class reference. You might check out a plugin called 'inspecter'. Its great for wandering around the object tree, and printing out available variables, methods, properties, etc. – Douglas McDonald Nov 1 '14 at 0:25
  • Thanks - I've found a way of doing it here craftcms.stackexchange.com/questions/4491/…. Not sure if that's the best way though. Seems straightforward enough – Russ Back Nov 1 '14 at 19:18
  • That will definitely work. I was just trying to narrow the field choices down to the entry type in question. All fields might be a big drop-down, with possibly duplicate field names, etc (unless you display field handles). – Douglas McDonald Nov 1 '14 at 23:35
  • May not be the most direct, but this seems to work: {% for field in craft.entries.type('jobs').first().getFieldLayout().getFields() %}{{ field.getField().name }}{% endfor %} – Douglas McDonald Nov 1 '14 at 23:52

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.