Skip navigation.
Home
That which cannot be rendered in binary is by definition a delusion
 

The Drupal Crud Checklist

If you are doing a custom module, there is a LOT to do just to add a content type (presuming you are not using CCK). Here's a checklist for creating a custom type. note terms in bold are generic functional placeholders for custom namespace tokens.

While there may be times when this is not a requirement, its assumed throughout that you have an nid and a vid field in your custom table. It's useful to use vid as the primary key.

This may seem like a load, but keep in mind these snippets are custom tooled to insert unique code within a larger system and as such, what might be whole files or classes in other systems are being replaced by relatively tiny functional blocks.

Create a schema

In the modue.install file create an install hook to load the content type

function module_install() {
    drupal_install_schema('content_type');
}

... and the uninstall hook.

function module_uninstall() {
    // Drop database tables.
    drupal_uninstall_schema('content_type');
}

 

Create a hook to make your schema visible. note: I load mine from a YAML file so yours should look more like the stock system in the Drupal docs. note -- for drupal_get_path(), the FIRST 'module' is a LITERAL -- the word 'module' -- not the name of your module. the second module IS the name of your module.

function module_schema() {
    $path =  drupal_get_path('module', 'module') . '/schema.yml';
    $schema = Drupal_YAML::load($path);
    return $schema;
}

The node schema file contains data on your desired table(s)' structure as in:

css_lead_lead:
    description: A business lead
    primary: vid
    fields:
      vid:
        type: int
        default: 0
        not null: true
        description: primary key for this table, foreign key for node      
     lead_uid:
        type: int
        default: 0
        not null: true
        description: the lead's user id if they are a user -- rarely true but here it is.
      account_vid:
        type: int
        default: 0
        not null: true
        description: the account FK that the lead belongs to. 
      first_name:
        type: string
        length: 40
        default: ''
        not null: true
        description: a contact's first name. 
      last_name:
        type: string
        length: 40
        default: ''
        not null: true
        description: a contact's last name.

... and so on. Multiple tables can be put in a single YAML file. Schema tables don't have to be nodes; non node tables should have their own id of type serial.

Create an info hook

the module_node_info() hook puts your content type in the standard content creation api.

function module_node_info() {
    return array(
            'content_type' => array(
                    'name' => t('Content Title'),
                    'module' => 'module',
                    'description' => t('A content type'),
                    'has_title' => TRUE,
                    'title_label' => t('Name'),
                    'has_body' => TRUE,
                    'body_label' => t('Description')
            ),
    );
}

Create a form for the content type. Note that the specifics for the title and body fields will transport from module_node_info() above.

function content_type_form(&$node){
    $form = array(); 
    $weight = -10;
    $type = node_get_types('type', $node);

    if ($type->has_title) {

        $form['title'] = array(
                '#type' => 'textfield',
                '#title' => check_plain($type->title_label),
                '#required' => TRUE,
                '#default_value' => $node->title,
                '#weight' => $weight++
        );
    }

    if ($type->has_body) {

        $bf = node_body_field(
                $node,
                $type->body_label,
                $type->min_word_count);
        $bf['#weight'] = $weight++;
        $bf['body']['#rows'] = 5;
        $bf['teaser_js']['#rows'] = 2;
        $form['body_field'] = $bf;

    };
/**
 * add any other custom fields here
 */
    return $form;
}

Add crud hooks for insert

You'll need to handle the insertion and updating of custom fields in a specific pair of handlers. note that _content_type_set_defaults (below) sanitizes the node, ensuring that all neeed properties have been set.

function content_type_insert($node) {

    _content_type_set_defaults(&$node);

    $query = <<<QUERY
INSERT INTO {custom_table} (
    `custom_field_1` , 
...
    `custom_field_N`
)
VALUES (
    '%s',
...
    '%d'
);
QUERY;

    db_query($query,
            $node->custom_field_1 ,
...
            $node->custom_field_N
    );
}

Add an update hook

Similar to the above, only for revising existing records.

function content_type_update($node) {

    if ($node->revision) {
        return content_type_insert($node);
    }

    _content_type_set_defaults(&$node);

    $query = <<<QUERY
UPDATE {custom_table}
 SET
    `field_1` = '%s'
...
    `field_n` = '%s'
 WHERE
    {custom_table}.`vid` = %d;
QUERY;
    db_query($query,
            $node->custom_field_1,
            $node->empathy,
            $node->vid
    );
}
function _content_type_defaults(&$node){
    if (!property_exists($node, 'custom_field_1')){
         $node->custom_field_1 = 'default';
    }
...
}

Add a delete hook

the delete button will delete the records in Drupal's node tables but you'll need to delete your custom record on your own. If there are subrecords that relate to this record they can be addressed here too. Note - by deleting the node ID related rows you delete ALL revisions.

function content_type_delete($node) {

    $query = <<<QUERY
DELETE FROM {custom_table} WHERE nid = %d
QUERY;

    db_query($query, $node->nid);
} 

Add a load hook

This will pull all your custom tables' fields into a node stdClass object. Note: the expected return is a stdClass.

function content_type_load($node){
    $query = <<<QUERY
SELECT
     custom_field_1,
...
     custom_field_N
FROM
    {custom_table}
WHERE
    vid = %d
QUERY;
    $result = db_query($query, $node->vid);
    $out = db_fetch_object($result);
    return $out;
}

 Enable node theming with a view hook

Your view field should bind in any custom theming for your object. NOTE: if you pass the teaser flag to your theme, you can use the same theme file for the teaser and full view of the node.

function content_type_view($node, $teaser = FALSE, $page) {
    $node = node_prepare($node, $teaser);
   
    $field_1 = $node->field_1;

...    $field_n = $node->field_N;

    $node->content['content_type_info'] = array(
            '#value' => theme('content_type_info',
            $teaser,
            $field_1 ,
...
            $field_n
                    ),
            '#weight' => 1
    );

    return $node;
}

Add a bridge to the theme, note that the key, content_type_info, should be the same for both the view and the theme, and should match the file 'content_type_info.tpl.php' in your module root.

function module_theme() {

    return array(
            'content_type_info' => array(
                    'template' => 'content_type_info',
                    'arguments' => array(
                            'teaser' => FALSE,
                            'field_1' => '',
                            'field_N' =>''
                    )
            )
    );
}

this should be executed in a template file called content_type_info.tpl.php

<div class="content_type_info">

<? if (!$teaser): ?>
<dl>
<dt>Field One</dt>
<dd><?= $field_1 ?></dd>
...
</dl>

<? endif; ?>
</div>

Note that the HTML style here used here is just an example -- you can use any HTML arrangement you want, and you're not obligated to expose all the variables.

Post new comment

  • Lines and paragraphs break automatically.
  • Allowed HTML tags: <a> <p> <span><small> <div> <h1> <h2> <h3> <h4> <h5> <h6> <img> <map> <area> <hr> <br> <br /> <ul> <ol> <li> <dl> <dt> <dd> <table> <tr> <td> <em> <b> <u> <i> <strong> <font> <del> <ins> <sub> <sup> <quote> <blockquote> <pre> <address> <code> <cite> <embed> <object> <param> <strike> <caption>
  • Web page addresses and e-mail addresses turn into links automatically.

More information about formatting options