by Robert Douglass on March 7, 2007 // Short URL

What is the Content Construction Kit? A View from the Database.

This article describes the Content Construction Kit, version 5.x-1.4.

The Content Construction Kit (CCK) began as a natural evolution from the popular Flexinode module. The Flexinode module allowed you to define your own content types (a blog entry, a recipe, a poll, etc) with a number of custom fields. CCK also allows you to do this, but in a more powerful way.

Content types and the content.module

With Drupal 5, you can create your own content types. The default installation comes with Page and Story content types, which are included for historical reasons. You can delete these and create your own content types, or modify them to suit your needs.

CCK allows you to extend the data model of content types through the addition of fields such as a date, an image, an email address, etc. The core CCK module is the content.module. The content.module is the workhorse that handles CCK's main goal of extending content types with these new fields. Therefore, it is logical that the content.module manages its own database table for every content type you have defined. This includes the built in Page and Story types.

When you install and enable content.module, it creates tables for every content type you currently have. Here is the schema for the table it creates if your Drupal installation has a Page content type:

mysql> describe content_type_page;
+-------+------------------+------+-----+---------+-------+
| Field | Type             | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| vid   | int(10) unsigned | NO   | PRI | 0       |       |
| nid   | int(10) unsigned | NO   |     | 0       |       |
+-------+------------------+------+-----+---------+-------+

vid and nid are the bare minimum fields needed to extend a content type.

As you can see, the content_type_page table is an empty shell at this point, only having columns for vid (revision id) and nid (node id).

The content.module manages a great deal of data about the various fields you will use to extend your content types. I will show later that fields exist at two levels; the global level, which affects a field no matter which content type it extends, and the content-type-specific level, or field instance level, where a field can be customized to behave in a specific way for a specific content type. This dichotomy can be seen in the two administrative tables that the content.module creates, node_field, and node_field_instance:

mysql> describe node_field;
+-----------------+--------------+------+-----+---------+-------+
| Field           | Type         | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+-------+
| field_name      | varchar(32)  | NO   | PRI |         |       |
| type            | varchar(127) | NO   |     |         |       |
| global_settings | mediumtext   | NO   |     |         |       |
| required        | int(11)      | NO   |     | 0       |       |
| multiple        | int(11)      | NO   |     | 0       |       |
| db_storage      | int(11)      | NO   |     | 0       |       |
+-----------------+--------------+------+-----+---------+-------+

Note the global_settings field, as well as details about the database storage mechanism; these are details that are stored at the global level.

mysql> describe node_field_instance;
+------------------+--------------+------+-----+---------+-------+
| Field            | Type         | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+-------+
| field_name       | varchar(32)  | NO   | PRI |         |       |
| type_name        | varchar(32)  | NO   | PRI |         |       |
| weight           | int(11)      | NO   |     | 0       |       |
| label            | varchar(255) | NO   |     |         |       |
| widget_type      | varchar(32)  | NO   |     |         |       |
| widget_settings  | mediumtext   | NO   |     |         |       |
| display_settings | mediumtext   | NO   |     |         |       |
| description      | mediumtext   | NO   |     |         |       |
+------------------+--------------+------+-----+---------+-------+

Note that most of the information about how a field is displayed, i.e. weight, label, description, widget and display settings, are all stored at the instance level of a field.

Creating a new content type

To create a new content type, navigate to Administer -> Content management -> Content types -> Add content type (admin/content/types/add). You'll be required to give your new content type a human readable name and a machine readable name. There are other configuration options as well, but since creating and configuring new content types is part of Drupal 5 core, and not a feature of CCK, I won't cover that here.

For this article, I've created a new content type with the human readable name "Test content type" and the machine readable name "test". Here is the table that the content.module created on-the-fly, which is used to extend the "Test content type":

mysql> describe content_type_test;
+-------+------------------+------+-----+---------+-------+
| Field | Type             | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| vid   | int(10) unsigned | NO   | PRI | 0       |       |
| nid   | int(10) unsigned | NO   |     | 0       |       |
+-------+------------------+------+-----+---------+-------+

The structure of a CCK content table before fields have been added.

The fact CCK creates these tables for you is significant. The Flexinode approach was to save all of the information needed to extend content types in a few central tables, no matter how many flexinode types were created, or how many fields were added. These central tables became a bottleneck due to excessive JOIN queries being made. The CCK approach of creating new tables for the purpose scales much better.

Fields - an overview

Fields are the tools with which you extend the data model of a content type. A field comes in three parts; its underlying data type, its input widget, and its rendered output. These three parts are referred to as the field, the widget, and the formatter.

A good example of all these elements coming together is the date field. A date can have different underlying data structures (thus the choice between date and datestamp).

There are also many ways that a date can be input in a browser. A simple textfield is enough, if you can justify having your end users type in ISO standard date strings. A more comfortable solution is a separate input element, either text field or select list, for the various units of the date/time (year, month, day, hour, minute second). These are two different widgets; a textfield versus a number of select lists. Another possible widget is a JavaScript driven date picker. No matter which widget is used, the underlying data that gets stored in the database will be the same.

CCK HOWTO: two date fields with different widgets

Finally, there are many options when it comes to displaying and formatting the date. This is the realm of formatters. Formatters will not be covered in this article, although they are similar to a theme function in that they are concerned with the rendered output of a field.

This separation of concerns within a field is diagrammed below:

CCK HOWTO: The three parts of a field

Fields - adding new fields

So far I have enabled the content.module and created a new content type. If I try to add a field at Administer -> Content management -> Content types -> Add field I receive the following error message.

No field modules are enabled. You need to enable one, such as text.module, before you can add new fields.

This is because I have not enabled any modules which provide fields. One of reasons Flexinode became so popular was because of the relative simplicity with which people could add new field types. CCK is extensible in much the same way that Flexinode is, and it comes with three modules, the text, number and date modules, which define fields. In another article, I intend to show that creating your own custom fields is a straightforward process, granted you have an overview of what CCK is and how it does its business.

Go to Administer -> Site building -> Modules and enable text.module. The text module manages text-based fields.

To add a new field to an existing content type, go to Administer -> Content management -> Content types -> Add field (admin/content/types/test/add_field).

Adding a CCK text field

As soon as you create a new text field, CCK updates the underlying table in your database for that content type. Now look at the database schema for content_type_test:

mysql> describe content_type_test;
+--------------------------+------------------+------+-----+---------+-------+
| Field                    | Type             | Null | Key | Default | Extra |
+--------------------------+------------------+------+-----+---------+-------+
| vid                      | int(10) unsigned | NO   | PRI | 0       |       |
| nid                      | int(10) unsigned | NO   |     | 0       |       |
| field_example_text_value | longtext         | YES  |     | NULL    |       |
+--------------------------+------------------+------+-----+---------+-------+

field_example_text_value shows up in this table because I added a text field named "Example text".

Fields - global versus instance

Fields store global data plus per-instance data. The global configuration for the field goes into the node_field table. This includes the underlying data type, plus some data handling information specific to text fields, such as the input filter that should be used.

mysql> select * from node_field;
Column name Value
field_name field_example_text
type text
global_settings
a:4:{
  s:15:"text_processing";s:1:"1";
  s:10:"max_length";s:0:"";
  s:14:"allowed_values";s:0:"";
  s:18:"allowed_values_php";s:0:"";
}
required 1
multiple 0
db_storage 1

The global_settings column contains configuration data such as whether filtering is supposed to take place, what the maximum length is, and what the allowed values are. The data is in serialized form.

The node_field_instances table contains configuration information for the field that is specific to the the "test" content type. The fact that the "test" content type uses the "Example text" field is what is considered an instance of a field. Later I'll show that other content types can also use the same field. Each content type that decides to use it creates another instance of it, and each instance can, in turn, have different configurations. The data included at the per-instance level and stored in the node_field_instances table includes the label to be shown on the form, the widget that is to be used (textfield), and the number of rows that the form element should have.

mysql> select * from node_field_instance;
Column name Value
field_name field_example_text
type_name test
weight 0
label Example text
widget_type text
widget_settings
a:3:{
  s:13:"default_value";
  a:1:{
    i:0;
    a:1:{
      s:5:"value";
      s:0:"";
    }
  }
  s:17:"default_value_php";s:0:"";
  s:4:"rows";s:1:"1";
}
display_settings a:0:{}
description This is an example text field for a Lullabot article.

The per-instance settings include information about the widget that is to be used for capturing input (widget_type: text), the label for the input element ("Example text"), and the description ("This is an example text field for...")

Creating content

Now, with our extended content type, we can create some content. The data that is common to all nodes (author, published, created...) will be stored in the node and node_revisions tables, but the data that extends this content type will be stored in the content_type_test table. Here is what the content_type_test table looks like after creating a first "Test content type" node:

mysql> select * from content_type_test;
Column name Value
vid 1
nid 1
field_example_text_value Here is some example text! <div>Forbidden HTML will be stripped.</div>
field_example_text_format 1

Adding a second field

Now I'll add a second field to the Test content type, extending it even further. This time I'll add an Integer. The Integer field comes from the number.module (contained in the CCK download), so the first step is to enable that module. The number module defines two new data types, Integer, and Decimal. Each of them rely on the textfield widget by default. This clearly shows the independence of data types and widgets in the CCK architecture.

Adding a CCK number field

The configuration options for Integer and Text data are different. The reason that each needs different configuration is made clear when considering the validation requirements. An Integer is a much narrower set of values than Text, and to guarantee that only integers get stored in the database, the number module needs to do some extra work when accepting user input. Furthermore, there are possibilities for integers (such as minimum or maximum values) that don't make sense when considering free text. Karen Stevenson describes how the validation of user input is divided between the widget and the underlying data type:

In the current CCK model there are two layers of validation. The widgets provide their own input validation that is naive to the requirements of the data layer. The Data layer then validates what the widget produced as final output.

As you may have guessed, adding a second field to the Test content type results in further expansion of the content_type_test table. It is interesting to note that the storage requirements of each field are not the same. Text fields need the value and the format (for filtering), whereas our integer field only needs the data itself.

mysql> describe content_type_test;
+-------------------------------------+------------------+------+-----+
| Field                               | Type             | Null | Key |
+-------------------------------------+------------------+------+-----+
| vid                                 | int(10) unsigned | NO   | PRI |
| nid                                 | int(10) unsigned | NO   |     |
| field_example_text_value            | longtext         | YES  |     |
| field_example_text_format           | int(10) unsigned | NO   |     |
| field_number_of_toes_you_have_value | int(11)          | YES  |     |
+-------------------------------------+------------------+------+-----+

field_number_of_toes_you_have_value has been added to the content_type_test table by CCK because I added an Integer field named "Number of toes you have".

Multiple values

So far I've only demonstrated fields that have a single value per node. I've shown that such fields have their data stored directly in a table (content_type_test in the example) that is used to extend a content type. This paradigm changes, however, when a field is marked as "multiple".

CCK HOWTO: Turning on multiple field values

Once multiple values are enabled, many copies of the widget show up on the node form. If you fill them all up, submit, and then edit the node again, you will be provided with even more widgets for your use. The number of copies of the widget per node is not limited, so you could repeat the process indefinitely. This workflow is still a bit clumsy in CCK, but the groundwork has been laid for a very powerful system of managing one-to-many relationships between nodes and fields.

Multiple fields, multiple input formats
Multiple fields, multiple input formats; the results

When a field can have multiple copies, it no longer has a one-to-one relationship with the node. Rather, it has a one-to-many relationship, and this must be mirrored at the database level. Let's see what happens when I go back to the configuration of the text field and specify that multiple values are supported.

mysql> describe content_type_test;
+-------------------------------------+------------------+------+-----+
| Field                               | Type             | Null | Key |
+-------------------------------------+------------------+------+-----+
| vid                                 | int(10) unsigned | NO   | PRI |
| nid                                 | int(10) unsigned | NO   |     |
| field_number_of_toes_you_have_value | int(11)          | YES  |     |
+-------------------------------------+------------------+------+-----+

content_type_test has again been modified by CCK: this time fields have been removed.

Where did the field_example_text_value and field_example_text_format columns go? They're now in their own table:

mysql> describe content_field_example_text;
+---------------------------+------------------+------+-----+---------+-------+
| Field                     | Type             | Null | Key | Default | Extra |
+---------------------------+------------------+------+-----+---------+-------+
| vid                       | int(10) unsigned | NO   | PRI | 0       |       |
| delta                     | int(10) unsigned | NO   | PRI | 0       |       |
| nid                       | int(10) unsigned | NO   |     | 0       |       |
| field_example_text_value  | longtext         | YES  |     | NULL    |       |
| field_example_text_format | int(10) unsigned | NO   |     | 0       |       |
+---------------------------+------------------+------+-----+---------+-------+

In order to handle a one-to-many relationship between a content type and a "Multiple" field, CCK creates a new table for the field.

mysql> select * from content_field_example_text;
vid delta nid field_example_text_value field_example_text_format
1 0 1 Here is some example text! <div>Forbidden HTML will be stripped.</div> 1
1 1 1 I can use a different <span style="color:green;">input format</span> for each text field! 3
1 2 1 Even more example text. 1

The data storage of a "Multiple" text field.

Semantic meaning and sharing fields between content types

One of the primary goals of CCK is that the fields have semantic meaning. What does this mean? It means that a field called "Age", while being in principle identical in nature to a field called "Number of toes you have", is intended to convey a different meaning. Both fields store data as an integer. Both should be configured to only allow positive numbers. Age, however, should always be understood to refer to the length of time something has existed and the number of toes you have, while still a number, should be understood to have a totally different meaning.

Furthermore, it is often the case that a particular field with a particular semantic meaning needs to be used for more than one content type. For example, a content type called "Person" may have an Age field, and a content type called "Animal" may also have an Age field. Semantically, these fields should have the same meaning. CCK solves this problem by letting you use existing fields with any number of content types.

Fields retain semantic value across content types

As soon as a field is used in more than one content type, its values are no longer stored in the content-type-specific tables. A new table is created to store the values for that field across content types. This is the table that got created when I added the "Number of toes you have" field to a second content type:

mysql> describe content_field_number_of_toes_you_have;
+-------------------------------------+------------------+------+-----+
| Field                               | Type             | Null | Key |
+-------------------------------------+------------------+------+-----+
| vid                                 | int(10) unsigned | NO   | PRI |
| nid                                 | int(10) unsigned | NO   |     |
| field_number_of_toes_you_have_value | int(11)          | YES  |     |
+-------------------------------------+------------------+------+-----+

The table structure for an Integer field named "Number of toes you have". This field is being used by more than one content type, which is why CCK uses a dedicated table to store its data.

This information will no longer be stored in the content_type_test table. In fact that table has now been reduced back to its original state:

mysql> describe content_type_test;
+-------+------------------+------+-----+---------+-------+
| Field | Type             | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| vid   | int(10) unsigned | NO   | PRI | 0       |       |
| nid   | int(10) unsigned | NO   |     | 0       |       |
+-------+------------------+------+-----+---------+-------+

content_type_test has been stripped of its field columns altogether.

Summary

The Content Construction Kit is a carefully crafted tool that allows you to extend the data model for content types. The storage, retrieval and presentation of data is divided into the following parts:

  • data: fields
  • input: widgets
  • output: formatters

Fields can have single or multiple values per node. This distinction also influences how the data is stored in the database - whether it is stored directly in a table for a content type when the relationship is one-to-one, or whether it is stored in a field-specific table that allows the one-to-many relationship to be modeled.

Fields have semantic meaning that is retained across content types. When you add a field to a second content type, the storage of that field will switch from being within the table for the original content type to storage in a field-specific table.

Robert Douglass

Comments

Alex Rollin

Excellent Article

The Lullabot tutorials are really packing a punch for me. I really appreciate your sharing your experience with some of the complex integration work you have done, and this overview is no exception.

Reply

Netmonger

Awesome Article!

Very well written and informative article. Im a big fan of flexinode, and am really looking forward to utilizing CCK as I upgrade my site to 5.x. Great work! :)

Reply

Anonymous

cck base example

This is great. How would you like to flesh it out with a basic company phone list example with a twist. I'd like to have users authenticate from Active Directory even though we'd like to run Drupal 5 on Linux. If you haven't done that, we did play with that with 4.7 and it works and adds the user to Drupal the first time they log in.

What we'd like to get is where we have internal extensions, outside direct dial in numbers, and home phone numbers. a gotcha is only allowing managers to view home phone numbers. which means we'd need a field like manager's name and dept, etc.

a best practice would be nice to have so people can extend from it. i see too many ways to go about this and don't have the depth of understanding to know if one is more advantageous at this point. this kind of req't should be very common for business use.

thx much.

Reply

robert

I hope to write more...

In fact, looking at how fields work at the module code level is my next goal. I doubt I'll tackle an example as complicated as what you suggest, though.

Reply

Anonymous

cool. thx. i see there are

cool. thx.

i see there are some more modules now as well to give me more options:

User Profile Node Integrator
Addressbook

if you pick something that incorporates the user info you have my vote. again thx.

Reply

Victor Kane

Brilliant article

In its apparent simplicity and ease of understanding, this article, as a first step towards opening doors of perception in the use of a formidable tool, constitutes a great contribution to the Drupal community.

Secondly, it opens a semantic door.

It makes it clear that this is a model which has enormous growth potential, in terms of Drupal as a web application framework.

In my own capacity as Architect and Project Lead, articles of this kind, in the full spirit of the Drupal Dojo classes and group activities, signify an easy path towards very effective team building, indeed.

Many roads to productivity!

Victor Kane
http://awebfactory.com.ar

Reply

Philippe

This is very well explained

This is very well explained indeed. CCK seems to be really in the relational database spirit.

I wonder what happens when you switch back to a single value field from a multiple value one though

Reply

nate

Multiple => Single

CCK does the opposite of the behavior described above. That is, it converts the table of data into a column and places it back into the content type table.

What happens to extra content? They're 'chopped' off and only the first value from each multiple value field is saved.

Reply

saturday night live

Mutliple Item Fieldset Groups?

Lets say I wanted 2 SEPARATE text fields associated as a pair. A simple example would be first name and last name. Would it be possilbe to group them AS A MULTIPLE ITEM FIELDSET GROUP so that I could have multiple linked pairs...

EXAMPLE

first name
last name
-------------
first name
last name
-----------
first name
last name

etc..

versus

first name
first name
first name
first name

followed by

last name
last name
last name
last name

The difference is that as a grouped fieldset pair, not only are the first name and last name located together logically on the form, but they are associated as a unit in the db. so first name 'mickey' always is associated with last name 'mouse' and not last name 'duck'.

This would require that the delta field is shared for different field names of the same fieldset. in this case first name and last name for a given pair would always share the same delta.

Make sense?

ORDER
=====

Also, how would one enforce order of multi fields.

Say you enter in a bunch of multi text fields such as 'pets'.

cat
fish
dog
bird

Two weeks later, you decide that you want to rearrange the order of the fields. You bring up the edit node form. How do you rearrange the multi fields in a new order? for example so they look like this:

fish
bird
cat
dog

thanks for the article

Reply

robert

This should be its own field

I've started work on another article (which may or may not get done before the Sunnyvale conference coming up next week) about writing your own CCK field modules. I think what you're describing would be best achieved as a new field that stores two text columns in the database. There is no way to do what you're saying with just the default CCK modules. Hopefully, after my next article, you'll see that this isn't such a hard thing!

Reply

Anonymous

Great..

I look forward to that in a big way..

1) If possible, it would be cool to use my dual field dilemna in the example if you could..

2) I mentioned **ORDERING*** (and REordering) of the fields AFTER they'be already been submitted in my post. e.g. you pull up an existing node of the new content type that has multifield field with 10 instances of that field and and then rearrange the fields in a new sequence.

Any suggestion or recommended approach on how best to do that?

3) i know cck now has the ability to 'copy' content types which is cool. But do you know if it's possible (maybe in one of your future tutorials) to programatically create a predefined content type? If so how (maybe a quick answer now if you plan on doing this in a future article)?

I ask because it would be great if i could create a custom module that simply creates my own predefined cck types. i imagine that involves using teh cck api.

thanks

Reply

Slanj

Thank you for this great

Thank you for this great article. Quite understandable, even for me :) Question about double fieldgroup is very interesting for me also. For example I need to enter a pair - date of tour and a price for each date.

Reply

Marco

writing your own CCK field modules

Robert,

Great article! Is the other article 'writing your own CCK field modules' ready? If so, can you tell me where I can find it. Thank you.

Reply

robert

Sadly it is still unwritten.

Sadly it is still unwritten. Not that I've been slacking ;-) It is still on my list of things to do, and I even have some preliminary notes. I suggest subscribing to the RSS feeds here on Lullabot.com to keep up with the articles we publish. I'll still write it... as soon as I can get to it.

Reply

Ruby

Still?

This article made my month. Since it was written ~10 months ago, I'm hoping the follow-up is available. If you never got around to writing it, is there perhaps another source you can refer me to?

In particular, here's what I'm looking for help with: I'm creating a field type that collects/stores multiple pieces of data. So the field is actually made up of a number of sub-fields. There are several CCK field type modules that do this sort of thing, e.g., cck_address, which I'm using as a guide, but I'm still confused. I was thinking that my "field" would actually be implemented as multiple CCK fields. In cck_address, it appears to be much simpler than that. There is only one 'content_field_address' table (once the field is being used by multiple types), not a content_field_* table for each component of the address. But I can't quite figure out how to make that happen.

Thanks for any suggestions!
~ Ruby

Reply

Anonymous

Just to reitierate..

because i'm not sure it was clear in my original post and possibly even the second one.

When i talk about REORDERING, i'm talking about the VALUES contained in a multfield field. If the multifield is defined as 'pet' but can exist multiple times on the form, it can have VALUES like:

dog
cat
fish
bird

What i want to be able to do is rearrange the order of the VALUES ONCE THEY"VE BEEN CREATED.

in otherwords, the ORDER of the VALUES needs to be allowed to be different for every node of this content type POST SUBMITTAL. someone else might type in:

dolphin
whale
shark
tuna
turtle
donkey

And they need to be allowed to rearrange those values if they so choose when editing the node.

It's almost as if each field instance of 'pet' in the db needs to have an index (weight) from 0.. infinity as an additional field. And maybe that's where creating my own field type comes into play because i give it the extra widget for reordering.

However, even if i do that, i'm wondering how to best CHANGE THAT INDEX. Ajax drag and drop or up/down arrows would be the best way but i'm not sure how to implement that.

Any thoughts here greatly appreciated as well as if i'm on the right track?

thanks

Reply

Alexis Bellido

CCK is now as clear as water

Thank you Robert. I've been choosing custom modules over CCK for new content types since 4.7 and intended to continue working that way in 5 but your article has helped me see the great power that CCK brings to Drupal 5.

Now I have to get used to theming CCK content and forms in Drupal 5 for my current project.

I'll do my best to contribute something of the experience back to the Drupal community soon.

Cheers!

Reply

MacRonin

Thanks for the info.

Thanks for this informative article. It cleared up a few things. And most important, let me know how to get more than three entries when using the multiple field type. I had thought I'd seen an option (a link) that kept adding fields. But either my memory is going, or maybe it was a 4.7 add-on.

Looking forward to even more articles.

Reply

Edward Ishaq

a question :)

What will happen if this scenario occurred :

  1. Created a new content type test_1
  2. add new field called "age"
  3. Created another new content type test_2
  4. used the same field "age" to the test_2 (at this point the field is removed from node_test_1 table and created its own table "node_field_age" )
  5. the test_2 content type is deleted

my question is will the field age go back to the test_1 node data table ? or it will keep existing in its own table ?

Reply

themegarden.org

Excellent article. I have

Excellent article.

I have one question.
Is CCK suitable for creating new content type which can handle some tabular data (for example product data sheet)?

If yes, could someone write small description or howto?
If no, which module could be suitable for this task?

Reply

robert

Well, yes, but you'll want

Well, yes, but you'll want to have some PHP skills and know a bit about Drupal modules to get the tabular output. Let's think about every row in your spreadsheet as a node. The CCK table will be content_type_foobar, and it will have columns for all the fields that you add to the foobar content type. As long as you keep them single value, the column will stay with the content_type_foobar table, and this is important to your solution. For your solution, you won't want to share fields between content types, and you won't want to have any of the fields that are in "the spreadsheet" be multiple.

Then, you've got two options. Either build a view that shows the files in a table view, or write a small module to show the table. Use views if no calculations are needed. If you need to do calculations on the columns of any sort, then you need to write a module.

Here's the quick recipe for such a module:

  1. implement hook_menu to get a callback to the page with the table
  2. SELECT * FROM {content_type_foobar}
  3. while ($row = db_get_array...)
  4. $rows[] = $row; // <--- you can do calculations here
  5. return theme('table', $headers, $rows);

That's obviously pseudo code, but it should give you the main points.

Reply

Amnon Levav

For i18n compatibility, an internal field name is a must

Currently, for each content type you must define a a machine readable name. This is great! since it serves as a part of the table name created for that content type.

Problem is no such concept exist for the field names.

Suggestion: Carry this excellent contcept to the field level! Allow the user to define a machine readable name for each field as well.

Otherwise, when I define my Hebrew field names for my new content type, and look at the DB table, all I get is underscores, which is not very friendly. Field names are *completely* erased, which was not the original intention.

Here is how my 'directory' CCK table looks: Excellent internal name for the table, but only underscores for the field names.

Fixing it will be a great improvement to the CCK data model and will enable easier internationalization.

mysql>  desc content_type_directory;    
+------------------------+------------------+------+-----+---------+-------+
| Field                  | Type             | Null | Key | Default | Extra |
+------------------------+------------------+------+-----+---------+-------+
| vid                    | int(10) unsigned |      | PRI | 0       |       |
| nid                    | int(10) unsigned |      |     | 0       |       |
| field___url            | varchar(255)     |      |     |         |       |
| field___title          | varchar(255)     |      |     |         |       |
| field___attributes     | mediumtext       |      |     |         |       |
| field__page_rank_value | int(11)          | YES  |     | NULL    |       |
| field___0_url          | varchar(255)     |      |     |         |       |
| field___0_title        | varchar(255)     |      |     |         |       |
| field___0_attributes   | mediumtext       |      |     |         |       |
| field___1_value        | int(11)          | YES  |     | NULL    |       |
| field___4_value        | longtext         |      |     |         |       |
+------------------------+------------------+------+-----+---------+-------+
11 rows in set (0.00 sec)

Thanks

Amnon
-
Professional: Drupal Search | Drupal Israel | Web Hosting Strategies
Personal: Hitech Dolphin: Regain Simple Joy :)

Reply

dellis

I have CCK normalization confusion

I'm not sure it is clear to me how CCK works with normalized data. Specifically with many-to-many relationships. Ordinarily, you'd create an interaction table that would allow you to have two separate one-to-many relationships and therefore keep things normalized. How do you do this in drupal CCK?

For example:
Problem: You wish to relate "authors" to "articles" - each author could write many articles, and each article could have many authors.

Without drupal, I'm thinking that I would make three tables: authors, articles and authorarticlepair. Each author could have many authorarticlepair nIDs, but each authorarticlepair nID could only have only author. Each article could have multiple authorarticlepair nIDs, but each authorarticlepaid nID could only have one article. This way you wouldn't have to update the data in multiple places.

But I don't really understand how you could implement this with CCK? I'd be thrilled if you had any suggestions!

Reply

omnyx

node object?

great article!
one question that's been killing me. How is node object created for a node type created through CCK with new fields?
i.e. let's say i defined new content type 'test' and it has a field 'time' set as a datestamp.
Now using hook_nodeapi I want to create more complex validation of inputs. But, how do I access a node's field 'time'.
Basically, I'd like to be able to get something like $node->field_time but it doesn't seem like I can just say $node->field_time the same way I can say $node->nid?

any ideas?

Reply

paresh

date field using CCK

hi,

I have created new content type say Advertise.
I am able to add fields of fields type "Node Reference", "Integer", "Decimal", "text", "email", "Image".

But i want to add the "date field", means a text box with date picker control which allow me the pick the date from calender,

please advice how to achieve it.

Also I had used the Profile module to add custom fields in User Registration page.
Now I have to add the Password field in user registration page.
please tell me how this to done.

(I know drupal gives me the password fields in registration then too i have to add more password field in registration).

Reply

robert

Date module

The Date module adds fields to CCK for date types.

I'm not sure what you mean about the password field, but that isn't something you'll achieve with CCK since CCK only adds fields to nodes, and user registrations aren't nodes. For hints on extending the user registration process, check out the Login Toboggan module.

Reply

Tobias

Read and Display the date_field

Hello, i have a Problem that makes me crazy!! I have created a new content type with a date_field and the user can select the date in a list. Now, in the database is the date in the format like this: 2008-08-18T00:00:00
Now, i SELECT my node from the database and would display the date like this: 18 Aug 2008. are there any funktions to format the ISO_DATE?

hope you understand me, if not, you also can send me a privat message

mfg
tobi

Reply

TKS

Can CCK handle integers larger than 2147483647?

Great article - thanks!

Quick question, though, for Robert or anyone else reading: Is it possible to have a CCK integer field be a BIGINT as opposed to INT ? (see http://drupal.org/node/262712 for some of the context, and another person having this same issue)

Changing the field type directly in the database clearly doesn't cut it. Is there a good way to work with really large numbers in CCK? (Aside from just making it a textfield, of course...)

Reply

Anonymous

Additional comment fields and making them compulsory

Hi everyone,
Changed over from Joomla and find the flexibility amazing!! I am quite a newbie to drupal and php and by eveyones help, am picking up fast.

However, I am a bit stuck on this one and will be very grateful for some help .....

I have selected Anonymous posters must leave their contact information on comment settings

I have the following fields available for posting comments
'Your Name' *
'Email' *
'Homepage'
'subject'
'comment' *

1) Is it possible to add a few further fields like 'fullname' 'occupation' 'address' and be able to also call them up for printing on the screen when comments are listed.

2) How can I make the other fields compulsory to fill up

Tried to search if there are any appropriate modules for Drupal 6.2, couldnt find any.

Will be extremely grateful for some direction

Reply

Rosamunda

Thanks!!

Great article, it really explain things in an easy to understand way, because it was a nightmare to adapt the flexinode way of thinking to the CCK way.

If you continue with articles that covers CCK, I would suggest computed field module or maybe how CCK works very nicely with Views.

Again, thank you very much for this insight!

Rosamunda
Buenos Aires

Reply

VB6

Work with views

How does all this work with views. I have a Visual Basic tutorial site that I use that has a custom tutorial content type. I then want to show a list of my tutorials and then a sublist based on the taxonomy they picked. I don't know if this makes sense. I have it working right now on the VB6 site but I had to do it all by hand. You can see an example of my VB6 File Tutorials view.

I'm not sure if this all makes sense but I was wondering how I would either create a new Content Type for each type of Visual Basic Tutorial, but this seems silly. Or If there is a way to use views better so that I can display all my tutorials on one page and then with a parameter share the specific guides on another page.

Reply

aman

How to search the content created with CCK

Excellent article on CCK. I am new to Drupal and planning to use CCK for a real estate site. So if I create a content type property with about 10 fields like price, year built, bedrooms, bathrooms etc. and then want to provide a search capability for user to search that content on the above said fields, what is the easiest way to achieve that?
Thanks

Reply

Lourenzo Ferreira

Permition to translate

Howdy, I apreciate so much this work that I'm wondering if I could translate it and publish on my blog, citing the source and original authorship.

Would you allow me to do that?

Thanks

Reply

addi

Sure!

Hi Lourenzo,

That would be great! Please post the link to the translation here when you have it published. :-)

Reply

Glen

Great article, thanks!

I've been searching for a CMS platform which would meet the needs of a complex business data model and provide a powerful yet customisable core set of features. I've started to look into Drupal and this article has totally convinced me! It provided a great walk through of the core uses of CCK, which has turned out to be just what I have been looking for!

So thank you, once again!

Reply

Liberty Fun Pass

CCK

I'm doing a crash course on Drupal and this was a great introduction to CCK. Thanks! CCK and Devel so far are the must have modules.

Reply

Anonymous

One thing not clear

Great article thank you very much.

One thing is still not clear to me.

Lets say I create a content type vehicle and add fields

field: mileage
field: operation hours

This fields will be shared over several other content types.

How would I achieve that the last entry of any content type is the most current and that the previous entries will not be overwritten but instead a new entry is created (like a revision).

For instance:

If I have 100 miles in the database and now creating a new entry (from any of the content types) as 200 miles I want to have:

100
200

stored and not 100 with 200 overwritten.

Is that possible and if how would I achieve that?

Thank you for your help and keep up the great writing!

Reply

Krishna

reusing CCK fields with Custom Forms

Thank you for this article, It really helped me get a good understanding of CCK. Would it be possible to have an article about reusing CCK fields and widgets with custom forms to take advantage of the validation and presentation that is built into CCK?

Reply

Anonymous

A real great article

Your article is realy brilliant and give a very good introduction of what is going on in the CCK module. Thx for sharing this cool intro with the drupal community.

Reply