4

I've created a custom content-type called "Books."

I need to create another content type named "Catalogs" which may contain one/many "Books" as its fields.

How would I achieve that? I'd prefer some GUI tool to construct my custom content type, from admin panel, or doing some coding, if necessary.

PS: I found this question asked here but the solution did not help. Can someone provide a detailed answer, please?

EDIT:

MohammadAliAkbari's answer works perfectly :) One problem - When adding "Books" a user can add Books not created by him - he can add any Book to his "Catalog" - How can I add constraints such that a user can add Books only created by him to his Catalog?

Solution:

Using Tenken's answer, I figured out that I can write this code in my module to solve the scenario just mentioned above:

function myModule_form_alter(&$form, &$form_state, $form_id) {
//    dsm($form_id); // Use this line to find YOUR-DESIRED-FORM-ID
    switch ($form_id) {    
        case 'YOUR-DESIRED-FORM-ID':
            $form['#validate'][] = 'stylesku_add_sku_form_validate';
//            dsm($form); // Use this to find out form's elements
            global $user;
            $currentUser = $user->uid;
            $fieldSku = $form['FIELD-ID-OF-BOOK'];
            $lang = $fieldSku['#language'];
            $fieldOptions = $fieldSku[$lang]['#options'];
            foreach($fieldOptions as $nid=>$nodeTitle){
                if(!is_int($nid))
                    continue; // Needed as the first option in select box is not really any book
                $nid = (int) $nid;
                $n = node_load($nid);
                if($n->uid != $currentUser){
                    // Remove this BOOK, this book was not created by current user
                    unset($form['FIELD-ID-OF-BOOK'][$lang]['#options'][$nid]);
                }
            }
            break;
    }
}

4 Answers 4

3

Ok, you should be familiar with

  1. entity
  2. view mode
  3. entityreference

after install entityreference create a reference to books in your catelogs content-type, then go to catelogs > manage display and for books reference select Rendered entity formatter and in its options set something like teaser

after this go to books > manage display and configure teaser as you need.

also you can add more view modes by Display Suite or via simple module:

function mymodule_entity_info_alter(&$entity_info) {
  $entity_info['node']['view modes']['render_in_catelogs'] = array(
      'label' => t('render in catelogs'),
      'custom settings' => FALSE,
  );
}
5
  • Thanks @MohammadAliAkbari that works perfectly :) One problem - When adding Books a user can add Books not created by him - he can add any Book to his Catelog - How can I add constraints such that a user can add Books only created by him to his Catelog? Thanks in advance for helping...
    – Shafiul
    Mar 25, 2012 at 10:05
  • some hacks near protected function buildEntityFieldQuery(... is needed in entityreference/handler/base.inc Mar 25, 2012 at 10:37
  • Hacking will ruin it, being unable to update the module later. Is there any other elegant solution? Thanks
    – Shafiul
    Mar 25, 2012 at 10:42
  • entityreference not allow other solution (I think), so you can add this feature and commit it in drupal.org, you should add some setting in widget form and some conditions in buildEntityFieldQuery based on field instance setting Mar 26, 2012 at 3:57
  • I've created an issue at EntityReference's page... I'm waiting for their response, then I'll try!
    – Shafiul
    Mar 26, 2012 at 4:17
2

I can see 2 options to build upon @Akbari's advice ...

  1. the easy way hook_form_alter to change the select options to be limited to entityreference node values owned by the end-user. Alter the node submit validate function to assure its one the user owns. So this attempt would just edit the $form item using FAPI tweaks ... you can use FAPI '#element_validate' option to set a validate function for the selected $book.
  2. the really hard way ... which might work as @Akbari suggested ... you need to alter EntityReference_SelectionHandler_Generic::buildEntityFieldQuery() somehow. I recommend using hook_field_info_alter() to supply your own $info['entityreference']['handler'] key in the field info that extends the base class with your own and overrides the buildentityinfo logic with "ownership" logic. You will probably need to make the entityreference ctools plugins aware of your custom handler (somehow) ... an example using hook_field_info_alter can be found in this blog post (not mine) ...
2
  • Thanks Tenken! I'd really like to go with option 1 - I'll try and ask again here if I'm in trouble!
    – Shafiul
    Mar 26, 2012 at 4:14
  • Thanks @Tenken, option 1 works perfectly, I added my code in my question. I tried to manipulate the form using malicious data - and it seems that Drupal can figure out if any user is trying to change form's select box's information. So do I really need to add a validate handler?
    – Shafiul
    Apr 2, 2012 at 13:00
1

You can use the Multifield or Field Collection module.

0

You can use node reference cck field. Node reference is a CCK field by which you can create some relationship between the two content types. At the time of creation a catalog you can assign book nodes to the catalog and make it multivalued so you can assign one or more book nodes to the catalog content type.

4
  • I can't find any such field, do I need to install some module for that? Attaching a screen-shot. dl.dropbox.com/u/9053005/hosted/screen-casts/Drupal/…
    – Shafiul
    Mar 25, 2012 at 7:45
  • See this youtube.com/watch?v=CpUoVNt8O4s Mar 25, 2012 at 11:45
  • CCK is not a Drupal 7 concept.
    – Clive
    Mar 26, 2012 at 11:04
  • In Drupal 7, the core part of CCK has been implemented as field API. CCK still have a Drupal 7 release, but it is only for updating from Drupal 6 to Drupal 7, and for implementing the extra fields that have not moved to Drupal core.
    – apaderno
    Mar 26, 2012 at 13:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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